I'm using Kendo UI grid with ASP.Net MVC Wrappers. My grid datasource is defined as follows:
.DataSource(dataSource => dataSource
.Ajax()
.Model(model =>
{
model.Id(p => p.Code);
})
.Read(read => read.Url("api/ProjectMilestone").Type(HttpVerbs.Get))
.Create(create => create.Url("api/ProjectMilestone").Type(HttpVerbs.Post))
.Update(update => update.Url("api/ProjectMilestone").Type(HttpVerbs.Put))
.Destroy(destroy => destroy.Url("api/ProjectMilestone").Type(HttpVerbs.Delete))
)
So one would expect that the GET url would be generated as [server]/[app]/api/ProjectMilestone.
But in my case, the page on which the grid is hosted is at the following URL: [server]/[app]/Project.
This results in the GET url being generated as [server]/[app]/Project/api/ProjectMilestone, and of course the server returns error 404 not found.
Please tell me how I can have the GET url generated as [server]/[app]/api/ProjectMilestone instead.
Turns out the correct approach is to define the datasource as follows:
.Read(read => read.Url(Url.RouteUrl("DefaultApi", new { httproute ="", controller="ProjectMilestone" })).Type(HttpVerbs.Get))
.Create(create => create.Url(Url.RouteUrl("DefaultApi", new { httproute ="", controller="ProjectMilestone" })).Type(HttpVerbs.Post))
.Update(update => update.Url(Url.RouteUrl("DefaultApi", new { httproute ="", controller="ProjectMilestone" })).Type(HttpVerbs.Put))
.Destroy(destroy => destroy.Url(Url.RouteUrl("DefaultApi", new { httproute ="", controller="ProjectMilestone" })).Type(HttpVerbs.Delete))
as taken from this answer.
Have you tried the overload that takes a Controller name and action using "api" for the controller and "ProjectMilestone" for the action?
Related
I have a kendo data grid grouped default by a column and I want to edit the grid inline. I don't want the user to group by any other column. While the default grouping works fine, the update event is not fired and the control doesn't go the controller's inline update method. Can you please check where I'm going wrong. Below is the code:
#(Html.Kendo().Grid(Model)
.Name("grdTimesheets")
.Columns(columns =>
{
columns.Bound(p => p.EmployeeId).Hidden(true);
columns.Bound(p => p.FirstName);
columns.Bound(p => p.Monday.Hour).Title("Monday")
.EditorTemplateName("TimesheetMonday");
columns.Command(command =>
{
command.Edit();
command.Destroy();
command.Custom("Add").Text(" ").Click("AddNewTimesheet");
});
})
.Editable(editable => editable.Mode(GridEditMode.InLine))
.Pageable()
.Sortable()
.Groupable(false)
.Scrollable()
.DataSource(dataSource => dataSource
.Ajax()
.Model(model =>
{
model.Id(p => p.EmployeeId);
model.Field(p => p.FirstName).Editable(false);
})
.PageSize(20)
.Update(update => update.Action("EditingInline_Update", "Timesheet"))
.Destroy(destroy => destroy.Action("EditingInline_Destroy", "Timesheet"))
.Group(d=>d.Add(f=>f.FirstName))
)
If I comment out the last line ".Group(d=>d.Add(f=>f.FirstName))", everything works fine but the default grouping goes off.
I know that its a bit late for an answer but I will just leave this here in case that anybody else is having the same problem. Once you group by any column the grid will not fire ".Update(update => update.Action("EditingInline_Update", "Timesheet"))". In order to fix this you would need to add OnEditEvent for the grid and in the javascript function to attach an event to the textbox/dropdown or whatever control you have there. Sample below:
.Events(events => events.Edit("grid_edit")) this is in the view
javascript:
function grid_edit(e) {
var grid = $('#grid').data('kendoGrid');
var cell = e.container;
var area = cell.find("textarea")
area.on("blur", function() {
// update ur entries here
var areaVal = cell.find("textarea").val(); // this is the new value
// call some ajax to update the value and in the success call grid.dataSource.sync(); to refresh the grid
});}
Also you would need to remove your .Update() for the DataSource because its no longer needed.
My grid is build like this:
#(Html.Kendo().Grid<MyProject.Models.DataObjects.MyObject>()
.Name("my-object-grid")
.Columns(columns =>
{
columns.Bound(p => p.ID).Hidden();
columns.Bound(p => p.Name).Width(300);
columns.Command(command =>
{
command.Edit().Text("Modify")
.UpdateText("Save")
.CancelText("Cancel")
.HtmlAttributes(new { style = "width:90px;height:30px;font-size:12px;" });
command.Destroy().Text("Delete").HtmlAttributes(new { style = "width:90px;height:30px;font-size:12px;" });
}).Width(220);
})
.ToolBar(toolbar => toolbar.Create().Text("Add").HtmlAttributes(new { style = "width:120px;height:30px;float:left;" }))
.Editable(editable => editable.Mode(GridEditMode.PopUp)
.Window(win => win.Title("MyObject")).TemplateName("MyObject"))
.Pageable()
.Sortable()
.Scrollable()
.Filterable()
.HtmlAttributes(new { style = "height:430px;" })
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(10)
.Model(model =>
{
model.Id(p => p.ID);
})
.Create(update => update.Action("MyObject_Create", "MyObject"))
.Read(read => read.Action("MyObject_Read", "MyObject"))
.Update(update => update.Action("MyObject_Update", "MyObject"))
.Destroy(update => update.Action("MyObject_Delete", "MyObject"))
.Events(evt => evt.Push("myObjectGridDataSource_push").Error("myObjectGridDataSource_error"))
)
)
And the foolwingo javacript handlers are defined after:
<script type="text/javascript">
function myObjectGridDataSource_push(e) {
alert(e.type);
}
function myObjectGridDataSource_error(e) {
alert(e.status);
}
</script>
The javascript generated by the helper seems to be ok, but the event handlers are never fired when I add/edit/remove some item of the grid. But the requests to the controller are working fine.
Could be this related to the edit mode of the grid (using popup)?
I can't find what I am doing wrong...
Push is invoked during dataSource transport initialization which sets up push notifications. The data source will call this function only once and provide callbacks which will handle push notifications (data pushed from the server).
Push event Detailed information
If you can tell what exactly you are trying to achieve then I can be of a bit more help. Also if you want to catch the event before the record id being udpated or inserted or deleted then push won't do it. You will need to implement the sync event of the grid.
I have some difficulties to make a grid with an editor pop , which has inside a collection.
I found an example that 's almost like I want, but the grid
nested , has a GridEditMode.InCell , and I need to GridEditMode.PopUp .
When I try to change CellEditing PopEditing get the following error:
"The Insert data binding setting is required by the insert command . Please specify the Insert action or url in the DataBinding configuration. "
I want the whole object is recorded when the parent object is recorded.
#(Html.Kendo().Grid<EmployeeViewModel>()
.Name("grid")
.Columns(columns =>
{
columns.Command(comm =>
{
comm.Edit();
});
columns.Bound(e => e.EmployeeID);
columns.Bound(e => e.FirstName);
columns.Bound(e => e.LastName);
columns.Bound(e => e.Title);
columns.Bound(e => e.HireDate).Format("{0:d}");
columns.Bound(e => e.Territories)
.ClientTemplate("#=territoriesTemplate(Territories)#");
})
.Editable(ed=>ed.Mode(GridEditMode.PopUp))
.Pageable()
.Events(ev=>ev.Edit("onEdit"))
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(5)
.Model(model =>
{
model.Id(e => e.EmployeeID);
model.Field(e => e.EmployeeID).Editable(false);
model.Field(e => e.Territories).DefaultValue(new List<TerritoryViewModel>());
})
.Events(ev=>ev.Change("onDsChange"))
.Read(read => read.Action("Read", "Home"))
.Update(update => update.Action("Update", "Home").Data("serialize")))
)
This is the nested grid that need to be edited with GridEditMode.PopUp
#(Html.Kendo().Grid<TerritoryViewModel>()
.Name("TerritoryGrid")
.Sortable()
.Columns(cols =>
{
cols.Bound(b => b.TerritoryID);
cols.Bound(b => b.TerritoryDescription);
})
.Editable(ed=>ed.Mode(GridEditMode.InCell))
.AutoBind(false)
.DataSource(ds => ds.Ajax().Model(mo => {
mo.Id(m => m.TerritoryID);
mo.Field(f => f.TerritoryID).Editable(false);
}))
.ToClientTemplate()
)
Is there any way?
I assume you found the following demo and you want to change it to use popup editing for the nested Grid. It is possible to make the Grid use Popup editing, however the nested Grid will perform separate request.
If you want to achieve both Popup editing + batch updates you will have to declare your Grid via JavaScript since it provides you with way more flexibility.
Or you can use the approach covered in this code library to achieve similar to popup editing + batch updates.
I am having an issue where the READ operation for the Kendo Grid does not get invoked and hence the grid does not populate any data. I have followed these links
http://docs.kendoui.com/getting-started/using-kendo-with/aspnet-mvc/helpers/grid/troubleshooting#the-ajax-bound-grid-does-not-populate
Kendo UI Grid is not calling READ method
However the issue still exists.
/// CS File
public ActionResult GetItemsHome([DataSourceRequest] DataSourceRequest request , int page)
{
List<CustomItem> lst = new List<CustomItem>();
return Json(lst.ToDataSourceResult(request), JsonRequestBehavior.AllowGet);
}
///cs html file
#(Html.Kendo().Grid<CustomItem>()
.Name("grid")
.Columns(columns =>
{
columns.Bound(o => o.No).Width("15%");
columns.Bound(o => o.ShortDesc).Width("15%");
columns.Bound(o => o.Category).Width("6%");
})
.Sortable()
.Pageable(p=>p.Refresh(true))
.Filterable()
.Scrollable()
.Editable(edit => edit.DisplayDeleteConfirmation("Are You Sure To Delete This ").Mode(GridEditMode.PopUp))
.ColumnMenu(col=>col.Sortable(false))
.Groupable()
.ToolBar(toolbar => toolbar.Create())
.Resizable(resize => resize.Columns(true))
.Reorderable(reorder => reorder.Columns(true))
//.ClientDetailTemplateId("template")
.HtmlAttributes(new { style = "height:430px;" })
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(6)
.Read(read => read.Action("GetItemsHome", "det"))
.Model(model => {
model.Id(p => p.ID);
})
.Create(update => update.Action("EditingInline_Create", "det"))
// .Read(read => read.Action("EditingInline_Read", "Default1"))
.Update(update => update.Action("EditingInline_Update", "det"))
.Destroy(update => update.Action("EditingInline_Destroy", "det"))
)
)
the order in which the JS is loaded
Any ideas ?
Thanks
Your action GetItemsHome([DataSourceRequest] DataSourceRequest request , int page) requires page (non-null value) to be passed. You have 3 options:
Delete this argument (this makes sense since request contains everything you want)
Supply it like: .Read(read => read.Action("GetItemsHome", "det", new { page = 10}))
Make it nullable like: int? page
EDIT: After following any of above, return some data from controller action (I am creating some arbitrary data, you may return it from DB instead) to fill up your grid. Something like:
public ActionResult GetItemsHome([DataSourceRequest] DataSourceRequest request , int? page)
{
//List<CustomItem> lst = new List<CustomItem>();
// Dummy data
var data = new [] { new CustomItem(){ No = 1, ShortDesc = "xyz", Category = "abc"},
new CustomItem(){ No = 2, ShortDesc = "xyz", Category = "abc"} };
return Json(data.ToDataSourceResult(request), JsonRequestBehavior.AllowGet);
}
If your controller and action names are spelled correctly in view, above code should work.
Some possibilities, if your function is not being called:
If your ActionResult Index() function is doing some other operations instead of simply return View() and exiting, it's possible your GetItemsHome() function may not be called - I had this issue once.
Try just naming the function "Read" instead of "GetItemsHome".
Does your controller have any other functions (i.e. Update, Destroy)? I would comment them out, in case there are syntax issues in them that are causing the issue.
"det", I hope, is the name of your controller.
Why pass in the extra page parameter at all? Try it without it, and use a public variable in your model to hold that value.
The components I'm using Kendo UI, but I have problem in Grid
If you use the code below the column "Command" does not show on the page, but the page Change Sort or by grid, there is a page refresh.
#(Html.Kendo().Grid(Model)
.Name("Grid")
.Columns(columns =>
{
columns.Bound(p => p.cd_empresa).Visible(false);
columns.Bound(p => p.cd_grupo).Visible(false);
columns.Bound(p => p.descricao);
columns.Template
(
#<text>
Text 1
Text 2
</text>
).Title("Command").Width(80);
})
.ColumnMenu()
.Selectable(selectable => selectable.Mode(GridSelectionMode.Single))
.Pageable()
.Sortable()
.Scrollable(scr => scr.Height(240))
.Filterable()
.DataSource(dataSource => dataSource
.Ajax()
.ServerOperation(false)
.PageSize(7)
.Read(read => read.Action("Index", "GrupoFiscal"))
.Model(model => model.Id(p => p.cd_grupo))
.Model(model => model.Id(p => p.cd_empresa))
)
)
If I put
. DataSource (dataSource => dataSource
. Ajax ()
. ServerOperation (false)
. PageSize (7)
. Read (read => read.Action ("Index", "GrupoFiscal"))
. Model (model => model.Id (p => p.cd_grupo))
. Model (model => model.Id (p => p.cd_empresa))
)
Ajax works without refresh the page, but the column "Command" no shows.
Note This column has links to Edit, Delete and Details
Refer to the documentation:
A column template is not displayed
This will happen if the server template is set but the grid is
configured for ajax binding. Set the ClientTemplate as well. This will
also happen if only the client template is set but the grid is
configured for server binding. Set the Template as well.