Kendo UI Lazy Loading - c#

I am using the following code. Can anybody tell me how will I use the page number instead of scroll bar?
My Index.cshtml page will be like
<div id="CustomerProfile">
<div id="GridCusotmerProfile">
#(Html.Kendo().Grid(Model)
.Name("grdCustomerProfile")
.Columns(coloumns =>
{
coloumns.Bound(p => p.CustomerID).Title("Customer ID");
coloumns.Bound(p => p.UserId).Title("User Id");
coloumns.Bound(p => p.ComapnyName).Title("Company Name");
coloumns.Bound(p => p.ContactPerson).Title("Contact Person");
coloumns.Bound(p => p.AccountNumber).Title("Account Number");
}
)
.Sortable()
.Scrollable(scrollable => scrollable.Virtual(true))
.HtmlAttributes(new { style = "height:430px;" })
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(10)
.Read(read => read.Action("Virtualization_Read", "CustomerProfile"))
)
)
</div>
My Controller will be like the following
public List<CustomerProfileModel> CustomerDataSource(int page, int pagesize, int skip, int take)
{
List<CustomerProfileModel> ModelData = new List<CustomerProfileModel>();
take = skip + take + (page * 10);
var CustomerData = (from cp in context.CustomerProfile select cp).OrderBy(x => x.ComapnyName).Take(take).Skip(skip).ToList();
foreach (var items in CustomerData)
{
CustomerProfileModel Model = new CustomerProfileModel();
Model.CustomerID = items.CustomerID;
Model.AccountNumber = items.AccountNumber;
Model.ComapnyName = items.ComapnyName;
Model.ContactPerson = items.ContactPerson;
Model.UserId = items.UserId;
ModelData.Add(Model);
}
return ModelData;
}
public ActionResult Virtualization_Read([DataSourceRequest] DataSourceRequest request, string page,string pagesize,string skip,string take)
{
return Json(CustomerDataSource(Convert.ToInt32(page),Convert.ToInt32(pagesize),Convert.ToInt32(skip),Convert.ToInt32(take)).ToDataSourceResult(request),JsonRequestBehavior.AllowGet);
}
public List<CustomerProfileModel> CustomerDataSource(int page, int pagesize, int skip, int take)
{
List<CustomerProfileModel> ModelData = new List<CustomerProfileModel>();
take = skip + take + (page * 10);
var CustomerData = (from cp in context.CustomerProfile select cp).OrderBy(x => x.ComapnyName).Take(take).Skip(skip).ToList();
foreach (var items in CustomerData)
{
CustomerProfileModel Model = new CustomerProfileModel();
Model.CustomerID = items.CustomerID;
Model.AccountNumber = items.AccountNumber;
Model.ComapnyName = items.ComapnyName;
Model.ContactPerson = items.ContactPerson;
Model.UserId = items.UserId;
ModelData.Add(Model);
}
return ModelData;
}
public ActionResult Virtualization_Read([DataSourceRequest] DataSourceRequest request, string page,string pagesize,string skip,string take)
{
return Json(CustomerDataSource(Convert.ToInt32(page),Convert.ToInt32(pagesize),Convert.ToInt32(skip),Convert.ToInt32(take)).ToDataSourceResult(request),JsonRequestBehavior.AllowGet);
}
Please let me know if I need something else to get data as lazy loading.

