My model contains an enumeration that I'd like to filter the grid on when it's loaded via AJAX.
.cshtml Code:
#(Html.Kendo().Grid()
.Name("Grid")
.Columns(columns =>
{
columns.Bound(x => x.Type);
columns.Bound(x => x.Status); #*This is my enum*#
})
.Filterable()
.DataSource(ds => ds
.Ajax()
.ServerOperation(true)
.Filter(filter => filter.Add(x => x.Status).IsEqualTo(MyEnum.Updated))
.Read(read => read.Action("QueryAlerts", "Alert"))))
The filter request on the AJAX POST is going across as Status~eq~'updated' and returns an Input string was not in a correct format error.
I removed the filtering on the data source and used the filtering controls to see how that request is normally passed which looks like this: Status~eq~2.
I've tried casting the filter values to integers (e.g. filter.Add(x => (int)x.Status).IsEqualTo((int)MyEnum.Updated)) and that results in an invalid cast error to Int32 from the model which is expected by the Add method.
Can this problem be solved using Razor or is this a JavaScript fix?
What data type is your x.Status? If it's an int then you don't need to cast it, only the enumeration:
filter.Add(x => x.Status).IsEqualTo((int)MyEnum.Updated)
Related
I am binding Kendo Grid from ASP.NET MVC as follows:
#(Html.Kendo().Grid<My.Web.Models.Generated.CustomerSearch01.CityInfo>()
.Name("gridCities")
.Columns(columns =>
{
columns.Bound(c => c.Text).Width(140).Title("City");
})
.Scrollable()
.Selectable(selectable => selectable.Type(GridSelectionType.Row))
.BindTo(Model.CitiesList)
.DataSource(ds => ds.Server().Model(m => m.Id(p => p.Value)))
)
That works fine and the grid shows up on the page with data and I have no problems with above. However, using browser developer tools, if I try to get the data of the above grid using the following statement, it returns empty:
jQuery("#gridCities").data("kendoGrid").dataSource.data()
What am I missing?
Thanks in advance
Solution (based the answer):
replace the following:
.DataSource(ds => ds.Server().Model(m => m.Id(p => p.Value)))
with
.DataSource(ds => ds.Ajax().ServerOperation(false).Model(m => m.Id(p => p.Value)))
You Grid is configured to use ServerBinding which means the TR / TD elements are rendered from the server. If you want to have the JavaScript objects of your model on the client side and do not perform separate Ajax request configure your DataSource to be
ds.Ajax().ServerOperations(false)
This will not perform any Ajax requests, data will be serialized from the server int JSON.
I've been working with Kendo UI for some time now and I've stumble upon behaviour I can't explain
When you visit http://demos.telerik.com/kendo-ui/grid/remote-data-binding on grid you can see total of 830 elements.
When you go to console and run
$("#grid").data("kendoGrid").dataSource.view()
You receive array of 20 elements (as expected). And when you run
$("#grid").data("kendoGrid").dataSource.data()
You receive array of the same 20 elements. I tried playing with filters and from my experience .data() behaves exactly the same as view(), which is odd. As far as I understand documentation I should receive 20 elements when using view(), but i should receive all 830 when using data()
Have I been doing something wrong? Does data filter elements (and paginate) on backend? For reference this is my backend method, which returns data for my grid
public ActionResult IndexDataSource([DataSourceRequest] DataSourceRequest request)
{
var customers = this.GetViewModel();
return this.Json(customers.ToDataSourceResult(request));
}
Notice that in this example the serverFiltering property is set to true (and serverPaging, serverSorting also). So on the javaScript side, you will always have same data whatever you're using view() or data() method. And it will be the same array what controller's acton returns to display: one, selected page.
To make view() works as documentation say you have to turn off all properties that i said and read whole data in one bunch.
Explicity setting .ServerOperation(false) in MVC syntax resolved problem. I would like to thank j4ro for pointing me this option.
#(Html.Kendo().Grid<Model>()
.Name("Grid")
.Columns(columns =>
{
...
})
.Sortable()
.Filterable()
.Resizable(r => r.Columns(true))
.Events(e => e.DataBound("CustomerGridDataBound"))
.Pageable(pageable => pageable
.Refresh(true)
.PageSizes(new[] { 5, 50, 200, 99999 })
.ButtonCount(5))
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(5)
.ServerOperation(false) // you need to add this to be able to use .data()
.Read(read => read.Action("ActionDataSource", "Controller"))
))
I've recently purchased a Kendo subscription, I'm having trouble getting an AJAX bound grid to operate as expected, hoping someone here can help.
I have followed the Kendo docs tutorial # http://docs.kendoui.com/getting-started/using-kendo-with/aspnet-mvc/helpers/grid/ajax-binding
and could get the AJAX binding working nicely.
I've tried to now implement it into an existing MVC solution, and whenever I click the New or Edit command button, I get a string of JSON returned to the browser. Similiar to issue (JSON data to KENDO UI Grid ASP.NET MVC 4) But the answer in that problem didn't work for me.
Here is my Controller code...
public ActionResult Index()
{
// non-important code removed here //
var viewModel = newReferenceViewModel();
ViewBag.TradeReferences = TradeReferenceWorker.Get(applicationId);
return View(viewModel);
}
public ActionResult TradeReferences_Read([DataSourceRequest]DataSourceRequest request)
{
var applicationId = GetCurrentApplicationId();
DataSourceResult result = TradeReferenceWorker.Get(applicationId).ToDataSourceResult(request);
return Json(result, "text/x-json", JsonRequestBehavior.AllowGet);
}
And the View ....
#(Html.Kendo().Grid((IEnumerable<TradeReference>)ViewBag.TradeReferences)
.Name("gridTradeReference")
.DataSource(dataSource => dataSource
.Ajax()
.Model(model =>
{
model.Id(tradeReference => tradeReference.TradeReferenceId);
model.Field(tradeReference => tradeReference.TradeReferenceId).Editable(false);
})
.Read(read => read.Action("TradeReferences_Read", "References"))
.Create(create => create.Action("TradeReference_Create", "References"))
.Update(update => update.Action("TradeReference_Update", "References"))
.Destroy(destroy => destroy.Action("TradeReference_Destroy", "References"))
)
.Columns(columns =>
{
columns.Bound(tref => tref.TradeReferenceId).Visible(false);
columns.Bound(tref => tref.Name);
columns.Bound(tref => tref.Phone);
columns.Command(commands =>
{
commands.Edit();
commands.Destroy();
}).Title("").Width(200);
})
.ToolBar(toolbar => toolbar.Create())
.Editable(editable => editable.Mode(GridEditMode.InLine))
.Sortable()
)
So to sum up... the Grid will load perfectly the first time. I haven't wired up anything on the Edit / Delete actions, just trying to get Create operational. Clicking Add New, or even Edit for that matter will make the browser simply display Json to the screen.
It is hopefully something simple - thanks in advance
Solved it - the problem was the kendo js files were not being referenced correctly.
In my particular case, the bundling wasn't done 100% correctly so the Kendo javascript files were never getting included in the page.
They must also appear in a certain order, as described in the troubleshooting guide http://docs.kendoui.com/getting-started/using-kendo-with/aspnet-mvc/helpers/grid/troubleshooting
I am trying to dynamically add grid filters in my view using the html helper via datasource configuration, like this example from the kendo documentation:
#(Html.Kendo().Grid<Product>()
.Name("grid")
.DataSource(dataSource => dataSource
.Ajax()
.Read(read => read.Action("Products_Read", "Home"))
.Filter(filters =>
{
if (someCondition){
// Show products whose ProductName property contains "C"
filters.Add(product => product.ProductName).Contains("C");
// and UnitsInStock is greater than 10
filters.Add(product => product.UnitsInStock).IsGreaterThan(10);
}
})
)
)
The filters are added, but the filterdescriptor.Value in each case is always null (the Member and Operator are fine).
Any help much appreciated.
Thanks!
--Berry
Make sure you have included kendo.aspnetmvc.min.js. Missing it would lead to similar symptoms.
I call grid.SaveChanges() in my javascript function. The grid is using inline editing mode.
My problem is if there were some client side validation errors for example invalid date format, then I must not execute some DOM operations. Unfortunately grid.SaveChanges() has no return value and searching for keyword 'valid' in grid documentation page has no result. (Teleport to Kendo Grid API documentation)
So: How can I determine if there was validation errors after SaveChanges() or the data was successfully sync-ed with the persistent store?
Thx in advance
I'm assuming that you are using the MVC wrappers but calling grid.SaveChanges() as part of your script. Since you're using inline editing mode, that means you're using Ajax. If those assumptions are correct, then when you call SaveChanges() your controller action specified in the wrapper is executed. If you hook into the .Error event you can execute whatever script needs to be executed (even if that's just setting a variable that you check in the other parts of your script). Have a look at the Ajax Editing portion of Getting Started on Kendo's website. Your Razor code will look similar to the following (some of this is extraneous, I pulled it out of production code and modified slightly):
#(Html.Kendo().Grid(Model)
.Name("Grid")
.Columns(cols =>
{
cols.Bound(p => p.ColumnA);
})
.Editable(edit => edit.Enabled(true).Mode(GridEditMode.InCell))
.DataSource(ds => ds
.Ajax()
.AutoSync(false)
.Model(model =>
{
model.Id(p => p.ColumnId);
})
// Configure RU -->
.Read(read => read.Action("_MyRead", "MyController").Data("additionalData"))
.Update(update => update.Action("_MyUpdate", "MyController").Data("additionalData"))
//.ServerOperation(false)
.Batch(true)
.Events(events => events
.Error("onError")
)
)
// <-- Configure RU
.Pageable(page => page.PageSizes(new int[] { 10, 25, 50, 100 }).Enabled(true))
.Groupable(group => group.Enabled(true))
.Filterable(filter => filter.Enabled(true).Extra(false))
.Sortable(sort => sort.Enabled(true).SortMode(GridSortMode.SingleColumn).AllowUnsort(true))
.Navigatable(nav => nav.Enabled(true))
.Resizable(resizing => resizing.Columns(true))
.Reorderable(reorder => reorder.Columns(true))
)
Then your onError script will look like this:
function onError(e, status) {
if (e.errors) {
var message = "The following errors have occurred and changes will be discarded:\n";
$.each(e.errors, function (key, value) {
if (value.errors) {
message += value.errors.join("\n");
}
});
alert(message);
var grid = $("#Grid").data("kendoGrid");
grid.cancelChanges();
}
}