Kendo UI difficulty getting Errors from grid model - c#

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

Related

Telerik Mvc grid with SignalR events not firing

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 "http://localhost", how to solve?

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

Dynamic size of telerik grid

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

Kendo UI grid won't populate from ajax dataSource MVC

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.

Kendo UI Grid paging issue in ASP.NET MVC

In my Kendo UI Grid, I set the Page Size attribute to three - PageSize(3):
#(Html.Kendo().Grid<Kendo.Mvc.Examples.Models.Discount>()
.Name("discountgrid")
.Columns(c=>
{
c.Bound(d => d.Id);
c.Bound(d => d.Category);
c.Bound(d => d.Percentage);
c.Bound(d => d.Merchandise);
c.Command(cm => { cm.Edit(); cm.Destroy(); });
})
.Pageable()
.ToolBar(toolbar => toolbar.Create())
.Editable(editable => editable.Mode(GridEditMode.InCell))
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(3)
.ServerOperation(false)
.Model(model => model.Id(d => d.Id))
.Create(update => update.Action("EditingInline_Create", "Grid"))
.Update(update => update.Action("EditingInline_Update", "Grid"))
.Destroy(update => update.Action("EditingInline_Destroy", "Grid"))
)
)
After adding the first three rows, when I insert the 4th record, the first record disappears (as expected) - but I don't see an option to go to the second page (Page 2) in the grid footer. Why is that? What am I missing?
I think you're missing to provide the READ action to the grid.
You have to specify the Read action on the DataSource and add the RequestEnd event. You can place your DataSource read method inside this event. The event type parameter on the RequestEnd event such as "update","create","destroy" can then be used to determine which operation is complete and reload the data on the grid.
#(Html.Kendo().Grid<Kendo.Mvc.Examples.Models.Discount>()
.Name("discountgrid")
.Columns(c=>
{
c.Bound(d => d.Id);
c.Bound(d => d.Category);
c.Bound(d => d.Percentage);
c.Bound(d => d.Merchandise);
c.Command(cm => { cm.Edit(); cm.Destroy(); });
})
.Pageable()
.ToolBar(toolbar => toolbar.Create())
.Editable(editable => editable.Mode(GridEditMode.InCell))
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(3)
.ServerOperation(false)
.Events(e => { e.RequestEnd("onRequestEnd"); })//onRequestEnd is the javascript fxn
.Model(model => model.Id(d => d.Id))
.Read(read => read.Action("EditingInline_Read","Grid"))
.Create(update => update.Action("EditingInline_Create", "Grid"))
.Update(update => update.Action("EditingInline_Update", "Grid"))
.Destroy(update => update.Action("EditingInline_Destroy", "Grid"))
))
<script type="text/javascript">
function onRequestEnd(e) {
if (e.type === "create" || e.type === "update" || e.type === "destroy") {
e.sender.read();
}
}
</script>
If you need further information, please read this link
Try adding the Read() action to your grid, and for testing purposes, maybe set ServerOperation(true)

Categories

Resources