I am trying to convert my Telerik MVC application to Kendo UI MVC but have hit a problem.
We have a basic grid on a page that we only want populating after some form values have been entered and a search button pressed.
I had this working with the Telerik MVC grid by binding the data using javascript after an ajax call to the action.
var
resultsGrid = $(
'#ResultsGrid'
).data(
'tGrid'
);
resultsGrid.dataBind(json);
Is there a way to have a Kendo grid initially blank and then populated in a similar fashion?
Thanks in advance.
Richard.
10 Answers, 1 is accepted
So I have had some luck in getting this to work.
I have the following datasource for the grid.
.DataSource(dataSource => dataSource
.Ajax()
.Read(read => read.Data("kendoDataBinding").Action("TestKendoGrid", "SelectiveEnquiries"))
PageSize(5)
)
I also have the following javascript code
function
kendoDataBinding() {
var
$form = $(
"form"
);
var
data = {
npdFormValues: $form.serializeArray(),
firstPass: firstPass
};
firstPass =
false
;
return
data;
}
So when the page first loads, firstPass is true and this is so that in my action method, the search isn't actually performed.
The reason I do this is because I could not see an .AutoBind(false) configuration setting.
When search is pressed, i run the following bit of JavaScript code.
var
grid = $(
"#ResultsGrid"
).data(
"kendoGrid"
);
grid.dataSource.transport.read();
grid.dataSource.read();
This works fine in chrome but when I run it in Firefox, I get the following JavaScript error:-
b.slice is not a function
This is in kendo.web.min.js.
Any help would be greatly appreciated.
Richard
If it helps this is the full markup for the grid.
@(Html.Kendo().Grid<
NoticeProductionDueResultsViewModel
>()
.Name("ResultsGrid")
.TableHtmlAttributes(new { style = "width:100%;" })
.Columns(columns =>
{
columns.Bound(npdr => npdr.laRef).Width(50).ClientTemplate("<
input
type
=
'checkbox'
name
=
'checkedRecords'
value='<#= laRef #>' />").Title("Tag?");
columns.Bound(npdr => npdr.laRef).Width(75);
columns.Bound(npdr => npdr.dueDate).Width(100).Format("{0:dd/MM/yyyy}");
columns.Bound(npdr => npdr.dueNoticeType).Width(200);
columns.Bound(npdr => npdr.address1).Width(300);
columns.Bound(npdr => npdr.worksRef).Width(200);
columns.Bound(npdr => npdr.startDate).Width(100).Format("{0:dd/MM/yyyy}");
columns.Bound(npdr => npdr.endDate).Width(100).Format("{0:dd/MM/yyyy}");
columns.Bound(npdr => npdr.laRef).Width(75);
columns.Bound(npdr => npdr.roadClass).Width(100);
columns.Bound(npdr => npdr.streetTS).Width(80).ClientTemplate("# if(streetTS) { #<
img
src
=
'../Content/images/greenTick2.png'
width
=
'10px'
height
=
'10px'
/># } else {#<
img
src
=
'../Content/images/redCross.png'
width
=
'10px'
height
=
'10px'
/># } #");
columns.Bound(npdr => npdr.streetRES).Width(80).ClientTemplate("<
input
type
=
'checkbox'
value='<#= streetRES #>' />");
columns.Bound(npdr => npdr.streetPS).Width(80).ClientTemplate("<
input
type
=
'checkbox'
value='<#= streetPS #>' />");
columns.Bound(npdr => npdr.streetED).Width(80).ClientTemplate("<
input
type
=
'checkbox'
value='<#= streetED #>' />");
})
.Events(events => events.Change("onChange"))
.Sortable()
.Groupable()
.Pageable()
.Filterable()
.DataSource(dataSource => dataSource
.Ajax()
.Read(read => read.Data("kendoDataBinding").Action("TestKendoGrid", "SelectiveEnquiries"))
.PageSize(5)
)
.Selectable(selectable => selectable.Mode(Kendo.Mvc.UI.GridSelectionMode.Single))
.Resizable(resize => resize.Columns(true))
.Reorderable(reorder => reorder.Columns(true))
)
Currently it is not possible to cancel the RequestStart event of the DataSource. We will provide such functionality in the future releases. I am sorry for the inconvenience.
All the best,
Petur Subev
the Telerik team
public ActionResult Items_Read([DataSourceRequest]DataSourceRequest request, InventoryItems_Active inventoryItems)
{
try
{
inventoryItems.DataAreaId =
"mdsi";
var items = new InquiryService.InquiryClient().GetInventoryItems(inventoryItems.ItemId, inventoryItems.InventManufacturerId, inventoryItems.ItemGroupId, inventoryItems.DataAreaId).ToList<InventoryItems_Active>();
DataSourceResult result = items.ToDataSourceResult(request);
return Json(result, JsonRequestBehavior.AllowGet);
}
catch (Exception ex)
{
string errorMessage = "An error occurred: " + ex.Message;
}
return null;
What does your client side code look like for populating the grid?
Regards,
Richard
Thank you for the quick resonse here is detailed information.
I am using Entity Framework, and calling a stored proc to populate the grid via WFC service:
public List<
InventoryItems_Active
> GetInventoryItems(string ItemPartNumber, string ItemManufacturer, string ItemCategory, string DataAreaID)
{
return InventoryManager.GetInventoryItems(ItemPartNumber, ItemManufacturer, ItemCategory, DataAreaID);
}
This is calling the manager:
public static List<
PACT.DataModel.InventoryItems_Active
> GetInventoryItems(string ItemPartNumber, string ItemManufacturer, string ItemCategory, string DataAreaID)
{
List<
PACT.DataModel.InventoryItems_Active
> inventoryItems = new List<
PACT.DataModel.InventoryItems_Active
>();
using (AXInquiry_Entities inquiry = new AXInquiry_Entities())
{
inventoryItems = inquiry.mdsi_GetInventoryItems_Active(ItemPartNumber, ItemManufacturer, ItemCategory, DataAreaID).ToList<
InventoryItems_Active
>();
}
return inventoryItems;
}
The Controller:
public ActionResult Index()
{
return View("~/Views/Shared/ModalPopUps/_PartialItemSearchModalDefault.cshtml");
}
public ActionResult AjaxContent()
{
return PartialView("~/Views/Shared/Forms/_PartialItemSearchFormDefault.cshtml");
}
public ActionResult Items_Read([DataSourceRequest]DataSourceRequest request, InventoryItems_Active inventoryItems)
{
inventoryItems.DataAreaId = "mdsi";
InquiryService.InquiryClient client = new InquiryService.InquiryClient();
List<
InventoryItems_Active
> items = client.GetInventoryItems(inventoryItems.ItemId, inventoryItems.InventManufacturerId, inventoryItems.ItemGroupId, inventoryItems.DataAreaId).ToList<
InventoryItems_Active
>();
ViewData["itemList"] = items;
DataSourceResult result = items.ToDataSourceResult(request);
//return View(result);
//return PartialView("~/Views/Shared/Grids/_PartialItemSearchGridDefault.cshtml");
//return PartialView("~/Views/Shared/Forms/_PartialItemSearchFormDefault.cshtml");
return Json(result);
}
The ModalWindow:
@(Html.Kendo().Window()
.Name("ItemSearchWindow")
.Title("Product Search")
.LoadContentFrom("AjaxContent", "ItemSearch")
.Draggable()
.Resizable()
.Width(800)
.Height(600)
.Modal(true)
)
The Grid:
@(Html.Kendo().Grid<
PACT.DataModel.InventoryItems_Active
>()
.Name("ItemSearchGrid")
.Columns(columns =>
{
columns.Bound(p => p.ItemId).Title("Part #");
columns.Bound(p => p.ItemName).Title("Description");
columns.Bound(p => p.InventManufacturerId).Title("Manufacturer");
columns.Bound(p => p.ItemGroupId).Title("Category");
})
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(10)
.Read(read => read.Action("Items_Read", "ItemSearch"))
)
.Pageable()
.Sortable()
)
The AjaxContent Partial:
@{
AjaxOptions test = new AjaxOptions { HttpMethod = "Post", UpdateTargetId = "GridContent", InsertionMode = InsertionMode.Replace };
}
<
div
id
=
"WindowContent"
>
@using (Ajax.BeginForm("Items_Read", "ItemSearch", test, new { id = "itemSearchSubmissionForm" }))
{
@Html.ValidationSummary(true)
<
div
class
=
"form-container"
style="border: 1px solid lightgray; padding: 5px; padding-right: 0px;
margin-right: 5px;">
<
div
class
=
"editor-label"
>
@Html.Label("Part Number")
</
div
>
<
div
class
=
"editor-field"
>
@Html.TextBox("ItemId","")
</
div
>
<
div
class
=
"editor-label"
>
@Html.Label("Manufacturer")
</
div
>
<
div
class
=
"editor-field"
>
@Html.TextBox("InventManufacturerId", "")
</
div
>
<
div
class
=
"editor-label"
>
@Html.Label("Category")
</
div
>
<
div
class
=
"editor-field"
>
@Html.TextBox("ItemGroupId","")
</
div
>
<
input
type
=
"submit"
value
=
"Search"
/>
</
div
>
}
</
div
>
<
div
id
=
"GridContent"
>
@Html.Partial("~/Views/Shared/Grids/_PartialItemSearchGridDefault.cshtml")
</
div
>
Couple Issues: Issue:1:The modal window will come up but change the view behind. How can I get the modal window to just pop up over the current view? Issue:2: When I submit the form, the grid disappears. On load it does appear and if I hardcode values for the parameters, the grid works great with paging, but if I remove the hardcode and submit parameters the grid will disappear within the modal window Is there a step I am missing? Issue:3:I was able to switch this to a ViewData instead of using datasource and get the grid to populate from the search, but then paging does not work it reloads the grid with nothing if you click page 2,3, etc... any Ideas?
I am new to Kendo UI and MVC myself.
I can't really tell how you are opening the Kendo window, what page the window is held in or how you are passing data to the grid after search has been pressed (My understanding is that the grid will only call the read.action on pageload).
I don't know if someone at Telerik can help. Have you tried sending a support ticket? I still have no solution to binding data after page load but am hoping that when the MVC wrappers are properly released there will be better documentation and more features.
Sorry I couldn't be of help.
Richard.
You are having this error because you are returning null in your action. Try replacing it with
json(
new
InventoryItems_Active[]{}.ToDataSourceResult(request),JsonRequestBehavior.AllowGet)
I need a help
I have two Grid "Members" and "Categories" , the Categories grid is with checkboxese . when I select a row from Members gird i want to check all the categories of selected Member in Categories grid .
Categories Grid :
@model MvcRazorSite.Models.HeaderTemplateViewModel
@{using (Html.BeginForm())
{
@(Html.Kendo().Grid(Model.Categories)
.Name("Grid")
.Columns(colums=>
{
columns.Template(@<
text
>
<
input
name
=
"selectedCategories"
type
=
"checkbox"
title
=
"select product"
value
=
"@item.CategoryID"
@{
if (Model.SelectedCategories.Any(p => p.CategoryID == item.CategoryID))
{
@("checked=checked")
}
}/>
</
text
>)
.HeaderTemplate(@<
text
>
<
input
id
=
"selectAllCategories"
type
=
"checkbox"
title
=
"select all"
@{
if (Model.SelectedCategories.Any())
{
@("
checked
=checked")
}
} />
</
text
>)
.Width(50)
.HtmlAttributes(new { style = "text-align:center" })
.HeaderHtmlAttributes(new { style = "text-align:center" });
columns.Bound(p => p.CategoryID);
columns.Bound(p => p.CategoryName);
columns.Bound(p => p.Description);
})
.DataSource(dataSource => dataSource
.Ajax()
.Read(read => read.Action("GetData", "Test")
.Data("additionalData") // the name of the JavaScript function which will return the additional data
)
)
.Pageable()
)
function additionalData() {
var grid = $('#objectsGrid').data('kendoGrid');
var id;
grid.select().each(function () {
var dataItem = grid.dataItem($(this));
return {id : dataItem.MemberID };
}
//Action Executed after seletec Row
public ActionResult GetData([DataSourceRequest]DataSourceRequest request, string id, int[] selectedCategories)
{
MiniSiteDBEntities DBContext = new MiniSiteDBEntities();
if(!string.IsNullOrEmpty(id))
selectedCategories = GetCategoryByMember(id);
var categories = GetCategories();
selectedCategories = selectedCategories ?? new int[0];
IEnumerable<
CategoryViewModel
> Categories = GetCategories();
IEnumerable<
CategoryViewModel
> SelectedCategories = GetCategories();
HeaderTemplateViewModel headers = new HeaderTemplateViewModel
{
Categories = categories,
SelectedCategories = categories.Where(p => selectedCategories.Contains(p.CategoryID))
};
var result = new DataSourceResult()
{
Data = Categories
};
// return Json(result, JsonRequestBehavior.AllowGet);
return Json(new[] { headers }.ToDataSourceResult(request),JsonRequestBehavior.AllowGet);
}