Kendo grid virtual scrolling (endless scrolling) does not work - asp.net-mvc-3

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.

Related

Kendo DataSource requestEnd event gets fired multiple times

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

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.

How to keep the Kendo grid default grouping from being removed

I have a grid which has default grouping by one of the columns e.g "Important". I allow grouping by other columns, but I want to lock my default grouping. So no one can remove this grouping.
I didn't find any property to achieve this. I tried using the DataBound event change class and removed the remove button of this column in the group header but later the Kendo script reverted this back to its original state.
#(Html.Kendo().Grid<Model>()
.Name("Grid")
.DataSource(ds => ds
.Ajax()
.PageSize(20)
.ServerOperation(false)
.Model(m => m
.Id(z => z.Id))
.Read(r => r.Action("myAction", "myController"))
.Group(g=>g.AddDescending(c=>c.Important))
)
.Columns(c =>
{
c.Bound(d => d.Important)
.Title("This is important")
.Groupable(false)
.Visible(true)
.Hidden(true);
c.Bound(d => d.otherColumn)
.Title("otherColumn")
.Groupable(true);
....
}
.Groupable()
.Events(e=>e
.Change("onChange")
.DataBound("dataBound")
)
)

Adding a Dropdown inside Kendo Grid

I'm trying to add a DropDown inside kendo grid but it displays a TextBox
#(Html.Kendo().Grid((IEnumerable<Doc.Web.Models.Vendor.DocumentsDetails>)Model.documents_lst)
.Name("grid").Scrollable()
.Columns(columns =>
{
columns.Bound(o => o.DocumentRevisionID).Visible(false);
columns.Bound(o => o.Documentnumber).Title("Document #").Width(150);
columns.Bound(o => o.Revision).Title("Revision").Width(80);
columns.Bound(o => o.RevisionDate).Format("{0:dd/MM/yyyy}").Title("Rev Date").Width(85);
columns.Bound(o => o.RevisionStatus).Title("Revision</br> Status").Width(100);
columns.Bound(s => s.DocNumberPurpose).ClientTemplate((#Html.Kendo().DropDownList()
.BindTo((System.Collections.IEnumerable)ViewData["Purpose"])
.Name("DocNumberPurpose")
.DataTextField("Text")
.DataValueField("Value")
.ToClientTemplate()).ToHtmlString());
})
.DataSource(dataSource => dataSource
.Ajax()
.Model(model => model.Id(o => o.DocumentRevisionID))
.Model(model=>model.Field(o=>o.DocNumberPurpose).Editable(false))
)
.Events(ev=>ev.DataBound("onGridDataBound"))
.Pageable()
.Sortable()
.Filterable()
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(5)
.Events(events => events.Error("error_handler"))
.Model(model => model.Id(p => p.DocumentRevisionID))
.Read(read => read.Action("EditingInline_Read", "DesignCoverSheet").Data("additionalInfo"))
)
)
<script>
function onGridDataBound(e) {
$('#grid script').appendTo(document.body);
}
</script>
You're very close actually:
columns.Bound(property => property.neatProperty).Width(38).EditorTemplateName("neatPropertyDropDownList").Title("NeatProperty")
And then in a separate view called "neatPropertyDropDownList.cshtml"
#using System.Collections;
#(Html.Kendo().DropDownList()
.Name("NeatProperty")
.DataTextField("Value")
.DataValueField("Text")
.BindTo("don't forget to bind!")
)
Check this article for a detailed example of exactly what you are trying to do, specifically in step 3
Step 3 – Embedding the Kendo Drop-down List
Basically you can do that in the following manner:
Inside the Kendo grid the property foreign key of your model must be linked to a EditorTemplateName that accepts a template name. As an example:
columns.Bound(e => e.CompanyId).EditorTemplateName("CompaniesList").Title("Company").ClientTemplate("#:CompanyName#");
The template name in the above example is "CompaniesList" which will be a cshtml view file inside EditorTemplates folder.
As per the above article:
The EditorTemplateName specifies to the grid that when either in Create or Edit modes, the template should be placed in the data file named "CompaniesList" that is found in the directory by name of EditorTemplates directory. The subsequent step therefore involves the creation of a folder by name of "EditorTemplates" and place an empty view in it by name of "CompaniesList". The code bit "ClientTemplate(“#:CompanyName#”)" means that when display is in the view mode, (that is, not creating or editing) CompanyName has to be displayed (in this case, it is "Microsoft"). Once this is complete, all what remains to be done is the creation of drop-down list which will be used in the view.
After you create the "CompaniesList" editor template file, you define the Kendo drop down list inside it as follows:
#using System.Collections
#model System.Int32
#(Html.Kendo().DropDownList()
.BindTo((IEnumerable)ViewBag.Companies)
.OptionLabel("- Select Company - ")
.DataValueField("Id")
.DataTextField("Name")
.Name("CompanyId")
)
Note that the drop down Name must be exactly as the column property in the grid which is "CompanyId"
You might look into Kendo Grid ForeignKey Column concept. It can be used as
columns.ForeignKey(p => p.CategoryID, (System.Collections.IEnumerable)ViewData["categories"], "CategoryID", "CategoryName").Title("Category").Width(150);
Detail can be found here http://demos.telerik.com/kendo-ui/web/grid/foreignkeycolumn.html

