Pass the telerik grid column values to controller action result - model-view-controller

I have to pass the Id and Date value to action result(Update) in a Index controller. But I am not able to pass the parameters by using below code:
#(Html.Telerik().Grid(Model)
.Name("NotesDetails")
.DataBinding(dataBinding => dataBinding.Ajax().Select("ListAjax", "NotesDetails"))
.Columns(columns =>
{
columns.Bound(o => o.Flag).Visible(false).Title("Flag");
columns.Bound(o => o.Id).Visible(false).Title("Id");
columns.Command(commands =>
{
commands.Custom("Flag value")
.Text("<img id='flag' width='20' height='10' src = '/Content/images/Flag.png' >")
.Ajax(true)
.Action("Update", "Index", new { id=#-Id#, date = #-Date# });
}).Title("Flag");
columns.Bound(o => o.Date).Visible(true).Title("Date");
columns.Bound(o => o.Author).Visible(true);
columns.Bound(o => o.Task).Visible(true);
})
.Pageable(pager =>
{
pager.Style(GridPagerStyles.PageSizeDropDown | GridPagerStyles.NextPrevious);
pager.Position(GridPagerPosition.Both);
pager.PageSize(50, new int[] { 50, 100, 500 });
})
If I give the values like .Action("Update", "Index", new { id=123, date = "2000/2/2"}); I am getting result
Thanks in advance

We handle this in a Jquery way
command.Custom("Update").Click("jQueryFilename.functionName").Text("Refresh User")
and in jQuery:
jQueryFilename.functionName = function(e) {
e.preventDefault();
var dataItem = this.dataItem($(e.currentTarget).closest("tr"));
var json = JSON.stringify(dataItem);
$.ajax({
url: Controllername/Index,
type: 'POST',
contentType: "application/json",
data: json
}).done(function () {
var grid = $("#Grid").data("kendoGrid");
grid.dataSource.read();
grid.refresh();
}
);
}
You'll need to get set the jQuery selector to get your id and and date but that's pretty straight forward.
Happy coding!

Related

Kendo Grid: How to append to URL

I want to make my update url for my Kendo grid dynamic. I want to be able to go from "http://dummy.restapiexample.com/api/v1/update" to "http://dummy.restapiexample.com/api/v1/update/100"
I've followed the Kendo tutorial for custom data sources. I modified the "parameterMap" function and can change the value of the update url but it does not seem to bind.
#(Html.Kendo().Grid<KendoDemo.Models.EmployeeViewModel>()
.Name("NCSBEGrid")
.Columns(columns =>
{
columns.Bound(p => p.employee_name).Title("Name");
columns.Bound(p => p.employee_age).Width(140).Title("Age");
columns.Bound(p => p.employee_salary).Width(140).Title("Salary");
columns.Bound(p => p.profile_image).Hidden(true);
columns.Command(command => command.Destroy()).Width(110).Title("Delete");
})
.ToolBar(toolbar =>
{
toolbar.Create();
toolbar.Save();
})
.Editable(editable => editable.Mode(GridEditMode.InCell))
.Pageable()
.Navigatable()
.Sortable()
.Scrollable()
.DataSource(dataSource => dataSource
.Custom()
.Events(events => events.Error("error_handler")
)
.Batch(true)
.PageSize(20)
.Schema(schema => schema
.Model(m => m.Id(p => p.id)))
.Transport(transport =>
{
transport.Read(read =>
read.Url("http://dummy.restapiexample.com/api/v1/employees")
.DataType("json")
);
transport.Create(create =>
create.Url("http://dummy.restapiexample.com/api/v1/create")
.Type(HttpVerbs.Post)
.DataType("json")
);
transport.Update(update =>
update.Url("http://dummy.restapiexample.com/api/v1/update")
.Type(HttpVerbs.Put)
.DataType("json")
);
transport.Destroy(destroy =>
destroy.Url("http://dummy.restapiexample.com/api/v1/update")
.Type(HttpVerbs.Delete)
.DataType("jsonp")
);
transport.ParameterMap("parameterMap");
})
)
)
<script>
function parameterMap(options, operation) {
var grid = $("#NCSBEGrid").data("kendoGrid");
if (operation == "create") {
var params = { "name": options.models[0].employee_name, "salary": options.models[0].employee_salary, "age": options.models[0].employee_age };
return JSON.stringify(params);
}
else if (operation == "update") {
var params = { "name": options.models[0].employee_name, "salary": options.models[0].employee_salary, "age": options.models[0].employee_age };
grid.dataSource.transport.options.update.url = "http://dummy.restapiexample.com/api/v1/update/" + options.models[0].id;
//grid.dataSource.sync;
//grid.dataSource.transport.options.update.data = JSON.stringify(params);
//grid.dataSource.read;
return JSON.stringify(params);
}
}
function error_handler(e) {
if (e.errors) {
var message = "Errors:\n";
$.each(e.errors, function (key, value) {
if ('errors' in value) {
$.each(value.errors, function () {
message += this + "\n";
});
}
});
alert(message);
}
}
</script>
In javascript section I expect the update url to include the id at the end. Currently it is updating but when the call to the dummy api is made the id is omitted. It seems easy to do but I cannot figure it out.
Any help would be appreciated.
I used a handler to add the employee id to the url. Thank you Joe for the help.
MVC:
transport.Update(new { url = new Kendo.Mvc.ClientHandlerDescriptor() { HandlerName = "update" } });
Javascript:
function update(options) {
let params = {
"name": options.employee_name,
"salary": options.employee_salary,
"age": options.employee_age
};
let json = JSON.stringify(params);
$.ajax({
method: "PUT",
url: "http://dummy.restapiexample.com/api/v1/update/" + options.id.toString(),
dataType: "json",
data: json
});
}

Get PK of Selected Row Kendo Grid From Toolbar Button

I have a Selectable Kendo Grid with a Custom Toolbar Button.
How can I get the selected row PK when button is Clicked?
I tried many tips but no one was working because I have a Server DataSource.
<%: Html.Kendo().Grid<Web.Models.Model>()
.Name("Grid")
.BindTo((IEnumerable<Web.Models.Model>)ViewBag.List)
.Columns(columns =>
{
columns.Bound(p => p.PK).Title("PK");
columns.Bound(p => p.STATUS).Title("Status");
columns.Bound(p => p.NOTES).Title("Notes");
})
.ToolBar(toolbar =>
{
toolbar.Custom();
toolbar.Template("<a class='k-button k-button-icontext' onClick='EditItem();' ></span>Edit Item</a>");
})
.DataSource(dataSource => dataSource
.Server()
.Model(Model => Model.Id(p => p.PK))
)
.Selectable(selectable => selectable
.Mode(GridSelectionMode.Multiple))
%>
function EditItem(e) {
???
};
Please try with the below code snippet.
<script>
function EditItem() {
var grid = $("#Grid").data("kendoGrid");
var rows = grid.select();
rows.each(function (index, row) {
var selectedItem = grid.dataItem(row);
alert(selectedItem.PK);
});
}
</script>
Let me know if any concern.
hi you can use plain jquery for that as an another option
var rowID = $("#Grid .k-state-selected").find("td:eq(0)")[0].innerText
alert(rowID)
This one works!
function EditItem(e) {
var selectedRows = $("#Grid").find(".k-state-selected");
for (var i = 0; i < selectedRows.length; i++) {
var selectedRow = selectedRows[i];
var PK = selectedRows[i].cells[0].innerText;
}
};

How can I refresh the grid after I edit the Kendo UI grid?

I edit the grid using editable: "popup" as shown on Telerik's demo page. After I edit the grid, I want the grid to refresh. Does the grid have any event that is called after I edit the grid?
I tried to use the databound event. In this event I make the datasource read, but it tells me it is an infinite loop to refresh the grid. I tried to use the saveChanges event, but it is not working.
#(Html.Kendo().Grid<Kendo.Mvc.Examples.Models.ProductViewModel>()
.Name("grid")
.Columns(columns =>
{
columns.Bound(p => p.ProductName);
columns.Bound(p => p.UnitPrice).Width(100);
columns.Bound(p => p.UnitsInStock).Width(100);
columns.Bound(p => p.Discontinued).Width(100);
columns.Command(command => { command.Edit(); command.Destroy(); }).Width(160);
})
.ToolBar(toolbar => toolbar.Create())
.Editable(editable => editable.Mode(GridEditMode.PopUp))
.Pageable()
.Sortable()
.Scrollable()
.Events(events => events.Change("saveChanges "))
.HtmlAttributes(new { style = "height:430px;" })
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(20)
.Events(events => events.Error("error_handler"))
.Model(model => model.Id(p => p.ProductID))
.Create(update => update.Action("EditingPopup_Create", "Grid"))
.Read(read => read.Action("EditingPopup_Read", "Grid"))
.Update(update => update.Action("EditingPopup_Update", "Grid"))
.Destroy(update => update.Action("EditingPopup_Destroy", "Grid"))
))
You can subscribe to the Sync event of the grid's data source and call the read method of its data source.
.Events(events => events.Error("error_handler").Sync("sync_handler"))
function sync_handler(e) {
this.read();
}
Add Events into DataSource
.DataSource(dataSource => dataSource.Ajax(
.Events(e => e.RequestEnd("PowerPlantProduction.onRequestEnd"))**
)
Javascript:
onRequestEnd: function (e) {
if (e.type == "update") {
if (!e.response.Errors) {
e.sender.read();
}
}
},
The accepted answer can cause unexpected behaviour if you're using server side validation. The sync event triggers whenever an update is sent to the server regardless of whether the request was successful, so if the request triggers server side validation errors (or any other errors) the grid will still be updated and any changes lost. Still looking at the this but the best solution I've found is to use the data source's onRequestEnd() event and manually check for errors.
For example:
function onRequestEnd(e)
{
var grid = $("#grid").data("kendoGrid");
var data = grid.dataSource;
if (e.type == "create" || e.type == "update") {
if (!e.response.Errors)
data.read();
else console.log("I had some issues");
}
}
This will refresh the Grid
var grid = $("#Name").data("kendoGrid");
grid.dataSource.page(1);
if .page(1) doesn't work try .read, but it should
using AutoSync(true) in ajax mvc kendo grid having pop up edit mode causes the pop up to not show up at all.
So I use this
function onRequestEnd(e) {
if(e.type == "create" || e.type == "destroy" || e.type == "update") {
setTimeout(function myfunction() {
$("#mygrid").data("kendoGrid").dataSource.read();
}, 1000);
}
}
The time out is to make sure you dont over lap the crud operation.
In case someone else needs to know how to do this. You can include the "complete" function in your create as well as update bits.
transport: {
read: {
url: "http://myurl.json"
},
create: {
url: "http://mycreate.json",
type: "POST",
complete: function(e) {
$("#grid").data("kendoGrid").dataSource.read();
}
},
I agree this is very old question, but unfortunately I was also a victim of this error few days back. My scenario was
First time i was able to insert new record in database using popup method
If I add another record in same grid without refresh, grid is sending both the records to server, and unfortunately leads in duplicate value error.
Finally I think I got a solution for my problem, I was not setting primary key value to my record when I insert it into database and returning that object.
Below is my kendo grid code
#(Html.Kendo().Grid<TeamMemberViewModel>()
.Name("Grid")
.Columns(columns =>
{
columns.Bound(p => p.abcd);
columns.Bound(p => p.abcd_id).Hidden();
columns.Bound(p => p.abcd12_id).Hidden();
columns.Command(command =>
{
command.Edit();
command.Destroy();
});
})
.ToolBar(toolbar =>
{
if (ViewBag.IsAddAllowed)
{
toolbar.Create().Text("Add new");
}
// toolbar.Save().SaveText("Save Changes");
})
.Editable(editable => editable.Mode(GridEditMode.PopUp).TemplateName("ABCD")
)
.Pageable()
.Navigatable()
.Sortable()
.Scrollable()
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(20)
.ServerOperation(false)
.Events(events =>
{
events.Error("error_handler");
events.RequestEnd("request_end");
}
)
.Model(model =>
{
model.Id(p => p.primarykey_id);
model.Field(p => p.abcd);
})
.Create("ABCD_Create", "TeamMember", new { id = Model.abcd_id})
.Read("ABCD_Read", "TeamMember", new { id = Model.abcd_id })
.Update("ABCD_Update", "TeamMember", new { id = Model.abcd_id })
.Destroy("TeamMember_Destroy", "TeamMember", new { id = Model.hackathon_id })
)
)
Below is error handling code
function error_handler(e) {
if (e.errors) {
var message = "Errors:\n";
$.each(e.errors, function (key, value) {
if ('errors' in value) {
$.each(value.errors, function () {
message += this + "\n";
});
}
});
$(".errorMessage").text(message);
alert(message);
}
}
function request_end(e) {
switch (e.type) {
case "create":
if (e.Errors == undefined && e.response.Total > 0) {
// alert("Saved Successfully");
$(".errorMessage").text("Saved Successfully");
}
break;
case "update":
if (e.Errors == undefined && e.response.Total > 0) {
// alert("Updated Successfully");
$(".errorMessage").text("Updated Successfully");
}
break;
case "destroy":
if (e.Errors == undefined && e.response.Total > 0) {
// alert("Deleted Successfully");
$(".errorMessage").text("Deleted Successfully");
}
break;
default:
$(".errorMessage").text("");
break;
}
return true;
}
Server Code
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult ABCD_Create([DataSourceRequest] DataSourceRequest request, MyViewModel my, short abcd_id)
{
if (my != null && ModelState.IsValid)
{
MY tm = Mapper.Map<MyViewModel>(my);
tm.abcd_id = abcd_id;
try
{
repo.Create(tm);
my.primarykey_id = tm.primarykey_id; ///This is most important
}
catch (Exception ex)
{
ModelState.AddModelError("Duplicate Value Found", string.Format("error: {0} already exists", my.abcd));
}
}
else
{
ModelState.AddModelError("Error", "Not valid please send data again");
}
return Json(new[] { my }.ToDataSourceResult(request, ModelState));
}
Hope this might help someone
Use this if you want to refresh the grid.
$("#WorkOrderDetails").data("kendoGrid").refresh();
You can call a function on you edit button click and inside that you can refresh the grid:
function EditRow(){
var grid = $("#YourGridName").data("kendoGrid");
grid.dataSource.read();
}
.sync: function (e) {
this.read();
},
I've been trying to figure out how to refresh the grid after creating a new item. Scenario is: Create an item in the client, send request to server, receive response and update client. (Alternatively, I wouldn't mind figuring out why the grid isn't using the item I'm returning it in the server-side create function)
This post mentions the requestEnd event, but it's not exposed in razor. This event seems to fire after a request is finished, that is, after the server processes the event, so new objects created on the client will already be sent to the server for processing; then the client can request the latest information without losing data. Since the grid datasource object was undefined on page load, I ended up using the .Change event to hook the requestEnd event.
#(Html.Kendo().Grid
.Name("user-grid")
...
.Pageable(pageable => pageable
...
.Events( e => e.Remove("grid_remove").Change("hook_request_end"))
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(20)
.Model(m =>
{
m.Id(vm => vm.DocumentId);
m.Field<DateTime>("LastModified").Editable(false);
})
.Read(a => a.Action("KList", "Controller"))
.Create(a => a.Action("KCreate", "Controller"))
.Update(a => a.Action("KUpdate", "Controller"))
)
and then the javascript:
var requestEndHooked = false;
function hook_request_end()
{
if (requestEndHooked == true)
{
return;
}
requestEndHooked = true;
$("#user-grid").data("kendoGrid").dataSource.bind("requestEnd", dataSource_requestEnd);
}
function dataSource_requestEnd(e)
{
try
{
if (e.type == "create")
{
$("#user-grid").data("kendoGrid").dataSource.read();
}
}
catch (e)
{
}
}
If there's a better way, I'd love to know.
To answer your question, there are events other than "create": "read", "update"
I know this is an old question, but there is a perfectly working example (at least for me!) on the Telerik forum: https://www.telerik.com/forums/refresh-grid-after-insert-update
I post this here because that forum question and answer is less than a year old, it might be that that solution wasn't available for the Kendo version at the time of the OP's question.
The solution mentioned there is to attach a dataBound handler function to the grid, which will be executed only once after the save event. In code:
function onGridEdit(e) {
e.sender.one("dataBound", function (e) {
e.sender.dataSource.read();
});
}
function bindDataAndRefresh(e) {
var grid = $("#upcoming-grid").data("kendoGrid");
grid.bind("dataBound", onGridEdit(e));
}
$(document).ready(function () {
var grid = $("#upcoming-grid").data("kendoGrid");
grid.bind("save", bindDataAndRefresh);
});
I used complete property of transport:update section while creating datasource for kendo.
My code
dsource = new kendo.data.DataSource({
transport: {
read: {
url: serverapiUrl + "/emp",
type: 'GET',
dataType: "json",
cache: true,
beforeSend: function (xhr, settings) {
xhr.setRequestHeader('api-key', 'auth key');
}
},
create: {
url: serverapiUrl + "/emp",
type: 'POST',
dataType: 'json',
beforeSend: function (xhr, settings) {
console.log('under create');
xhr.setRequestHeader('api-key', 'authkey');
xhr.setRequestHeader("content-type", "application/json");
console.log('settings', settings);
console.log(xhr);
}
},
update: {
url: serverapiUrl + "/emp",
type: 'PUT',
dataType: 'json',
beforeSend: function (xhr, settings) {
console.log('under update');
xhr.setRequestHeader('api-key', 'authkey');
xhr.setRequestHeader("content-type", "application/json");
console.log('settings', settings);
console.log(xhr);
},
complete: function (eve) {
console.log('update complete');
$("#griddiv").data("kendoGrid").dataSource.read();
}
}
rest follows the normal structure of kendo ui datasource creation documentation.

Kendo Grid Destroy Command Not Refreshing Grid

In below grid i have implemented Destroy method to delete records, but the issue is when an error occurred during deletion on server side, kendo grid still remove the record from grid. when i refresh the page record appears again as expected. how can i prevent kendo grid from removing a record if server side error occurred and show a error message to user?
#(Html.Kendo().Grid((IEnumerable<RealEstateApp.Models.propertyOwenerModel>)Model)
.Name("grid")
.Columns(columns =>
{
columns.Bound(o => o.id).Visible(false);
columns.Bound(o => o.name).Width("150px");
columns.Bound(o => o.email).Width("100px");
columns.Bound(o => o.address).Width("200px");
columns.Bound(o => o.telephone).Width("100px");
columns.Bound(o => o.mobile).Width("100px");
columns.Template(o => Html.ActionLink("Edit", "Edit", new { o.id })).ClientTemplate("<a class='k-button k-button-icontext' href=\"" + Url.Action("Edit", "propertyOwner") + "/#= id#\"><span class='k-icon k-edit'></span>Edit</a>").Width(80).Title("Edit");
if (Roles.IsUserInRole(User.Identity.Name, "admin"))
{
columns.Command(commands =>
{
commands.Destroy(); // The "destroy" command removes data items
}).Title("Delete").Width(90);
}
//columns.Template(o => Html.ActionLink("Delete", "Delete", new { o.id })).ClientTemplate("<a class='blue' href=\"" + Url.Action("Details", "propertyOwner") + "/#= id#\"><i class='icon-zoom-in bigger-130'>Delete</i></a>").Width(65).Title("Details");
})
.ToolBar(toolbar =>
{
toolbar.Template(#<text>
<a class="k-button" href="/propertyOwner/Create"><span class="k-icon k-si-plus"></span></a>
</text>);
})
.Pageable()
.Sortable()
.Scrollable()
.Filterable()
.Groupable()
.HtmlAttributes(new { style = "height:900px;" })
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(20)
.Read(read => read.Action("AjaxGrid", "propertyOwner"))
.Destroy(destroy => destroy.Action("Destroy", "propertyOwner"))
.Model(model =>
{
model.Id(m=>m.id); // Specify the property which is the unique identifier of the model
model.Field(m => m.id).Editable(false); // Make the ProductID property not editable
})
)
)
You should define an errors function or field in you Schema definition, this is the field where your server sends the notification to the UI.
Then, in the DataSource define an error event handler that displays the alert message (or whatever you want to do).
Example of a DataSource definition using errors field definition and error event handler:
var dataSource = new kendo.data.DataSource({
transport: {
read: {
url: "http://demos.kendoui.com/service/twitter/search",
dataType: "jsonp",
data: { q: "#" }
}
},
schema: {
errors: "error" // twitter's response is { "error": "Invalid query" }
},
error: function(e) {
console.log(e.errors); // displays "Invalid query"
}
});
EDIT: If you need to do some complex validation and not just saying which field contains the error, you might define an errors function in you schema that returns true for error and false for ok!.
Example:
var dataSource = new kendo.data.DataSource({
transport: {
read: {
url: "http://demos.kendoui.com/service/twitter/search",
dataType: "jsonp",
data: { q: "#" }
}
},
schema: {
errors: function (d) {
// twitter's response is { "error": "Invalid query" }
return (d.error && d.error !== "ok") ? true : false;
}
},
error: function(e) {
...
}
});

Internal Server Error on kendo grid update with ajax

i m trying to update grid with ajax but i couldn't success in passing and getting values between controler and view with ajax
When i run program its output is like that
[object Object]++error++Internal Server Error
So i need help
HomeController Function
[HttpGet]
public ActionResult RssCek(string value)
{
XDocument rssXml = new XDocument();
switch (value)
{
case "Ekonomi":
{
rssXml = XDocument.Load("http://sozcu.com.tr/rss.php");
break;
}
case "Siyaset":
{
rssXml = XDocument.Load("http://www.milliyet.com.tr/D/rss/rss/Rss_4.xml");
break;
}
case "Yaşam":
{
rssXml = XDocument.Load("http://www.milliyet.com.tr/D/rss/rss/Rss_5.xml");
break;
}
default:
{
rssXml = XDocument.Load("http://sozcu.com.tr/rss.php");
}
break;
}
var feedler = from feed in rssXml.Descendants("item")
select new Rss
{
Baslik = feed.Element("title").Value,
Link = "Oku",
Aciklama = feed.Element("description").Value
};
var valueToReturn = new JsonResult { Data = feedler };
return valueToReturn;
}
IndexView Grid Code
#Html.Kendo().Grid(Model)
.Name("Grid").Pageable()
.Columns(columns =>
{
columns.Bound(p => p.Baslik).Groupable(false);
columns.Bound(p => p.Aciklama).Encoded(false);
columns.Bound(p => p.Link).Encoded(false);
})
.DataSource(dataSource => dataSource
.Ajax()
.Read(read => read.Action("RssCek", "Home"))
)
IndexView JavaScript Code
<script>
function select(e) {
var value = $(e.item).find("> .k-link").text();
$.ajax({
url: '#Url.Action("RssCek", "Home")',
type: 'GET',
contentType: 'application/json; charset=utf-8',
data: { value: value},
success: function (feedler)
{
document.write(feedler);
},
error: function (request, status, error)
{document.write(request+"++"+ status+"++"+ error);}
});
}
</script>
I found problem is caused by missing JsonRequestBehavior.AllowGet
return Json(feedler, JsonRequestBehavior.AllowGet);
instead of ;
var valueToReturn = new JsonResult { Data = feedler };
return valueToReturn;

Resources