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)
Related
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
I have such grid defined
#(Html.Kendo().Grid<FieldViewModel>(Model.Fields)
.HtmlAttributes(new { #class = "fullScreen" })
.Name("formFields")
.ClientDetailTemplateId("formFieldsTemplate")
.Columns(columns =>
{
columns.Bound(e => e.Key);
columns.Bound(e => e.DisplayName);
columns.Bound(e => e.FieldTypeName);
columns.Bound(e => e.Order);
columns.Bound(e => e.IsMandatory);
columns.Bound(e => e.Type);
})
.Pageable()
.Sortable()
.Scrollable()
.Selectable()
.Resizable(resize => resize.Columns(true))
.Groupable()
.Filterable()
.DataSource(dataSource => dataSource.Ajax().ServerOperation(false).Model(model => model.Id(e => e.Key))))
and details template
<script id="formFieldsTemplate" type="text/kendo-tmpl">
#(Html.Kendo().Grid<FieldViewModel>()
.Name("FormField_#=Key#")
.ClientDetailTemplateId("formFieldsTemplate")
.Columns(columns =>
{
columns.Bound(e => e.Key);
columns.Bound(e => e.DisplayName);
columns.Bound(e => e.FieldTypeName);
columns.Bound(e => e.Order);
columns.Bound(e => e.IsMandatory);
columns.Bound(e => e.Type);
})
.DataSource(dataSource => dataSource.Ajax().Read(read => read.Action("LoadFieldDetails", "Forms", new { formPath = Model.Schema, rootElementName = Model.Root ,fieldKey = "#=Key#" })))
.Pageable()
.Sortable()
.Selectable()
.ToClientTemplate())
</script>
As you can see I have Type property (of type int), so what I want to do is not to show any details view and no arrow on the entire row when Type property is set to the specific value. How can I achieve it?
When you define your template like this, then it's used on client side. It's rendered by the #(Html.Kendo().Grid<FieldViewModel>() command but actually then used on client side. But you cannot compare a Type on clientside. but for example, when constructing the model you do:
if (myType is MyDataType) // Do the type check
{
myRow.UseTemplate = 1; // Define ID for template
}
else // ...and so on, can do a 'switch` or whatever
{
myRow.UseTemplate = 2;
}
And here is your template where you switch by Template ID:
<script id="formFieldsTemplate" type="text/kendo-tmpl">
# if (UseTemplate == 1) { #
<div>Template 1</div>
# } else { #
<div>Template 2</div>
# } #
</script>
Not sure if it will work properly if you have different data to display within your data rows... Hope you get the idea though.