I'm trying to populate a kendo grid within a kendo window in MVC and am unable to find what is wrong. The window is created, and the grid is created within the window... however the DataSource's Read method is never called.
Window:
#{
Html.Kendo().Window()
.Name("DListing")
.Title("Listing")
.Draggable()
.Resizable()
.Width(1000)
.Height(500)
.Visible(true)
.Modal(true)
.Actions(actions => actions
.Maximize()
.Close())
.LoadContentFrom("Dispatch", "Listing", new { Number = #ViewBag.Number })
.Render();}
The Dispatch method in the Listing controller returns back a partial view that contains the grid.
Grid:
#(Html.Kendo().Grid(Model)
.Name("Grid")
.Events(events => events.Change("onChange"))
.HtmlAttributes(new { style = "height:400px;" })
.Columns(columns =>
{
columns.Bound(p => p.Number);
columns.Bound(p => p.DateTime).Format("{0:MM/dd/yyyy hh:mm tt}");
columns.Bound(p => p.Location);
columns.Bound(p => p.Name);
columns.Bound(p => p.Elapsed_Hours);
})
.Groupable()
.Pageable(pageable => pageable
.Numeric(false)
.Input(true)
.PageSizes(new[] { 5, 10, 25 }))
.Sortable()
.Scrollable(scrollable => scrollable
.Virtual(true))
.Filterable()
.Selectable(selectable => selectable
.Mode(GridSelectionMode.Multiple))
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(13)
.Sort(sort => { sort.Add(p => p.DateTime).Descending(); })
.Model(model => { model.Id(p => p.Number); })
.Read(read => read.Action("Listing_Read", "Listing", new { Number = #ViewBag.Number })))
)
Listing_Read Method:
public ActionResult Listing_Read([DataSourceRequest] DataSourceRequest request, int Number)
{
return Json(GetListing(branchNumber).ToDataSourceResult(request), JsonRequestBehavior.AllowGet);
}
Also, it should be noted that I went through and verified that the viewbag data is available for both the window and later on in the grid.
For a little more back info, I initially had the grid on it's own page and it was able to call the read method and populated with the data with no issues. After moving it to populate in the window is when this became a problem.
Monitoring the http requests, the grid never attempts to call the read method (so the request isn't failing). I tried manually refreshing the datasource after the window has loaded thinking that might force the call, but that doesn't call the read method either.
I've been scratching my head on this one for a few hours now trying different things, hoping someone can spot what the problem is :)
Here's what worked for me:
1) View (~/Views/Home/Index.cshtml)
#(Html.Kendo().Window()
.Name("myWindow")
.Title("Title")
.Actions(actions => actions.Pin().Minimize().Maximize().Close())
//.Content(Html.Partial("gridCat").ToHtmlString())
.LoadContentFrom("Load_gridCat", "Home")
)
2) Partial View (~/Views/Shared/gridCat.cshtml)
#(Html.Kendo().Grid<TelerikMvcApp1.Models.Category>()
.Name("CategoriesGrid")
.Columns(columns =>
{
columns.Bound(c => c.CategoryID).Title("Category").Width("10%");
columns.Bound(c => c.CategoryName);
columns.Bound(c => c.Description);
})
.Filterable()
.Pageable()
.Sortable()
.Scrollable()
.DataSource(dataSource => dataSource
.Ajax()
.Model(model => model.Id(p => p.CategoryID))
.Read(r => r.Action("Categories_Read", "Home"))
)
.HtmlAttributes(new { style = "height:250px" })
)
3) Controller (~/Controllers/HomeController.cs)
public ActionResult Load_gridCat()
{
return PartialView("gridCat");
}
public ActionResult Categories_Read([DataSourceRequest]DataSourceRequest request)
{
using (var ctx = new NWindContext())
{
IQueryable<Category> categories = ctx.Categories;
DataSourceResult result = categories.ToDataSourceResult(request);
return Json(result, JsonRequestBehavior.AllowGet);
}
}
Related
I am trying to open kendo grid in popup on clicking of link. Kendo grid Opens in popup perfectly, but filtering and sorting functionality is not working. I am using server side Operation. When I sort particular column In controller side in DatasourceRequest I always gets value as null.
Any help is highly appreciated..
<div class="panel-body" id="countryImageData">
#(Html.Kendo().Grid(Model.GlobalInventoryImages)
.Name("InventoryCountryImageDetailsGrid")
.Columns(columns =>
{
columns.Bound(p => p.SmartInventoryID).Hidden().Title("SPC #").HtmlAttributes(new { #id = "CountrySmartInventory_Grid" });
columns.Bound(p => p.SubwayProductCode).Width(50).Title("SPC #").HtmlAttributes(new { #id = "CountrySubwayProductCode_Grid" });
columns.Bound(p => p.GlobalCaseImageName).Width(100).Title("Case Images").HtmlAttributes(new { #id = "GlobalCaseGraphicName_Grid" }).ClientTemplate(" #=GlobalCaseImageName# ");
columns.Bound(p => p.GlobalInnerImageName).Width(100).Title("Inner Images ").HtmlAttributes(new { #id = "GlobalInnerImageName_Grid" }).ClientTemplate(" #=GlobalInnerImageName# ");
columns.Bound(p => p.CountryNames).Width(100).Title("Country").HtmlAttributes(new { #id = "CountryNames_Grid" });
})
.Pageable(pager => pager.PageSizes(new int[] { 25, 50, 75, 100 }).Input(true))
.Sortable(e => e.AllowUnsort(true).SortMode(GridSortMode.MultipleColumn))
.Scrollable()
.ColumnMenu()
.NoRecords("No Records")
.Selectable(e => e.Mode(GridSelectionMode.Multiple))
.Filterable()
.ColumnResizeHandleWidth(10)
.ColumnResizeHandleWidth(10)
.Resizable(resize => resize.Columns(true))
.Reorderable(reorder => reorder.Columns(true))
.HtmlAttributes(new { #class = "custom-kendo-grid custom-kendo-grid-inv" })
.DataSource(dataSource => dataSource
.Ajax()
.ServerOperation(true)
.PageSize(25)
.Read(read => read.Action("InventoryImage_Read", "Inventory").Data("function onCountryAdditonalData(){ return {subwayProductCode: $('#SubwayProductCode').val()};}"))
)
)
</div>
With MVC you have to add the following in your dataSource:
type: 'aspnetmvc-ajax'
for the filter and sort not to be null. Also, your Action method in your MVC Controller must have parameters set up like so:
public async Task<ActionResult> InventoryImage_Read([DataSourceRequest] DataSourceRequest )
You didn't post your MVC Controller Action so I wasn't sure if you had that part set up correctly. I hope this helps.
I have one grid like this :
#(Html.Kendo().Grid<ProductViewModel>()
.Name("Grid")
.Columns(columns =>
{
**columns.Bound(c => c.Logo).ClientTemplate();**
columns.Bound(p => p.Title);
columns.Bound(p => p.Category);
columns.Bound(p => p.SupplierName);
columns.Bound(p => p.SupplierContactName);
columns.Bound(p => p.IsDeleted);
columns.Bound(p => p.TimeStamp).Format("{0:yyyy/MM/dd HH:mm}").EditorTemplateName("DateTime"); ;
//columns.Command(command => { command.Edit(); command.Destroy(); }).Width(220).Title("Command");
//columns.Command(command => { command.Edit(); command.Destroy(); }).Width(250);
})
.Pageable()
.Scrollable()
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(20)
.Events(events => events.Error("error_handler"))
.Model(model => model.Id(p => p.ID))
.Read(read => read.Action("EditingCustomValidation_Read", "Product"))
)
And I have one action like this for Showing image :
public FileContentResult Photo(int id)
{
return new FileContentResult(db.Products.Find(id).Logo, "image");
}
What should I write in my ClientTemplate for calling this action sending productid an showing products logo?
Please you can try like this...
columns.Bound(c => c.Logo).ClientTemplate("<img src='" + Url.Content("~/ImagePath/") + "#=ImageUrl#' alt='#=Name #' Title='#=Name #' height='62' width='62'/>");
One of my colleague ran into same issue and we posted question on telerik forum Bind image path to a controller function in Kendo Grid and they responded as below.
I think instead of your controller returning a string with the URL of the image it might be easier for it to just return the image itself. Some thing like this post on stackoverlow
That way you can just have your template point the src property of the img html element to this controller action that would presumably take as parameter something to pinpoint the corresponding image file to each row element.
I am using Kendo Grid for MVC.
Following is my controller and actions.
public class ComplainController : Controller
{
private MSMContext db = new MSMContext();
public ActionResult Index([DataSourceRequest]DataSourceRequest request)
{
var cOMPLAINs = db.COMPLAINs.Include(c => c.MASTER_FAULT);
var model = cOMPLAINs.Select(o => new
{
JOBSHEET_NO = o.JOBSHEET_NO,
CUSTOMER_NAME = o.CUSTOMER_NAME,
CUSTOMER_MOBILE = o.CUSTOMER_MOBILE,
COMPANY_NAME = o.COMPANY_NAME,
MODEL_NAME = o.MODEL_NAME
});
return Json(model.ToDataSourceResult(request), JsonRequestBehavior.AllowGet);
}
public ActionResult GetData([DataSourceRequest]DataSourceRequest request)
{
var model = db.COMPLAINs.Select(o => new
{
JOBSHEET_NO = o.JOBSHEET_NO,
CUSTOMER_NAME = o.CUSTOMER_NAME,
CUSTOMER_MOBILE = o.CUSTOMER_MOBILE,
COMPANY_NAME = o.COMPANY_NAME,
MODEL_NAME = o.MODEL_NAME
});
return Json(model.ToDataSourceResult(request), JsonRequestBehavior.AllowGet);
}
}
Now Following is my Kendo Grid Code I am using in a view.
#(Html.Kendo().Grid<WebMSM.Models.COMPLAIN>()
.Name("grid")
.Columns(columns =>
{
columns.Bound(p => p.JOBSHEET_NO).Width(150);
columns.Bound(p => p.CUSTOMER_NAME).Width(400);
columns.Bound(p => p.CUSTOMER_MOBILE).Width(200);
columns.Bound(p => p.COMPANY_NAME).Width(200);
columns.Bound(p => p.MODEL_NAME).Width(150);
})
.Pageable()
.Sortable()
.Scrollable()
.Filterable()
.HtmlAttributes(new { style = "height:430px;" })
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(20)
.Read(read => read.Action("GetData", "Complain"))
)
)
If I use GetData action, Kendo Grid is working fine with all data shown.
But if I use Index action, Kendo Grid displays but without data.
While using Index action, following json data is displayed without any page layout and HTML.
{"Data":[{"JOBSHEET_NO":1018,"CUSTOMER_NAME":"HEMAL RATHOD","CUSTOMER_MOBILE":"9825369987","COMPANY_NAME":"SAMSUNG","MODEL_NAME":"NOTE 3"},{"JOBSHEET_NO":1019,"CUSTOMER_NAME":"MUKESH CHAUHAN","CUSTOMER_MOBILE":"9825305305","COMPANY_NAME":"APPLE","MODEL_NAME":"IPHONE 6"}],"Total":2,"AggregateResults":null,"Errors":null}
What am I missing?
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(20)
.Read(read => read.Action("GetData", "Complain"))
)
)
needs to be changed to
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(20)
.Read(read => read.Action("Index", "Complain"))
)
)
if you want to get it working with "Index". If your datasource never calls "Index" action method, then your grid will always be empty.
I have a Kendo Grid which has a popup editable template,
If possible i would like to pass the model (the model of the row, or at least its Id) to the editable template
Grid
#(Html.Kendo().Grid<Client>()
.Name("grid")
.Columns(columns =>
{
columns.Bound(c => c.Name).Width(140);
columns.Bound(c => c.Status);
columns.Bound(c => c.ProcesingStyle);
columns.Bound(c => c.ArchiveDays);
columns.Command(command =>
{
command.Edit().Text(" ");
command.Destroy().Text(" "); ;
}).Width(90);
})
.ToolBar(toolbar => toolbar.Create().Text("New"))
.Editable(editable => editable
.Mode(GridEditMode.PopUp)
.TemplateName("Client").AdditionalViewData(new { Client = Model })
.Window(w => w.Title("Site")))
.HtmlAttributes(new { style = "height: 380px;" })
.Scrollable()
.Sortable()
.Selectable()
.Resizable(resize => resize.Columns(true))
.Reorderable(reorder => reorder.Columns(true))
.Events(events => events.Change("onChange"))
.Pageable(pageable => pageable
.Refresh(true)
.PageSizes(true)
.ButtonCount(5))
.DataSource(dataSource => dataSource
.Ajax()
.Read(read => read.Action("Get", "Clients"))
.Model(model => model.Id(p => p.Id))
.Create(update => update.Action("Create", "Clients"))
.Update(update => update.Action("Update", "Clients"))
.Destroy(update => update.Action("Destroy", "Clients"))
)
)
Template
#model Client
#(Html.Kendo().ComboBoxFor(m => m.Plan)
.DataTextField("Name")
.DataValueField("Id")
.Placeholder("Select Plan...")
.HtmlAttributes(new { style = "width:300px" })
.Filter(FilterType.Contains)
.MinLength(3)
.DataSource(source =>
source.Read(read =>
read.Action("GetPlans", "Plans",new {ClientId = Model.Id}))))
Everything works fine except i need to use the Id of the row/model inside the template, in particular , i need the to pass the model.Id (which is the id of the model of the row), to the action on the Combobox in the template, so i can filter the data correctly
This is the offending line in the grid,
.TemplateName("Client").AdditionalViewData(new { Client = Model })
The result is the Model inside the template is always null, im not sure how to pass the data i need to the template
Is there anyway i can do this, or should i be looking at a different approach?
The way I got around this was to put a JavaScript function in the original view as seen below:
function getClientId() {
var row = $(event.srcElement).closest("tr");
var grid = $(event.srcElement).closest("[data-role=grid]").data("kendoGrid");
var dataItem = grid.dataItem(row);
if (dataItem)
return { clientId: dataItem.Id }
else
return { clientId: null }
}
And reference it from my editor template:
.DataSource(source => source.Read(read => read.Action("GetPlans", "Plans").Data("getClientId"))))
Note : I'm pretty sure you cant run JavaScript from a EditorTemplate so it needed to be housed in the original view.
I know this is a really old question, but for those who are wondering why this doesn't work:
.TemplateName("Client").AdditionalViewData(new { Client = Model })
This code doesn't work because the only data you can pass through this method is static data. You can pass specific strings or numbers, like "Hello World", and that would work fine. For dynamic data with kendo, I've learned that it really depends on the situation, and your solution here works well.
Ive seen lots of traffic regarding this issue so I thought I would add my own spin. Everything works as expected on my dev machine. But when I deploy to Azure, the read action on the grid is no longer posted. instead its posting to the url of the page.
Here is my grid
#(Html.Kendo().Grid<HondaPERebates.Model.Models.ClaimModel>()
.Name("grid")
.Groupable()
.Columns(columns =>
{
columns.Bound(p => p.RebateProgramId).Hidden();
columns.Bound(p => p.Status).ClientTemplate("<span class='#=GetClass(Status)#'>#=Status#</span>").Width(100);
columns.Bound(p => p.SellingDealerNo).Width(100);
columns.Bound(p => p.SerialNumberSuffix).ClientTemplate("<span>#=SerialNumberPrefix#-#=SerialNumberSuffix#</span>").Width(150).Title("Serial Number").Filterable(false);
columns.Bound(p => p.SubmittedDate).Format("{0:MM/dd/yyyy}").Width(75);
})
.Pageable()
.Sortable()
.Resizable(resize => resize.Columns(true))
.Selectable()
.Filterable()
.Scrollable(scrollable => scrollable.Virtual(true).Height(630))
.DataSource(dataSource => dataSource
.Ajax()
.Model(model =>
{
model.Id(p => p.RebateProgramId);
})
.PageSize(65)
.Read(read => read.Action("_GetClaims", "Rebates").Data("grid_Parameters"))
)
.Events(events => events.DataBound("onDataBound")
)
)
and the controller
public ActionResult _GetClaims(int rebateProgramId, [DataSourceRequest] DataSourceRequest request)
{
var email = this.HttpContext.User.Identity.Name;
var list = _manager.GetClaimsByEmail(rebateProgramId, email);
return Json(list.ToDataSourceResult(request), JsonRequestBehavior.AllowGet);
}
and the js that gets invoked to get extra parms
function grid_Parameters() {
var RebateProgramId = $('#RebateProgramId').val();
return { RebateProgramId: RebateProgramId };
}
I my case the Action method was not getting called (example : HierarchyBinding_Employees).
I changed the Name to GetHierarchyDataForEmployees and it worked for me :).