Hello,
In my grid, i have a nested object and i would like to add the filterable feature on it (so it doesn't display [] object). I followed this tutorial:
- https://demos.telerik.com/aspnet-core/grid/filter-multi-checkboxes
The call to the web API is done, but I keep having a javascript error after the call
Uncaught TypeError: e.slice is not a
function
How can i fix this ? Thank you very much
Here is my code so far:
@(Html.Kendo().Grid<EnginViewModel>()
.Name(
"enginGrid"
)
.Columns(col =>
{
col.Bound(c => c.Famille) //EnginViewModel.Famille
.Title(
"Famille"
)
.Filterable(ftb => ftb.Multi(
true
).Search(
true
)
.DataSource(d => d.Read(r => r.Action(
"Familles"
,
"EditorTemplate"
).Data(
"{ field: 'Nom'}"
))))
.EditorTemplateName(
"Famille"
)
.ClientTemplate(
"#= data ? data.FamilleDesignation : \"\" #"
);
})
.ToolBar(toolbar =>
{
toolbar.Create().IconClass(
"fa fa-plus"
).Text(
" Créer un engin"
);
})
.Sortable(
true
)
.Filterable(f =>
{
f.Mode(GridFilterMode.Menu);
})
.DataSource(ds => ds.Ajax()
.ServerOperation(
true
)
.Model(m =>
{
m.Id(f => f.Id);
})
.Events(evt => evt.Error(
"onGridDatasourceError"
))
.Read(a => a.Action(
"Read"
,
"Engins"
).Type(HttpVerbs.Get))
.Create(a => a.Action(
"Create"
,
"Engins"
).Type(HttpVerbs.Post))
.Update(a => a.Action(
"Update"
,
"Engins"
).Type(HttpVerbs.Put))
.Destroy(a => a.Action(
"Delete"
,
"Engins"
).Type(HttpVerbs.Delete)))
)
6 Answers, 1 is accepted

ok, i changed the return type of my method. Iam now returning an IEnumerable<FamilleViewModel> and not a DataSourceResult.
Here is the method i call to fetch my datas
[HttpGet(
"test"
)]
public
async Task<IActionResult> Test()
{
var familles = await _familleRepository.AllAsync();
return
Json(familles);
}
The previous error (e.slice is not a function) is now solved. I have now a new error:
VM5470:3 Uncaught ReferenceError: Famille is not defined
(
function
anonymous(data) {
var
$kendoOutput, $kendoHtmlEncode = kendo.htmlEncode;
with
(data) { $kendoOutput =
'<li class=\'k-item\'><label class=\'k-label\'><input type=\'checkbox\' class=\'\' value=\''
+ $kendoHtmlEncode(kendo.format(
'{0}'
, Famille)) +
'\'/>'
+ $kendoHtmlEncode(kendo.format(
'{0}'
, Famille)) +
'</label></li>'
; }
return
$kendoOutput;
})
Thank you for you help.
If a column is bound to a complex field, it cannot be sorted and filtered. A possible workaround is to bind the column to the nested field, for example:
col.Bound(c => c.Famille.FamilleDesignation)
.Title(
"Famille"
)
.Filterable(ftb => ftb.Multi(
true
).Search(
true
)
.DataSource(d => d.Read(r => r.Action(
"Familles"
,
"EditorTemplate"
).Data(
"{ field: 'Nom'}"
))))
.EditorTemplateName(
"Famille"
);
With this configuration, the column will only edit the FamilleDesignation field of the parent object, so if you want to update other properties, too, when a value is selected in the custom editor, you should do it manually.
I am attaching a sample project where I bind a column to a nested field. This column uses a custom DropDownList editor that updates automatically only the nested string field. On save of the edited cell, I copy the rest of the data from the selected data item to the edited Grid model.
It is also possible to move the logic that copies the rest of the fields into the DropDownList select event if you prefer to keep all custom logic within the editor. Let me know if you prefer this approach and need help with the implementation. In such case, please share the definition of the Famille model and the custom editor declaration.
Regards,
Tsvetina
Progress Telerik

Hello,
Thank you for your answer. An exemple of the logic inside the dropdownlist would be nice. Here is the definition of the Famille model and the custome editor declaration
public
class
FamilleViewModel
{
public
int
Id {
get
;
set
; }
public
string
Nom {
get
;
set
; }
public
List<PointVerificationViewModel> PointVerifications {
get
;
set
; }
}
The custom editor
@model FamilleViewModel
@(Html.Kendo().DropDownListFor(m => m)
.OptionLabel(
"Sélectionnez une famille"
)
.DataTextField(
"Nom"
)
.DataValueField(
"Id"
)
.DataSource(ds => ds.Ajax().Read(a => a.Url($
"Administration/api/editortemplates/familles"
).Type(HttpVerbs.Get)))
)
/* the called method (Administration/api/editortemplates/familles)*/
[HttpGet(
"familles"
)]
public
async Task<IActionResult> Familles([DataSourceRequest] DataSourceRequest request)
{
_logger.LogInformation(
"REST Request: Familles"
);
var familles = await _familleRepository.AllAsync();
var data = _mapper.Map<IEnumerable<FamilleViewModel>>(familles);
return
Json(data.ToDataSourceResult(request));
}
Thank you for your help

Hello, thank you for your answer. That would be nice to have an exemple of the logic inside the dropdownlist. Here are the informations you requested:
/*
Famille model
*/
public
class
FamilleViewModel
{
public
int
Id {
get
;
set
; }
public
string
Nom {
get
;
set
; }
public
List<PointVerificationViewModel> PointVerifications {
get
;
set
; }
}
/*
Custom Editor Declaration
*/
@model FamilleViewModel
@(Html.Kendo().DropDownListFor(m => m)
.OptionLabel(
"Sélectionnez une famille"
)
.DataTextField(
"Nom"
)
.DataValueField(
"Id"
)
.DataSource(ds => ds.Ajax().Read(a => a.Url($
"Administration/api/editortemplates/familles"
).Type(HttpVerbs.Get)))
)
/*
the URL method
*/
[HttpGet(
"familles"
)]
public
async Task<IActionResult> Familles([DataSourceRequest] DataSourceRequest request)
{
var familles = await _familleRepository.AllAsync();
var data = _mapper.Map<IEnumerable<FamilleViewModel>>(familles);
return
Json(data.ToDataSourceResult(request));
}
Thank you very much for the help.

Here is an example of what the custom editor would look like if you decide to put the logic that populates the selected item values in the Grid model:
@model string
<script>
function
onChange(e) {
var
ddl =
this
;
var
ddlItem = ddl.dataItem();
var
editedRow = ddl.element.closest(
"tr"
);
var
grid = editedRow.closest(
".k-grid"
).data(
"kendoGrid"
);
var
editedDataItem = grid.dataItem(editedRow);
editedDataItem.Shipment.ShipCity = ddlItem.ShipCity;
editedDataItem.Shipment.ShipCountry = ddlItem.ShipCountry;
}
</script>
@(Html.Kendo().DropDownListFor(m => m)
.DataValueField(
"ShipName"
)
.DataTextField(
"ShipName"
)
.BindTo((System.Collections.IEnumerable)ViewData[
"shipmentInfo"
])
.Events(e => e.Change(
"onChange"
))
)
If you decide to use this, remove the Grid onSave custom logic.
Regards,
Tsvetina
Progress Telerik