Why Kendo Ui Grid is not fire Update Action in MVC 4? - asp.net-mvc

I create Kendo UI Grid that can Create, Update and Delete Data. But it is not fire Update Action in my Controller.
Here is My Code :
<script src="~/Scripts/Kendo/jquery.min.js"></script>
<script src="~/Scripts/Kendo/kendo.all.min.js"></script>
<script src="~/Scripts/Kendo/kendo.aspnetmvc.min.js"></script>
#(Html.Kendo().Grid<SkuMetadata>()
.Name("Grid")
.Columns(colums =>
{
colums.Bound(p => p.CompanyName).Width(100);
colums.Bound(p => p.BrandName).Width(100);
colums.Bound(p => p.ProductName).Width(100);
colums.Bound(p => p.SkuName).Groupable(false).Width(100);
colums.Command(command => {
command.Edit();
command.Destroy(); }).Width(160);
})
.ToolBar(toolbar => toolbar.Create())
.Editable(editable => editable.Mode(GridEditMode.PopUp))
.Groupable()
.Pageable()
.Sortable()
.Scrollable()
.Filterable()
.HtmlAttributes(new { style = "height: 500px;" })
.DataSource(dataSource =>
dataSource
.Ajax()
.Batch(true)
.ServerOperation(false)
.PageSize(100)
.Events(events => events.Error("error_handler"))
.Model(model => model.Id(p => p.SkuId))
.Create(update => update.Action("CreateProducts", "Product"))
.Update(update => update.Action("UpdateProducts", "Product").Type(HttpVerbs.Post))
.Destroy(destroy => destroy.Action("DeleteProducts", "Product"))
.Read(read => read.Action("GetAllProducts", "Product"))))
My Action Is :
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult UpdateProducts([DataSourceRequest] DataSourceRequest request, SkuMetadata skuMetadata)
{
return Json(_basicUnit.Skus.GetAllSku().ToDataSourceResult(request));
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult DeleteProducts([DataSourceRequest] DataSourceRequest request, SkuMetadata skuMetadata)
{
return Json(_basicUnit.Skus.GetAllSku().ToDataSourceResult(request));
}
Create and Delete Works fine. I dont understand Why Update is not working. Am i miss any reference or what i doing wrong?

Use this
.DataSource(dataSource =>
dataSource
.Ajax()
.Batch(true)
.ServerOperation(false)
.PageSize(100)
.Events(events => events.Error("error_handler"))
---->**.Model(model => { model.Id(p => p.ID); model.Field(p => p.ID).DefaultValue(16000000); })** <--------
.Create(update => update.Action("CreateProducts", "Product"))
.Update(update => update.Action("UpdateProducts", "Product").Type(HttpVerbs.Post))
.Destroy(destroy => destroy.Action("DeleteProducts", "Product"))
.Read(read => read.Action("GetAllProducts", "Product"))))

I would first take the grid out of batch edit mode to see if you can get the update action to fire after you update the record in the popup.

Try mark action with [GridAction] attribute.
And may be you must write actions something like:
[AcceptVerbs(HttpVerbs.Post)]
[GridAction]
public ViewResult(...)
{
//do what you need..and if .ToDataSourceResult(..) return IEnumerable try write
var model = _basicUnit.Skus.GetAllSku().ToDataSourceResult(request);
return View(new GridModel(model));
}

you have to change ServerOperation(false) to ServerOperation(true)

In your render action you must send ID value in model.
[PopulateViewData("PopulateViewData")]
public virtual ActionResult Novo()
{
domain = ...;
var model = new Model
{
Id = model.Id,
Propertyx = model.PropertyX,
...
};
return View(model);
}

Related

Kendo.Grid Delete Acton does not invoke the Controller's method even though I'm doing the same as in telerik example