select Kendo ui grid row from controller

My first problem is : I use kendo grid with Single Select mode and I need when view loaded for the first time, the first row is selected, in other words, i want to select the first kendo grid row programatically.
moreover other problem is i insert radiobutton column in that grid , and i want synchronize
radiobutton select with row select , in other words, i want that when user select row,it causes it's radiobutton Selected
Please help me
tnx
this is the code:
#(Html.Kendo().Grid<CommonData.Domain.LegalEntityPhone>()
.Name("SMSGrid")
.HtmlAttributes(new { style = "width:800px;" })
.Selectable(selectable =>
selectable.Mode(GridSelectionMode.Single).Type(GridSelectionType.Row))
.Columns(columns =>
{
columns.Bound(c => c.Id)
.Title(" ")
.ClientTemplate(" <input type='radio' id='Approve' name='chkApprove' />");
columns.Bound(c => c.Number)
.Title("Destination")
.HeaderHtmlAttributes(new { style = "text-align: center;" })
.HtmlAttributes(new { style = "text-align: center; });
columns.Bound(c => c.CityCode)
.Title("City Code")
.Width(30)
.HeaderHtmlAttributes(new { style = "text-align: center" })
.HtmlAttributes(new { style = "text-align:center;width:30px" });
columns.Command(command => { command.Edit(); }).Width(150);
})
.Editable(editable => editable.Mode(GridEditMode.InLine))
.Events(events => events.Change("OnChange"))
.DataSource(dataSource => dataSource
.Ajax()
.Model(model =>
{
model.Id(p => p.Id);
model.Field(p => p.Id).Editable(false);
})
.Read(read => read.Action("LegalEntityPhoneInfo_Read", "Message"))
.Update(update => update.Action("LegalEntityPhoneInfo_Update", "Message"))
)
)
There is no such thing as making the row selected in the controller because the Grid is all created on the client. You can use the dataBound event to make the first row selected.
e.g.
$(function(){
$('#GridName').data().kendoGrid.bind('dataBound',function(e){
this.select(this.tbody.find('>tr:first'));
})
})
Or use one instead of bind to make the row selected only when the page is loaded, not each time when the Grid is rebound - sort,filter, etc. Check documentation for more info.
If you are unfamiliar with jQuery, I highly recommend you take an online free tutorial from http://jqueryair.com/.
Assuming your project is referencing the jQuery script in your _Layout page, all you should have to do is add an Event handler for Databound to the grid:
.Events(events => events.DataBound("Grid_Databound"))
Then just paste this script onto the page:
<script>
function Grid_Databound() {
var grid = $("#MyGridName").data("kendoGrid");
row = grid.tbody.find(">tr:not(.k-grouping-row)").eq(0);
grid.select(row);
}
</script>
I'm sure the same script that zeinad added would work as well, always more than one way to skin a cat. As far as making the radio button show selected if the row is selected, I think if you watched the tutorial I mentioned, you should be able to figure it out. Post back if you need more help.

Resources