Kendo DataSource requestEnd event gets fired multiple times - kendo-ui

I am using Telerik UI for ASP.NET MVC and i have grid defined as below
#(Html.Kendo().Grid<GridModel>()
.Name("grid")
.Columns(col =>
{
col.Bound(o => o.ID)
.ClientTemplate("<input class = 't-checkbox-selectrow' type='checkbox' value='#=ID#'/><label></label>")
.HeaderTemplate("<input class = 't-checkbox-selectallrows' type='checkbox' id='selectAll'/><label></label>")
.Sortable(false)
.Filterable(false)
.HtmlAttributes(new { #class = "t-gridcol-selectrow" })
.Width(40)
.Locked(true).Lockable(false);
col.Bound(o => o.StatusName).Width(150);
col.Bound(o => o.Deadline).Width(120);
col.Bound(o => o.Cost).Width(150);
})
.AutoBind(false)
.Pageable(x => x.PageSizes(UIConstants.PageSizes))
.Sortable(x => x.AllowUnsort(false))
.Resizable(resizing => resizing.Columns(true))
.Reorderable(reorder => reorder.Columns(true))
.Scrollable(s => s.Height("Auto"))
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(UIConstants.DefaultPageSizeMax)
.Read(read => read
.Action("GetData", "DataProvider"))
.ServerOperation(false))
)
Then in the JS file i am resetting the grid's page to 1 onRequestEnd, So user always goes back to first page whenever i fetch the data from remote service
$(function(){
var ds = $("#grid").data("kendoGrid").dataSource;
ds.bind("requestEnd", function (e){
e.sender.page(1);
})
})
As per the kendo's documentation
requestEnd
Fired when a remote service request is finished.
However the requestEnd event also gets fire on page change (and sorting). So when i change the page programmatic it fires the requestEnd event again and goes into loop. ( note requestEnd also gets fired when i change Page or Sort manually on UI)
Is this is by design or wrong documentation?

i did something like below. e.response will be only populated when requestEnds as part of response from server. In all other cases it will null.
dataSource.bind("requestEnd", function (e) {
if (e.status != "error" && e.response != null) {
// do soemething here
}
I would really like kendo team either fix the issue or create new event

This question was asked 3 years ago, but I am coming across it while looking up some other information. While I am here, I will answer it for others, as LP13 is likely not concerned about this anymore.
In the HTML Razer code, add the RequestEnd event to the DataSource. Here is an example:
#(Html.Kendo().Grid<GridModel>()
.Name("grid")
// (snip)
.DataSource(dataSource => dataSource
.Ajax()
.Events(o => o.DataBound("onDataBound"))
.PageSize(UIConstants.DefaultPageSizeMax)
.Read(read => read
.Action("GetData", "DataProvider"))
.ServerOperation(false))
)
Now in your jquery, you would write your event handler:
function onRequestEnd(e) {
console.log('onRequestEnd: e.response Object(The raw remote service response) = ', e.response);
console.log('onRequestEnd: e.sender kendo.data.DataSource(The data source instance which fired the event) = ', e.sender);
console.log('onRequestEnd: e.type String (The type of the request) = ', e.type);
}

Related

The Insert data binding setting is required by the insert command Kendo Grid Error anyone

Kendo Grid show the following ERROR
The Insert data binding setting is required by the insert command. Please specify the Insert action or url in the DataBinding configuration
#(Html.Kendo().Grid<Pa.Portal.KazangService.KazangAccount>()
.Name("grids")
.Columns(columns =>
{
columns.Bound(g => g.Id);
columns.Bound(g=>g.UserName);
columns.Bound(g=>g.Password);
columns.Bound(g=>g.Channel);
})
.ToolBar(toolbar => toolbar.Create())
.Pageable()
.Sortable()
.Scrollable()
.AutoBind(true)
.HtmlAttributes(new { style = "height:430px;" })
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(20)
.Model(m => m.Id(h => h.Id))
.Read(read => read.Action("LoadAllkazangAccounts", "Kazang"))
))
CONTROLLER
public ActionResult LoadAll([DataSourceRequest] DataSourceRequest request)
{
IKazangBusinessService client = PaChannelFactory<IKazangBusinessService>.Default.CreateChannel();
IEnumerable<KazangAccount> KaList = client.GetAllKazangAccounts().ToList();
((IChannel)client).Close();
return Json(KaList.ToDataSourceResult(request));
}
The reason why you are getting this error is down to the fact you have added the Create button in your toolbar.
With this added to the grid the datasource section is looking for the create command path.
eg. for your read action you have
.Read(read => read.Action("LoadAllkazangAccounts", "Kazang"))
so you need to add the appropriate insert action like:
.Create(create=> create.Action("CreatekazangAccounts", "Kazang"))
if you don't need to create anything in this grid then just remove the create toolbar menu item from the grid.

Kendo grid virtual scrolling (endless scrolling) does not work