I have the following Kendo().Grid():
#(Html.Kendo().Grid<TicketReportPropertyEntity>()
.Name("TicketReportPropertyGrid")
.Columns(columns =>
{
columns.Bound(c => c.ID).Hidden();
columns.Bound(c => c.PropertyName).Title("Property Name").EditorTemplateName("_PropertyNameEditor").Width(900);
columns.Bound(c => c.Amount).Title("Amount").Format("{0:C}").Width(90);
columns.Command(command => command.Destroy()).Width(150);
})
.Events(events => events.DataBound("Databound").SaveChanges("SaveGrid").Edit("Edit"))
.ToolBar(toolbar =>
{
toolbar.Create();
toolbar.Save();
})
.Editable(editable => editable.Mode(GridEditMode.InCell))
.Navigatable()
.DataSource(dataSource => dataSource
.Ajax()
.Batch(true)
.ServerOperation(false)
//.Events(events => events.Error("error_handler"))
.Model(model =>
{
model.Id(c => c.ID);
model.Field(c => c.PropertyName);
model.Field(c => c.Amount);
})
.Create(create => create.Action("AddTicketReportProperty", "TicketReportProperty").Data("GetData"))
.Read(read => read.Action("GetData", "TicketReportProperty", Model))
.Update(update => update.Action("UpdateTicketReportProperty", "TicketReportProperty"))
.Destroy(delete => delete.Action("DeleteTicketReportProperty", "TicketReportProperty"))
)
)
And my controller's method:
[HttpPost]
public ActionResult DeleteTicketReportProperty([DataSourceRequest] DataSourceRequest request, TicketReportPropertyModel model)
{
var result = new TicketReportPropertyModel().DeleteTicketReportProperty(model.ID);
return Json(new[] { model }.ToDataSourceResult(request, ModelState));
}
Here is a "SaveGrid" function:
function SaveGrid(e) {
console.log("save")
var rowsCount = e.sender.dataSource.data().length;
var totalSum = 0;
if (rowsCount > 0) {
for (var i = 0; i < rowsCount; i++) {
totalSum += e.sender.dataSource.data()[i].Amount;
}
}
var ticketAmount = $('#Ticket_Amount').val();
console.log(ticketAmount);
if (totalSum != ticketAmount) {
console.log("failed");
//show the popup
e.preventDefault();
}
}
It should add, update and delete records. Now, I'm working on deleting the record. But the event does not call the controller.
I'm following telerik example here
What am I missing?
I believe you are not following exactly the example from telerik. When you create the Grid you're using an Entity TicketReportPropertyEntity, but in the Controller you are receiving a Model TicketReportPropertyModel.
Make sure you create your Grid using the Model, not the Entity, as the example you're following.
#(Html.Kendo().Grid<TicketReportPropertyModel>()

Kendo Grid edit command not reaching controller

Can someone please help with my question:
The edit command in kendo grid isn't reaching my controller.
Am I missing something?
#(Html.Kendo().Grid<WEEKLY_ORDERS_LINES>()
.Name("orderDetails_edit" + Model.OrderID)
.Columns(columns =>
{
columns.Bound(e => e.ID).Hidden(true);
columns.Bound(e => e.INGRED_NAME).Title("Ingredient Name").Width(120).HeaderHtmlAttributes(new { style = "text-align: center;" }).HtmlAttributes(new { style = "text-align: center;" });
columns.Command(command => { command.Edit(); }).Width(60);
})
.Editable(e => e.Mode(GridEditMode.InLine))
.DataSource(dataSource => dataSource
.Ajax()
.Sort(sort => sort.Add("INGRED_NAME").Ascending())
.Model(model =>
{
model.Id(p => p.ID);
model.Field(p => p.ID).DefaultValue(new Guid());
model.Field(f => f.INGRED_NAME).Editable(true);
})
.Update(update => update.Action("Update", "Food"))
.Read(read => read.Action("Read", "Food").Data("additionalInfo"))
)
.Events(events => events.Cancel("refreshView"))
)
And my controller is like this:
public ActionResult Update([DataSourceRequest] DataSourceRequest request, WEEKLY_ORDERS_LINES model)
{
if (model != null && ModelState.IsValid)
{
WEEKLY_FOOD dbFood = _db.WEEKLY_FOOD.Find(model.ID);
dbFood.INGRED_NAME = model.INGRED_NAME;
_db.SaveChanges();
}
ActionResult a = Json(new[] { model }.ToDataSourceResult(request, ModelState));
return a;
}
I'm a colleague of Rute.
The problem that was ocurring was that the kendo Update was calling other controller and not the right one. This was happening because all the results of the data that were being rendered didn't have an unique identifier.
This unique identifier is now assign to the model.Id and the problem is solved. I understood this after seeing this link http://www.telerik.com/forums/wrong-methods-are-fired.
Thanks for the help.