Your on the right tracks, but it is actually a lot easier than you think. Your trying to hand roll functionality that Kendo handles with the `ToDataSourceResult() extension method.
The DataSourceRequest contains all the information needed for database operations, such as ordering, aggregates and paging. So you can simplfy your code down to pretty much the following (NOT TESTED)
public ActionResult Virtualization_Read([DataSourceRequest] DataSourceRequest request)
{
var CustomerData = (from cp in context.CustomerProfile select cp); // don't call toList() this exectues the SQL and pulls data into memory, leave it as a Queryable object so we can pass it to kendo to add its expressions this will the be a Database operation
DataSourceResult result = CustomerData.ToDataSourceResult(request, x => new CustomerProfileModel(){
CustomerID = x.CustomerID;
AccountNumber = x.AccountNumber;
ComapnyName = x.ComapnyName;
ContactPerson = x.ContactPerson;
UserId = x.UserId;
});
return Json(result);
}
For further reading take a look at this link:
http://docs.kendoui.com/getting-started/using-kendo-with/aspnet-mvc/helpers/grid/ajax-binding
From the Kendo Site:
How do I implement paging, sorting, filtering and grouping?
If your model supports the IQueryable interface or is DataTable the grid will do paging, sorting, filtering, grouping and aggregates automatically. For server binding scenarios no additional steps are required - just pass the IQueryable to the Grid constructor. Check the server binding help topic for additional info.
For ajax binding scenarios the ToDataSourceResult extension method must be used to perform the data processing. Check the ajax binding help topic for additional information. If your model does not implement IQueryable custom binding should be implemented. This means that the developer is responsible for paging, sorting, filtering and grouping the data. More info can be found in the custom binding help topic.
Important:
All data operations will be performed at database server level if the underlying IQueryable provider supports translation of expression trees to SQL. Kendo Grid for ASP.NET MVC has been tested with the following frameworks:
Entity Framework
Linq to SQL
Telerik OpenAccess
NHibernate

.Columns(columns =>
{
columns.Bound(p => p.ID).Title("ID").Width(100).Visible(false);
columns.Bound(p => p.Apply).Title("Apply").Width(100);
columns.Bound(p => p.TaxName).Title("Tax Name").Width(100);
columns.Bound(p => p.TaxPercent).Title("Percent").Width(130);
columns.Bound(p => p.OrderApplied).Title("Oreder Applied").Width(130);
columns.Bound(p => p.Compund).Title("Compund").Width(130);
columns.Command(command => { command.Edit(); command.Destroy(); }).Width(172);
})
.ToolBar(toolbar => toolbar.Create())
.Editable(editable => editable.Mode(GridEditMode.InLine))
.Pageable()
.Sortable()
.Scrollable(scr=>scr.Height(430))
//.Scrollable(scrollable => scrollable.Virtual(true))
.HtmlAttributes(new { style = "height:430px;" })
.Filterable()
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(10)
.Events(events => events.Error("error_handler"))
.Model(model => model.Id(p => p.ID))
.ServerOperation(false)
.Create(update => update.Action("EditingInline_Create", "Taxes"))
.Read(read => read.Action("EditingInline_Read", "Taxes"))
.Update(update => update.Action("EditingInline_Update", "Taxes"))
.Destroy(update => update.Action("EditingInline_Destroy", "Taxes"))
)
)

Related

In Kendo MVC Grid, how can I use local values for grid initialisation then later use the read operation?

I have the initial values for the grid in my ViewModel. But if the user wants to update values, I want to update my database, then send back the updated values for the grid from the backend. The problem is that the Ajax Read is always called. But it shouldn't because the (initial) values are there in the ViewModel and bound to Grid.
I tried setting the AutoBind to false, but it does not work, I get an error. (Cannot set AutoBind if widget is populated during initialization)
#(Html.Kendo().Grid<MyClass>()
.Name("MyClassGrid")
.BindTo(Model.MyClassList)
.Columns(column =>
{
column.Bound(c => c.SomeProp).Title("Some Property");
})
.Scrollable()
.DataSource(ds => ds
.Ajax()
.Read(read => read.Action("GetMyData", "CheckBar", new { param1 = Model.ParamFirst}))))
I want to display the already stored values for my grid, and only use the read operation if I want to update the values in my database too.
#(Html.Kendo().Grid<SQDCDashboard.Core.ViewModels.SafetyIncidentViewModel>()
.Name("safetyincident-grid")
.Columns(columns =>
{
columns.Bound(c => c.CreatedAt).HtmlAttributes(new { style = "width: 22%" }).Format("{0:MM/dd/yyyy}");
columns.Bound(c => c.Type).HtmlAttributes(new { style = "width: 22%" });
columns.Bound(c => c.Description).HtmlAttributes(new { style = "width: 22%" });
columns.ForeignKey(c => c.ProductionLineId, (System.Collections.IEnumerable)ViewData["ProductionLines"], "Id", "Name").HtmlAttributes(new { style = "width: 22%" });
columns.Command(command => { command.Edit(); }).HtmlAttributes(new { style = "width: 12%" });
})
.ToolBar(toolbar => toolbar.Create().Text("New Safety Incident"))
.Editable(editable => editable.Mode(GridEditMode.InLine))
.DataSource(ds =>
ds.Ajax()
.ServerOperation(false)
.Model(model =>
{
model.Id(p => p.Id);
model.Field(p => p.ProductionLineId).DefaultValue(Model.DefaultProdLine);
})
.Read(read => read.Action("GetSafetyIncidentList", "Safety"))
.Update(update => update.Action("EditSafetyIncidentInLine", "Safety"))
.Create(create => create.Action("CreateNewSafetyIncident", "Safety"))
)
.HtmlAttributes(new { style = "height: 100%" })
.Sortable()
.Filterable()
.Pageable()
.Mobile()
)
Here is an example of my grid. The Update(update => update.Action("Action" , "Controller"))
is the method you are wondering about. For my code I did not have to pass a parameter in with my read, and I do not need to pass one in with my Update.
[HttpPost]
public ActionResult EditSafetyIncidentInLine([DataSourceRequest] DataSourceRequest request, SafetyIncidentViewModel sivm)
{
if (sivm != null && ModelState.IsValid)
{
SafetyIncident si = _safetyIncidentService.Find(sivm.Id);
si.Description = sivm.Description;
si.ProductionLineId = sivm.ProductionLineId;
si.ProdLine = _productionLineService.Find(sivm.ProductionLineId);
si.Type = sivm.Type;
_safetyIncidentService.Update(si);
sivm.Id = si.Id;
sivm.CreatedAt = si.CreatedAt;
}
return this.Json(new[] { sivm }.ToDataSourceResult(request, ModelState));
}
This method is the one that is called when the Update button is pressed. The update button is created with the columns.Command(command => { command.Edit(); }; and the Editable(editable => editable.Mode(GridEditMode.InLine)). If you want more clarification or if your question is different let me know. I never got an error with having my grid already initialized when I was updating values.

Kendo UI MVC - Grid Paging, Sorting, Refreshing not working with WebAPI binding

When I set the datasource to WebAPI binding, the HTTP GET is being invoked on the controller and it returns the correct data. The problem is that my Kendo Grid is not binding the data correctly, instead I get an empty grid as a result.
#(Html.Kendo().Grid(Model)
.Name("Accounts")
.Columns(columns =>
{
columns.Bound(c => c.Description).Title("Account Name");
columns.ForeignKey(c => c.Type, (System.Collections.IEnumerable)ViewData["accountTypes"], "Id", "Name").Title("Account Type");
columns.ForeignKey(c => c.Currency, (System.Collections.IEnumerable)ViewData["currencyTypes"], "Id", "Name").Title("Account Currency");
columns.Command(command => { command.Edit(); command.Destroy(); }).Width(210);
})
.Sortable(sortable =>
{
sortable.SortMode(GridSortMode.SingleColumn);
sortable.AllowUnsort(false);
})
.Pageable(pageable => pageable
.Refresh(true)
.PageSizes(true)
.ButtonCount(5)
)
.ToolBar(toolbar => { toolbar.Create(); })
.Editable(editable => editable.Mode(GridEditMode.InLine))
.DataSource(dataSource => dataSource
.WebApi()
.Model(model =>
{
model.Id(p => p.Id);
model.Field(p => p.Currency).DefaultValue(0).Editable(true);
model.Field(p => p.Description).Editable(true);
model.Field(p => p.Type).Editable(true);
})
.ServerOperation(true)
.Read(read => read.Action("Get", "Accounts"))
.Create(create => create.Action("Post", "Accounts"))
.Update(update => update.Action("Put", "Accounts", new { id = "{0}" }))
.Destroy(destroy => destroy.Action("Delete", "Accounts", new { id = "{0}" }))
.PageSize(10)
)
)
Controller
// GET: api/values
[HttpGet]
public DataSourceResult Get([DataSourceRequest]DataSourceRequest request)
{
return _context.Accounts.ToDataSourceResult(request);
}
I always get an HTTP 200 OK as a result of the paging or sorting command, but the grid is empty afterwards. The URL generated by Kendo is:
http://localhost:58829/Accounts/Get?sort=&page=1&pageSize=10&group=&filter=
Which actually returns JSON when I open it with a browser.
The problem seems to be that you are mixing two different ways to load the data. On the one hand you are passing the Model by param to the grid (this approach is used when ServerOperation = false) and on the other hand you are setting ServerOperation = true and specifying a read action.
The reason why the grid is empty in this case is probably because either the Model is empty.
Take a look at this demo example for a reference on how to implement the remote source databinding: http://demos.telerik.com/aspnet-core/grid/remote-data-binding
Example View:
Example controller:
Hope this helps KendoGrid is an awesome library but like many other libraries it could definitely use better exception handling and more user friendly exceptions :) In my opinion the grid should have shown an exception in this case.
The problem was this: when declaring the Kendo Grid and passing the Model as a parameter like so:
#(Html.Kendo().Grid(Model)
You need to remove the .Read() action, and make sure to use .ServerOperation(false). This works either with WebApi binding or Ajax binding:
.DataSource(dataSource => dataSource
.WebApi() // also works with .Ajax()
.Model(model =>
{
model.Id(p => p.Id);
}
)
.ServerOperation(false)
.Create(create => create.Action("Post", "Invoices"))
.Update(update => update.Action("Put", "Invoices", new { id = "{0}" }))
.Destroy(destroy => destroy.Action("Delete", "Invoices", new { id = "{0}" }))
.PageSize(10)
)
Also, the DataSourceResult Get() method can be removed.

Refresh after update Telerik Kendo Grid (MVC)

I have a Kendo Grid with some environments data. One of the fields of the grid is "isDefault" wich recieve 1 or 0 (for true or false). In the database I have a trigger that when some record is set to isDefault = 1 any other record is update to isDefault = 0, just to make sure there is only one default environment.
The Kendo grid is working fine, it binds the data and updates the records just fine but after the update, the grid is not refreshing all the records and if there was, lets say, record 1 with isDefault =1 and I update record 4 to isDefault = 1 the trigger is fired and updates all others records to isDefault = 0 but the grid still showing record 1 with isDefault = 1 and now record 4 with isDefault = 1
This is the code on my view:
Html.Kendo().Grid<Models.Environment>()
.Name("environmentGrid")
.Sortable()
.ToolBar(tb => tb.Create())
.Editable(editable => editable.Mode(GridEditMode.PopUp))
.Columns(cols =>
{
cols.Bound(c => c.Name).Width(150).Sortable(true);
cols.Bound(c => c.ConnectionString).Width(150).Sortable(true);
cols.Bound(c => c.Template).Width(150).Sortable(true);
cols.Bound(c => c.isDefault).Width(150).Sortable(true);
cols.Bound(c => c.StatusID).Width(150).Sortable(true);
cols.Command(command => { command.Edit();}).Width(60);
})
.DataSource(ds => ds
.Ajax()
.Model(model =>
{
model.Id(m => m.EnvironmentID);
})
.Read(r => r.Action("GetEnvironments", "Admin"))
.Update(update => update.Action("UpdateEnvironments", "Admin"))
.Create(update => update.Action("UpdateEnvironments", "Admin"))
)
and this is the code on my controller:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult UpdateEnvironments([DataSourceRequest] DataSourceRequest dsRequest, Environment environment)
{
environment.ModifiedBy = userName;
if (environment != null && ModelState.IsValid)
{
if (environment.EnvironmentID != 0)
{
var toUpdate = xgr.EnviromentRepository.ListAll().FirstOrDefault(p => p.EnvironmentID == environment.EnvironmentID);
TryUpdateModel(toUpdate);
}
xgr.EnviromentRepository.Save(environment);
}
return Json(ModelState.ToDataSourceResult());
}
Thank you in advance for your answers.
I finally get it to work. Added an event handler:
Html.Kendo().Grid<Models.Environment>()
.Name("environmentGrid")
.Sortable()
.ToolBar(tb => tb.Create())
.Editable(editable => editable.Mode(GridEditMode.PopUp))
.Columns(cols =>
{
cols.Bound(c => c.Name).Width(150).Sortable(true);
cols.Bound(c => c.ConnectionString).Width(150).Sortable(true);
cols.Bound(c => c.Template).Width(150).Sortable(true);
cols.Bound(c => c.isDefault).Width(150).Sortable(true);
cols.Bound(c => c.StatusID).Width(150).Sortable(true);
cols.Command(command => { command.Edit();}).Width(60);
})
.DataSource(ds => ds
.Ajax()
.Model(model =>
{
model.Id(m => m.EnvironmentID);
})
.Events(events =>
{
events.RequestEnd("onRequestEnd"); //I've added this
})
.Read(r => r.Action("GetEnvironments", "Admin"))
.Update(update => update.Action("UpdateEnvironments", "Admin"))
.Create(update => update.Action("UpdateEnvironments", "Admin"))
)
And a Javascript Function:
function onRequestEnd(e) {
if (e.type == "update") {
$("#environmentGrid").data("kendoGrid").dataSource.read();
}
}
Also I needed to modify my ListAll() Method on the EnvironmentRepository to be like this:
public List<XML_Environment> ListAll()
{
_dataContext = new XMLGenEntitiesDataContext(); //I've to add this line. so the context is instantiated every time I call the ListAll Method.
return _dataContext.XML_Environments.OrderBy<XML_Environment, string>(c => c.EnvironmentName).ToList<XML_Environment>();
}
You are returning the wrong object. I don't really know how you get your data, because you did not posted the GET controller, so I'm going to try to guess it. After you updated your data, you need to send them back to the grid. The ModelState does not contain the data you want. Try this:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult UpdateEnvironments([DataSourceRequest] DataSourceRequest dsRequest, Environment environment)
{
environment.ModifiedBy = userName;
var updatedRecords = null;//1
if (environment != null && ModelState.IsValid)
{
if (environment.EnvironmentID != 0)
{
var toUpdate = xgr.EnviromentRepository.ListAll().FirstOrDefault(p => p.EnvironmentID == environment.EnvironmentID);
TryUpdateModel(toUpdate);
updatedRecords = xgr.EnviromentRepository.ListAll();//2 -- you might need to add "ToList()", depending on your implementation
}
xgr.EnviromentRepository.Save(environment);
}
return Json(updatedRecords.ToDataSourceResult(request, ModelState));//3
}
Please see this link for a complete example.

Kendo MVC Ajax Grid : Values are not showing

net mvc4 project with Kendo UI iam using a simple ajax grid to print values from the database but it is not showing on the grid my code is
<%: Html.Kendo().Grid<CustomerTest.Models.ProductViewModel>()
.Name("grid")
.DataSource(dataSource => dataSource
.Ajax()
.Read(read => read
.Action("Printc", "Home") // Set the action method which will return the data in JSON format
// .Data("productsReadData") // Specify the JavaScript function which will return the data
)
)
.Columns(columns =>
{
columns.Bound(product => product.CustomerID);
columns.Bound(product => product.CustomerFName);
columns.Bound(product => product.CustomerLName);
})
.Pageable()
.Sortable()
%>
and my action method is
public ActionResult Printc()
{
// ViewBag.Message = "Welcome to ASP.NET MVC!";
return View(GetCustomers());
}
private static IEnumerable<ProductViewModel> GetCustomers()
{
var northwind = new CustomerLinqDataContext();
var purchCount = northwind.Customer_details.Count();
return northwind.Customer_details.Select(product => new ProductViewModel
{
CustomerID = product.ID,
CustomerFName = product.name,
CustomerLName = product.lname,
CustomerAge = product.age
});
}
please some one help me put what i am doing wrong? i tried to pass my model on the page header
<%# Page Title="" Language="C#" MasterPageFile="~/Areas/aspx/Views/Shared/Web.Master"
Inherits="System.Web.Mvc.ViewPage<IEnumerable<CustomerTest.Models.ProductViewModel>>" %>
It worked fine but i have mutiple grids on my single page and they are coming from different tables so thats why i want to pass each model differently please someone help me in this code thanks
The problem is on your Printc method. You have to return a Json object create for the Kendo Grid :
public ActionResult Index_Printc([DataSourceRequest] DataSourceRequest request)
{
return Json(GetCustomers().ToDataSourceResult(request));
}
On my side, I specify the ID on the Ajax request, I don't know if it's mandatory for a read request, but if the update of the method doesn't work, add this :
<%: Html.Kendo().Grid<CustomerTest.Models.ProductViewModel>()
.Name("grid")
.DataSource(dataSource => dataSource
.Ajax()
.Model(model => model.Id(p => p.CustomerID))
.Read(read => read.Action("Printc", "Home")
)
)
.Columns(columns =>
{
columns.Bound(product => product.CustomerID);
columns.Bound(product => product.CustomerFName);
columns.Bound(product => product.CustomerLName);
})
.Pageable()
.Sortable()
%>
Hope it helps !
if you have several grids on the same page make sure that they have unique names and not all of them are called grid.

Kendo Grid - Won't bind to remote data MVC

Maddening... Trying to utilize AJAX reads with a Kendo Grid. I've done quite a few binding to data passed down from the model. I copy the code straight from the KendoUI site and tweak to meet my demands:
#(Html.Kendo().Grid<FaultReport2.Models.usp_CMC_TopIssues_Result>()
.Name("grid")
.Columns(columns =>
{
columns.Bound(p => p.description).Title("Description");
columns.Bound(p => p.responsible).Title("Responsibility");
columns.Bound(p => p.charged_time).Title("Time");
columns.Bound(p => p.responsible).Title("Responsible");
columns.Bound(p => p.root_cause).Title("Root Cause");
columns.Bound(p => p.counter_measure).Title("Countermeasure");
columns.Bound(p => p.status).Title("Status");
})
.Pageable()
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(10)
.Read(read => read
.Action("cmcTopIssues", "FaultInfo", new { equipment_id = Model.area_id, start_date = Model.start_date })
)
)
)
Controller code for the read.Action():
public ActionResult cmcTopIssues(int equipment_id, DateTime start_date)
{
var db = new Models.FAULTEntities1();
var top_issues = db.usp_CMC_TopIssues(equipment_id, start_date).ToList();
return Json(top_issues, JsonRequestBehavior.AllowGet);
}
Does not work. I verify that my cmcTopIssues method is being called and that the top_issues var is being filled. It just does not populate the grid.
When I switch over to local and pass the data down through the model, it works fine.
Any help would be appreciated.
Hmm, perhaps try modifying your action method as shown in here so that you return a Kendo data source result instead:
public ActionResult cmcTopIssues([DataSourceRequest]DataSourceRequest request, int equipment_id, DateTime start_date)
{
var db = new Models.FAULTEntities1();
var top_issues = db.usp_CMC_TopIssues(equipment_id, start_date).AsEnumerable();
return Json(top_issues.ToDataSourceResult(request));
}

Categories

Resources