I'm trying to populate kendo grid with my model from ajax call. This is my Kendo Ui Grid with Html.Helpers in .cshtml
<div id="grid">
#(Html.Kendo().Grid<OtpadModel.AddressObject>()
.Name("Grid")
.Pageable()
.Sortable()
.Selectable(sel =>
{
sel.Mode(GridSelectionMode.Single);
})
.Filterable()
.Scrollable()
.Events(events => events.Change("onChange"))
.Groupable()
.DataSource(dataSource => dataSource
.Ajax()
.Read(read => read.Action("GetAddressObjects", "AddressObject"))
.Model(model => model.Id(p => p.ID)))
.Columns(columns => {
columns.Bound(p => p.KeyNumber).Title("Šifra objekta");
columns.Bound(p => p.ObjectType.Type).Title("Vrsta objekta");
columns.Bound(p => p.ObjectOwners.FirstOrDefault().Owner.Name).Title("Ime vlasnika");
columns.Bound(p => p.ObjectOwners.FirstOrDefault().Owner.Surname).Title("Prezime vlasnika");
columns.Bound(p => p.Address.Street).Title("Ulica");
columns.Bound(p => p.Address.Number).Title("Broj");
columns.Bound(p => p.Address.City.Name).Title("Grad");
columns.Bound(p => p.ResidentalArea).Title("Površina");
columns.Bound(p => p.ResidentsNumber).Title("Članovi");
columns.Bound(p => p.TuristBedsNumber).Title("Turistički kreveti");
})
)
</div>
My controller method implementation is:
public ActionResult GetAddressObjects([DataSourceRequest] DataSourceRequest request)
{
IEnumerable<AddressObject> addressObjects = unitOfWork.AddressObjectRepository.Get(includeProperties: "ObjectType, Address, ObjectOwners");
DataSourceResult result = addressObjects.ToDataSourceResult(request);
return Json(result, JsonRequestBehavior.AllowGet);
}
I have all refernces. I can populate from my server side, so when I write Grid(Model) grid is populated but I don't want this.
Thank you all for your huge help. The problem was that one of my classes had one virtual property and the problem is that virtual keyword. You cannot have anything virtual, map always to ViewModel. But accidentally, one of my properties in my ViewModel was virtual (copy, paste mistake).
Set the property autobind to false.
#(Html.Kendo().Grid<OtpadModel.AddressObject>()
.Name("Grid")
.Pageable()
.Sortable()
.Selectable(sel =>
{
sel.Mode(GridSelectionMode.Single);
})
.AutoBind(false)
.Filterable()
.Scrollable()
.Events(events => events.Change("onChange"))
.Groupable()
.DataSource(dataSource => dataSource
.Ajax()
.Read(read => read.Action("GetAddressObjects", "AddressObject"))
.Model(model => model.Id(p => p.ID)))
.Columns(columns => {
columns.Bound(p => p.KeyNumber).Title("Šifra objekta");
columns.Bound(p => p.ObjectType.Type).Title("Vrsta objekta");
columns.Bound(p => p.ObjectOwners.FirstOrDefault().Owner.Name).Title("Ime vlasnika");
columns.Bound(p => p.ObjectOwners.FirstOrDefault().Owner.Surname).Title("Prezime vlasnika");
columns.Bound(p => p.Address.Street).Title("Ulica");
columns.Bound(p => p.Address.Number).Title("Broj");
columns.Bound(p => p.Address.City.Name).Title("Grad");
columns.Bound(p => p.ResidentalArea).Title("Površina");
columns.Bound(p => p.ResidentsNumber).Title("Članovi");
columns.Bound(p => p.TuristBedsNumber).Title("Turistički kreveti");
})
Then, in your document ready or some other page event, execute this code:
var grid = $("#yourgridElementName").data("kendoGrid");
grid.dataSource.read();
Hope this helps. Good luck.
Related
How can I delete a row from a Kendo Grid with confirmation and passing in the selected ID into the Destroy method? Here's my cshtml code:
#(Html.Kendo().Grid<EmailTemplateEditor.Models.EmailTemplate>()
.Name("EmailTemplates")
.Columns(columns =>
{
columns.Bound(c => c.ID).ClientTemplate("<a href='/EmailTemplate/EmailTemplate/#=ID#'>#=ID#</a>");
columns.Bound(c => c.Name);
columns.Bound(c => c.Subject);
columns.Bound(c => c.OperationalBrand);
columns.Bound(c => c.Body);
columns.Bound(c => c.DateAdded).Format("{0:MM/dd/yyyy}");
columns.Command(command => command.Destroy()).Width(110);
})
.HtmlAttributes(new { style = "height: 700px;" })
.Scrollable()
.Groupable()
.AutoBind(true)
.Sortable()
.Filterable()
.Pageable(pageable => pageable
.PageSizes(true)
.ButtonCount(5))
.DataSource(dataSource => dataSource
.Ajax()
.Model(model => model.Id(p => p.ID))
.Read(read => read.Action("GetEmailTemplates", "Home"))
.PageSize(20)
.ServerOperation(true)
.Destroy(update => update.Action("Delete", "Home", Model.ID))
)
)
And here is my controller method:
[HttpPost]
public ActionResult Delete([DataSourceRequest] DataSourceRequest request, int ID)
{
Worker.DeleteEmailTemplate(ID);
return View();
}
When I run this, I get an error saying that Model.ID is null. If I can't access the current row's ID in that way, how can I do it? I'd really like to avoid having to refactor this to use a "transport" style of datasource, but if that's the only way to do it, please let me know. Here's what the UI looks like:
Thanks
Change your Destroy command to the following.
.Destroy(update => update.Action("Delete", "Home"))
Then your controller to:
public ActionResult Delete([DataSourceRequest] DataSourceRequest request, EmailTemplate myModel)
Then you can access the id using
myModel.ID
I have a Telerik MVC Grid bound by SignalR. I'm looking to color the records conditionally dependent on a value in a given column (EventHexCode). To do this I need to fire an event on DataBound. I have used this many times with an AJAX datasource without having any issues firing events. But for the life of me I cannot get the DataBound event to fire with a SignalR data source.
I've used this method to achieve this in the past: https://docs.telerik.com/kendo-ui/controls/data-management/grid/how-to/Layout/style-rows-cells-based-on-data-item-values#iterate-the-table-rows
Here is my view:
#(Html.Kendo().Grid<DirectOrderTracker.Models.ViewModels.TempOrderViewModel>()
.Name("grid")
.ToolBar(toolBar =>
{
toolBar.Create();
// toolBar.Save();
})
.Filterable(ftb =>
{
ftb.Extra(false);
ftb.Operators(op =>
{
op.ForString(str =>
{
str.Clear().Contains("Contains");
});
});
})
.Editable(editable => editable.Mode(GridEditMode.InCell))
.Pageable()
.Events(e => { e.DataBound("onDataBound"); })
.Navigatable()
.Sortable()
.Scrollable()
.HtmlAttributes(new { style = "height:650px;" })
.Columns(columns =>
{
columns.Bound(p => p.TempOrderID).Hidden();
columns.Bound(p => p.EventHexCode).ClientTemplate("<span style='display: inline-block; width: 100%; height: 100%; background-color: #= EventHexCode #'> </span>").EditorTemplateName("ColorPicker").Width(120);
columns.ForeignKey(p => p.CustCode, (System.Collections.IEnumerable)ViewData["defaultCustCode"], "CustCode", "CustDesc").Title("Customer").EditorTemplateName("CustDescAutoComplete").Width(180);
columns.Bound(p => p.PONum).Title("Our PO#").Width(90);
columns.Bound(p => p.CustRef).Title("Cust Ref#").Width(90);
columns.Bound(p => p.ApptTime).Title("Appt").Width(70).Filterable(x => x.UI(GridFilterUIRole.TimePicker));
columns.Bound(p => p.Qty).Width(65).Filterable(false);
columns.ForeignKey(p => p.ProdNum, (System.Collections.IEnumerable)ViewData["defaultProdNum"], "ProdNum", "ProdDesc").Width(130).Title("Size/Spec").EditorTemplateName("ProdNumAutoComplete");
columns.Bound(p => p.SalePrice).Format("{0:c}").Width(75).Title("Price").Filterable(false);
columns.Bound(p => p.SONum).Title("Our SO#").Width(120);
columns.Bound(p => p.DueDate).Format("{0:MM/dd/yyyy}").Width(120).Title("Due Date");
columns.Bound(p => p.LoadDate).Format("{0:MM/dd/yyyy}").Width(120).Title("Load Date");
columns.ForeignKey(p => p.VendCode, (System.Collections.IEnumerable)ViewData["defaultVendCode"], "VendCode", "VendDesc").Title("Vendor").EditorTemplateName("VendDescAutoComplete").Width(130);
columns.Bound(p => p.Cost).Format("{0:c}").Width(75).Title("Cost").Filterable(false);
columns.Bound(p => p.Manifest).Title("Mani").Width(55);
columns.Bound(p => p.VendPO).Title("Ven PO#").Width(120);
columns.Bound(p => p.VendRef).Title("Ven Ref#").Width(120);
columns.ForeignKey(p => p.CarrCode, (System.Collections.IEnumerable)ViewData["defaultCarrCode"], "CarrCode", "CarrDesc").EditorTemplateName("CarrDescAutoComplete").Title("Truck").Width(120);
columns.Bound(p => p.FrghtRate).Format("{0:c}").Width(75).Title("Frght").Filterable(false);
columns.Bound(p => p.Comment).Title("Comment").Width(120);
columns.Command(command =>
{
// command.Edit();
command.Destroy();
}).Width(110);
})
.DataSource(dataSource => dataSource
.SignalR()
.AutoSync(true)
.Events(events => events.Push(#<text>
function(e) {
// var notification = $("#notification").data("kendoNotification");
// notification.success(e.type);
}
</text>))
.PageSize(24)
.Transport(tr => tr
.Promise("hubStart")
.Hub("hub")
.Client(c => c
.Read("read")
.Create("create")
.Update("update")
.Destroy("destroy"))
.Server(s => s
.Read("read")
.Create("create")
.Update("update")
.Destroy("destroy"))
)
.Schema(schema => schema
.Model(model =>
{
model.Id(p => p.TempOrderID);
model.Field(p => p.CustCode).Editable(true);
model.Field(p => p.DueDate).Editable(true);
model.Field(p => p.LoadDate).Editable(true);
model.Field(p => p.ProdNum).Editable(true);
model.Field(p => p.Qty).Editable(true);
model.Field(p => p.CarrCode);
model.Field(p => p.VendCode).Editable(true);
model.Field(p => p.SalePrice).Editable(true);
}
))))
Here is the javascript:
<script>
function onDataBound(arg) {
alert("Grid data bound");
}
</script>
To summarize, I'm looking to color the rows conditionally. To do this I need to fire a DataBound event and go through the table and update the CSS. What do you guys think?
Okay, very silly mistake. I have multiple grids in this project that all share the same javascript file. I didn't realize I already had declared a 'onDataBound' function.
I renamed the grid event 'onDataBoundTempOrders' and wrote the appropriate javascript.
Here is ultimately the solution:
.Events(events => events.DataBound("onDataBoundTempOrders"))
Javascript:
function onDataBoundTempOrders(e) {
var grid = this;
grid.tbody.find('>tr').each(function () {
var dataItem = grid.dataItem(this);
$(this).css("background-color", dataItem.EventHexCode);
});
$("#grid tr.k-alt").removeClass("k-alt");
}
So now when a user selects a hex color, it's stored in the table. The hex code is applied via jquery to the table row. Works like a champ.
Binding kendo grid to local data, It ajax current page("http://localhost"), how to solve?
When the page load, the current page("http://localhost") get 2 times.
My View
#(Html.Kendo().Grid<Models.RecordModel>()
.Name("ResultGrid")
.Columns(columns =>
{
columns.Bound(p => p.ProductTitle).Width(250).Title("Title").HtmlAttributes(new {#class = "GridTextLeft"});
columns.Bound(p => p.ProductCode).Width(110).Title("Code").HtmlAttributes(new {#class = "GridTextLeft"});
})
.Scrollable(scr => scr.Height(380))
.DataSource(dataSource => dataSource
.Ajax()
.ServerOperation(false)
.PageSize(10)
.Model(model =>
{
model.Id(p => p.ProductId);
model.Field(p => p.ProductTitle);
model.Field(p => p.ProductCode);
})
)
.Resizable(resize => resize.Columns(true))
.Pageable(pager => pager
.ButtonCount(1)
.PreviousNext(true)
.Messages(t => t.Display("{2} item"))
)
)
It needs that Kendo Grid to be pointed to your controller method that returns data if it is Ajax binding:
...
.DataSource(dataSource => dataSource
.Ajax()
.Read(read => read.Action("Products_Read", "Home")) //Set the action method which will return the data in JSON format.
)
)
...
Check the manual at http://docs.telerik.com/kendo-ui/aspnet-mvc/helpers/grid/binding/ajax-binding .
UPDATE. If you require server binding then apply the BindTo method as per http://docs.telerik.com/kendo-ui/aspnet-mvc/helpers/grid/binding/server-binding
I have the following grid in a ASP.NET MVC project.
<div class="actualGrid" id="actualGrid">
#(Html.Kendo().Grid<PROJECT.Models.Bench>()
.Name("grid")
.Columns(columns =>
{
columns.Bound(p => p.name).Title("Bench").Filterable(ftb => ftb.Cell(cell => cell.Operator("contains"))).Width(125);
columns.Bound(p => p.freeSeats).Title("Free Seats").Width(350);
columns.Command(command => { command.Custom("checkBench1 ").Text(" AM ").Click("doCheckIn"); command.Custom("checkBench 2").Text(" PM ").Click("doCheckIn"); command.Custom("checkBench3").Text("All Day").Click("doCheckIn"); }).Width(250).Title("Check in");
})
//.Editable(editable => editable.Mode(GridEditMode.PopUp))
.Pageable()
.Sortable()
.Scrollable()
.Filterable(ftb => ftb.Mode(GridFilterMode.Row))
.HtmlAttributes(new { style = "height:530px;" })
.Events(events => events.DataBound("onDataBound"))
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(20)
.Events(events => events.Error("error_handler"))
.Model(model => model.Id(p => p.id))
.Read(read => read.Action("GetBenches", "Home"))
)
)
</div>
I would like to know if there is a way to change the size(height) of the grid according to the number of results I have when I use filter.
For Example if I filter first column and get 1 result grid would be small, and if I had 10 results it would be larger.
use this line for it:
.Scrollable(scrolling => scrolling.Enabled(false))
In a Kendo UI grid I have an InLine edit which I am validating server side and if errors exist I return them in the json. I have gotten this far, but I am struggling to pull those errors out of the object to handle them. I will put in the code below starting with the problem and working backward.
I am grabbing the model from the Edit event. The model is populated, I can see the errors in the console, but the value of my errors variable in the below is null.
function onEdit(e) {
var errors = e.model.Errors;
console.log(errors);
console.log(e.model);
};
Here is my cshtml grid setup where I configure the Edit event and editable code.
#(Html.Kendo().Grid<RosterGridViewModel>()
.Name(gridId)
.HtmlAttributes(new {style="height: 400px;"})
.Columns(columns => {
columns.Bound(p => p.ApprovalStatus);
columns.Bound(p => p.LastName);
columns.Bound(p => p.FirstName);
columns.Bound(p => p.Birthdate).Format("{0:M/dd/yyyy}");
columns.Bound(p => p.Uic).Title("UIC");
columns.Bound(p => p.DateAdded).Format("{0:M/dd/yyyy}");
columns.Command(command => { command.Edit(); command.Destroy(); }).Width(190);
})
.Sortable()
.Scrollable()
.Editable(editable => editable.Mode(GridEditMode.InLine))
.Selectable(selectable => selectable.Mode(GridSelectionMode.Multiple))
.Events(events => events.DataBound("onDataBound").Edit("onEdit"))
.DataSource(dataSource => dataSource
.Ajax()
.Batch(true)
.Read(o => o.Action(AppRoute.RosterGridRead.ToMethod(), AppRoute.RosterGridRead.ToController()))
.Update(o => o.Action(AppRoute.RosterEdit.ToMethod(), AppRoute.RosterEdit.ToController()))
.Destroy(o => o.Action(AppRoute.RosterGridDestroy.ToMethod(), AppRoute.RosterGridDestroy.ToController()))
.Group(groups => groups.Add(p => p.School))
.Model(model =>
{
model.Id(p => p.Id);
model.Field(p => p.Id).Editable(false);
model.Field(p => p.ApprovalStatus).Editable(false);
model.Field(p => p.DateAdded).Editable(false);
}
)
)
.ToolBar(toolbar => toolbar.Custom().Text(ActionLabel.DeleteSelection.GetDescription()).HtmlAttributes(new { onclick = "deleteSelection(event)" }))
)
You have to convert the e.model.Errors object to JSON first as shown below and then you can grab any property/key you need.
e.model.Errors.toJSON().Message