Kendo grid delete button passing the details of the row

I have a kendo grid in which I want to form delete button to pass the details of the row to the controller (as I am using mvc). Then I will use these details to delete the row from the database.
I searched in kendo website and I found the part for the delete or destroy call but I don't know how to pass these details of the row to the controller.
#(Html.Kendo().Grid<Kendo.Mvc.Examples.Models.ProductViewModel>()
.Name("Grid")
.Columns(columns => {
columns.Bound(p => p.ProductName);
columns.Bound(p => p.UnitPrice).Width(140);
columns.Bound(p => p.UnitsInStock).Width(140);
columns.Bound(p => p.Discontinued).Width(100);
columns.Command(command => command.Destroy()).Width(110);
})
.ToolBar(toolbar => {
toolbar.Create();
toolbar.Save();
})
.Editable(editable => editable.Mode(GridEditMode.InCell))
.Pageable()
.Navigatable()
.Sortable()
.Scrollable()
.DataSource(dataSource => dataSource
.Ajax()
.Batch(true)
.PageSize(20)
.ServerOperation(false)
.Events(events => events.Error("error_handler"))
.Model(model => model.Id(p => p.ProductID))
.Create("Editing_Create", "Grid")
.Read("Editing_Read", "Grid")
.Update("Editing_Update", "Grid")
.Destroy("Editing_Destroy", "Grid")
)
)
My grid:
<div id="grid">
#(Html.Kendo().Grid<dynamic>()
.Name("BrowseGrid")
.Columns(columns =>
{
foreach (System.Data.DataColumn c in Model.Grid.Columns)
{
columns.Bound(c.ColumnName).EditorTemplateName("String");
}
columns.Command(command =>
{
command.Destroy();
command.Custom("").Text("editteam").HtmlAttributes(new { id = "editteam", onClick = "editRow()" });
});
})
.Scrollable()
.DataSource(dataSource => dataSource
.Ajax()
.Events(events => events.Error("error_handler"))
.Model(model =>
{
//Define the model
foreach (System.Data.DataColumn column in Model.Grid.Columns)
{
model.Field(column.ColumnName, column.DataType);
model.Id("Id");
}
})
.Read(read =>
read.Action("BrowseGrid", "Configuration")
)
.Destroy( update => update.Action("Delete", "Configuration"))
//Data("{nodeID:"+#Model.nodeID+"}"
)
.Pageable(pageable => pageable
.Refresh(true)
.PageSizes(new int[] { 10, 100, 1000, 10000, 100000, 1000000 })
.ButtonCount(10)
)
)
Please change to:
.Destroy(update => update.Action("Process_Destroy", "controller name"))
and in controller,
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Process_Destroy([DataSourceRequest] DataSourceRequest request, ProductViewModel product)
{
if (product != null)
{
//write your code for delete action;
}
return Json(ModelState.ToDataSourceResult());
}
This will work.
I am assuming you only need the id of the row to delete it, but I think you can send the full model of the selected row. I am sending both.
Like this:
.Destroy(d => d.Action("controllerMethod", "controllerName").Data("jsFunction"))
And in javascript:
function jsFunction() {
var grid = $("#BrowseGrid").data("kendoGrid");
var id = grid.dataItem(grid.select()).Id;
return {
id: id
};
}
Your controller method should receive the parameter:
public ActionResult controllerMethod(string id)