I want to turn on the endless scrolling on a kendo grid, called in this framework as virtual scrolling.
Abstract:
1) I load the page => the Action Virtualization_Read is called (OK)
2) I scroll down the Grid till bottom => the Action Virtualization_Read is called anothter time in order to get more data (KO)
The result is that when I reach the bottom of the grid, with scrollbar, the Action method that retrives the data is not hit anymore.
This is my grid, it shows the traces generated in my application:
#(Html.Kendo().Grid<Credit.Entity.ServiceObjects.MsgBlock>(Model.ListadoTrazas)
.Name("grdTrazas")
.Columns(columns =>
{
columns.Bound(c => c.LogID).Filterable(true);
columns.Bound(c => c.Timestamp).Filterable(false);
columns.Bound(c => c.FormattedMessage).Filterable(false).Width("80%");
})
.Scrollable(s => s.Virtual(true))
})
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(100)
.ServerOperation(true)
.Read(read => read.Action("Virtualization_Read", "Logging"))
)
)
And this is the MVC3 Action that fetches the data. This Action is called only the first time, when the page is loaded:
public ActionResult Virtualization_Read([DataSourceRequest] DataSourceRequest request)
{
return Json(GetData(request.Page, request.PageSize).ToDataSourceResult(request));
}
[NonAction]
private List<MsgBlock> GetData(int page, int getCount)
{
MVCLogging model = new MVCLogging();
// Fetches the data
return model.ListadoTrazas;
}
The Model MsgBlock has the same properties defined in the Grid Columns method:
LogId
TimeStamp
FormattedMessage
Do I forget anything?
The only potential issue I see here is that you are leveraging server operations on the grid, but initializing the grid with a collection of data instead of letting it fetch the initial data. In the Kendo demo for virtualization using the MVC extensions, the grid definition looks like:
#(Html.Kendo().Grid<Kendo.Mvc.Examples.Models.OrderViewModel>()
.Name("grid")
.Columns(columns =>
{
columns.Bound(o => o.OrderID).Width(60);
columns.Bound(o => o.CustomerID).Width(90);
columns.Bound(o => o.ShipName).Width(220);
columns.Bound(o => o.ShipAddress).Width(280);
columns.Bound(o => o.ShipCity).Width(110);
columns.Bound(o => o.ShipCountry).Width(110);
})
.Sortable()
.Scrollable(scrollable => scrollable.Virtual(true))
.HtmlAttributes(new { style = "height:430px;" })
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(100)
.Read(read => read.Action("Virtualization_Read", "Grid"))
)
)
Notice that after the type is supplied (Kendo.Mvc.Examples.Models.OrderViewModel) there is no initial set of data supplied, whereas your initialization attempts to give the grid the data it needs to render (Model.ListadoTrazas). Perhaps this is confusing the grid into thinking it has all the data is needs? I would try taking out Model.ListadoTrazas and letting the grid reach out for the data from the get go.

Kendo UI Grid returns JSON to browser (using MVC)

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

How to determine if there were validation errors after calling (Kendo) grid.SaveChanges() in javascript

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();
}
}

Binding a grid to a drop down list

I have a grid that I want to show depending on the result of the drop down list. I can't seem to be able to send the values to the select("controller", "action", data) method. How can I do that? I can't get my javascript to handle it.
This is the drop down list
<select id="workoutType" onchange="changed(value)">
#{ foreach (var type in Model.WorkoutTypes)
{
<option value="#type"> #type </option>
}
}
</select>
and here is the grid
#(Html.Telerik().Grid(Model.Approvers)
.Name("Orders")
.DataBinding(dataBinding => dataBinding
//Ajax binding
.Ajax()
//The action method which will return JSON
.Select("__AjaxBinding", "AssetResearch", new { workoutType = ViewData["dropDownValue"] })
)
.Columns(columns =>
{
columns.Bound(o => o.InvestorName).Width(125);
columns.Bound(o => o.ApproverType).Title("Type").Width(100);
columns.Bound(o => o.Email).Title("E-mail Address");
})
.ClientEvents(events => events
.OnDataBinding("onDataBinding")
)
.Pageable()
.Sortable()
)
I tried using Viewbag and sadly I can't seem to pull it off.
$(document).ready(function() {
$('#workoutType').change(function(){
//bind your data here
var data = $(this).value;
// pass into your C# stuff here
});
});
Would something like this work?
this is not the right way to achieve it because the RouteValue cannot be set on the server (when you are rendering the Grid)
One way to achieve it is to use the change event of the DropDOwnList which Phonixblade9 mentioned to make the Grid perform request and fetch its data from the server. This could be achieved through the ajaxRequest method of the Grid.
Here is what I mean:
$(document).ready(function() {
$('#workoutType').change(function(){
var data = $(this).value;
var gridClientObject = $('#Orders').data().tGrid;
gridClientObject.ajaxRequest({workoutType :data});// do not forget to name the parameter in the action again method again 'workoutType'
});
});

Resources