Kendo UI Grid Read Action is not being called when hosted on Azure

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

MVC Model Binding does not work on Kendo Grid

In an MVC project i have the following view where i use the Kendo Grid
<%: Html.Kendo().Grid<Milestone>()
.Name("MilestonesGrid")
.Columns(columns =>
{
columns.Bound(p => p.ContractMilestoneID).Hidden();
columns.Bound(p => p.MilestoneSN).Title("Κωδικός οροσήμου");
columns.Bound(p => p.EstimatedDate).Title("Εκτιμώμενη ημερομηνία");
columns.Bound(p => p.RealDate).Title("Πραγματική ημερομηνία");
columns.Bound(p => p.MilestoneDescription).Title("Περιγραφή");
columns.Bound(p => p.Payment).Title("Πληρωμή");
columns.Bound(p => p.PaymentRate).Title("Ποσοστό πληρωμής");
columns.Bound(p => p.IsCompleted).Title("Έχει ολοκληρωθεί");
columns.Command(command =>
{
command.Edit()
.Text("Επεξεργασία")
.CancelText("Ακύρωση")
.UpdateText("Αποθήκευση");
command.Destroy()
.Text("Διαγραφή");
});
})
.ToolBar(toolbar => toolbar.Create().Text("Προσθήκη νέου οροσήμου"))
.Editable(editable => editable.Mode(GridEditMode.InLine))
.Sortable()
.Pageable()
.Filterable()
.Resizable(resize => resize.Columns(true))
.DataSource(dataSource => dataSource
.Ajax()
.ServerOperation(true)
.Model(model => model.Id(o => o.ContractMilestoneID))
.Model(model => model.Field(o => o.MilestoneSN))
.Model(model => model.Field(o => o.EstimatedDate))
.Model(model => model.Field(o => o.RealDate))
.Model(model => model.Field(o => o.MilestoneDescription))
.Model(model => model.Field(o => o.Payment))
.Model(model => model.Field(o => o.PaymentRate))
.Model(model => model.Field(o => o.IsCompleted))
.Batch(true)
.Create(create => create.Action("CreateMilestone", "Milestones"))
.Read(read => read.Action("DetailsJson", "Milestones",
new { id = ViewBag.ID }))
.Update(update => update.Action("UpdateMilestone", "Milestones"))
.Destroy(delete => delete.Action("DeleteMilestone", "Milestones")))
%>
Also i have a controller where i want to save a new entry in the Kendo Grid.
[HttpPost]
public ActionResult CreateMilestone([DataSourceRequest] DataSourceRequest request,
Milestone milestone)
{
if (milestone != null && ModelState.IsValid)
{
using (TADCEntities database = new TADCEntities())
{
tblSymvaseisOrosima item = new tblSymvaseisOrosima
{
fldEstimatedDate = milestone.EstimatedDate,
fldIsCompleted = milestone.IsCompleted,
fldMilestoneDescription = milestone.MilestoneDescription,
fldMilestoneSN = milestone.MilestoneSN,
fldPayment = milestone.Payment,
fldPaymentRate = milestone.PaymentRate,
fldRealDate = milestone.RealDate,
fldStoixeioYpoergouID = milestone.ElementSubProjectID
};
database.tblSymvaseisOrosima.Add(item);
database.SaveChanges();
return Json(new[] { item }.ToDataSourceResult(request, ModelState));
}
}
return View();
// should also return json
}
The problem is that the Milestone type (the parameter in the controller) is always null even if i enter data when i create a new entry in the grid and press save. Any idea what to do in order to pass the entered data in the milestone parameter? Thank you in advance
As I saw in the Fiddler the parameters is posting with models prefix, thus you must access them like this:
public ActionResult CreateMilestone([DataSourceRequest] DataSourceRequest request,
[Bind(Prefix="models")] List<Milestone> milestons)
{
Milestone milestone = milestons[0];
.
.
.
}

Resources