Been trying to do an update on a Kendo grid and I'm having issues.
I'm using Rails as the back-end and when I do the update, the server seems to be showing that everything worked:
Started PUT "/" for 127.0.0.1 at 2012-02-12 17:28:19 -0600
Processing by HomeController#index as
Parameters: {"models"=>"[{\"created_at\":\"2012-02-08T17:34:50Z\",
\"first_name\":\"Milla\",\"id\":2,\"last_name\":\"sfasfsdf\",\"password\":\"\",
\"updated_at\":\"2012-02-08T17:34:50Z\",\"user_name\"
:\"\"}]"}
Rendered home/index.html.erb within layouts/application (3.0ms)
Completed 200 OK in 89ms (Views: 88.0ms | ActiveRecord: 0.0ms)
However, when I refresh the view, nothing has changed. When I checked the database, of course no changes had taken place there either.
I went through the documentation here about how to do edits in the grid: http://demos.kendoui.com/web/grid/editing.html
And I watched Burke Hollands video about how to set up the grid to work with Rails: http://www.youtube.com/watch?v=FhHMOjN0Bjc&context=C3f358ceADOEgsToPDskKlwC22A9IkOjYnQhYyY9HI
There must be something that I haven't done right, but I'm just not seeing it.
Here's my code that works with the Kendo stuff:
var User = kendo.data.Model.define({
id: "id",
fields: {
first_name: { validation: { required: true } },
last_name: { validation: { required: true } }
}
});
var UsersData = new kendo.data.DataSource({
transport: {
read: {
url: "/users.json"
},
create: {
url: "/users/create.json",
type: "POST"
},
update: {
type: "PUT"
},
destroy: {
type: "DELETE"
},
parameterMap: function(options, operation) {
if (operation !== "read" && options.models) {
return {models: kendo.stringify(options.models)};
}
}
},
batch: true,
pageSize: 5,
schema: {
model: User
}
});
$("#users-grid").kendoGrid({
dataSource: UsersData,
navigatable: true,
editable: true,
selectable: true,
pageable: true,
sortable: true,
toolbar: ["create", "save", "cancel"],
columns: [
{
field: "first_name",
title: "First Name"
},
{
field: "last_name",
title: "Last Name"
},
]
});
Some more research and I've got it working like this...
I added a route to override the 7 RESTful routes that Rails gives you by default. In your Routes.rb files, add this line...
match 'users' => 'users#update', :via => :put
Which basically says we are going to handle all puts by going to the update definition on the controller.
Now in the controller definition, you want to handle the update a bit differently since it's not RESTful. You need to first parse the JSON that you are sending via the parameterMap and then iterate through the objects updating with the object attributes...
def update
respond_to do |format|
#users = JSON.parse(params[:models])
#users.each do |u|
user = User.find(u["id"])
unless user.nil?
user.update_attributes u
end
end
format.json { head :no_content }
end
end
You can also modify your datasource because the url key can take a function:
var UsersData = new kendo.data.DataSource({
transport: {
read: {
url: '/users.json',
dataType: 'json'
},
update: {
url: function (o) {
return '/users/' + o.id + '.json'
},
dataType: 'json',
type: 'PUT'
},
destroy: {
url: function (o) {
return '/users/' + o.id + '.json'
},
dataType: 'json',
type: 'DELETE',
},
create: {
url: '/users.json',
dataType: 'json',
type: 'POST'
},
parameterMap: function(options, operation) {
if (operation !== "read" && options.models) {
return {models: kendo.stringify(options.models)};
}
}
},
batch: true,
pageSize: 5,
schema: {
model: User
}
});
Related
I am trying to use js grid for my application. I am trying to populate the grid after ajax request but it do not seem to work as expected.
I am trying with SQL Server as back end and web application is asp.net MVC
This is my code in the html
var table;
var result;
var $j = jQuery.noConflict();
$j(document).ready(function () {
table = $j('#grid').jsGrid({
height: "60%",
width: "50%",
inserting: true,
editing: true,
sorting: true,
paging: true,
autoload: true,
pageSize: 10,
controller: {
loadData: function (filter) {
var d = $j.Deferred();
$j.ajax({
type: "POST",
contentType: "application/json",
url: "#Url.Action("LoadData", "User")",
datatype: "json",
data: filter
#*success: function (data) {
result = data.data;
console.log("result", result);
d.resolve(result)
},
error: function (data) {
window.location.href = '#Url.Action("Error", "Audit")';
}*#
}).done(function (data) {
console.log("response", data);
console.log("data.data", data.data);
d.resolve(data)
});
return d.promise();
},
fields: [
{ name: "LastName", type: "text"},
{ name: "FirstName", type: "text"},
{ name: "Email", type: "email"},
{ name: "PhoneNumber", type: "number"},
{ type: "control" }
]
}
});
});
In Controller I return
''return Json(new { data }, JsonRequestBehavior.AllowGet);''
I expect the json data to bind in the div. But it did not ? Thanks
Ok, so I've had this problem recently.
First off, change your "height" to px, auto, or get rid of it entirely. It's not doing what you think it's doing.
Next, since you have paging, you need to return your data in the following format:
{
data: [{your list here}],
itemsCount: {int}
}
It's barely in the documentation, as it's inline and not very obvious. (Bolding mine.)
loadData is a function returning an array of data or jQuery promise that will be resolved with an array of data (when pageLoading is true instead of object the structure { data: [items], itemsCount: [total items count] } should be returned). Accepts filter parameter including current filter options and paging parameters when
http://js-grid.com/docs/#controller
I have kendo grid server side pagination and filtering based on start date and end date (2 Filters ), in first time grid drawn based on the 2 filters correctly .
When the 2 filters changed the grid draw correctly then when I go to another page the filters values sent to action server (action update data source) sent as firstly call not send current values .
Data source code is
dataSource: {
type: "aspnetmvc-ajax",
transport: {
read: {
url: "#Html.Raw(Url.Action("GetAllOldExcuse", "Security"))",
data: {
startDate: $('#FromDate').val(), endDate: $('#FromTo').val()
}
}
},
schema: {
model: {
fields: {
ID: { type: "number" },
}
}
, data: "Data",
total: "Total",
errors: "Errors",
AggregateResults: "AggregateResults",
},
pageSize: 10,
serverPaging: true,
serverSorting: true,
serverFiltering: true,
serverGrouping: true,
serverAggregates: true
}
Omar, you should change your data property into a function, so that it get re-evaluated each time the datasource requests data:
transport: {
read: {
url: "#Html.Raw(Url.Action("GetAllOldExcuse", "Security"))",
data: function() {
return {
startDate: $('#FromDate').val(),
endDate: $('#FromTo').val()
}
}
}
}
For some reasons I cannot use MVC-wrapper of Kendo grid. So I am trying to build Kendo grid on JavaScript.
There are 2 main problems when trying to update or create records on grid.
1-)All operations(destroy,update,create) on grid just go to create action by Datasource's of Kendo grid. For example after update a record, datasource send data to this URL to many times(number of columns):
http://localhost:63186/Administrator/DefinitionDetailCreate. It should pass values to:
http://localhost:63186/Administrator/DefinitionDetailUpdate
2-)After operation(update or create) Grid sends all data to Action Method instead of new or updated data. So it sends requests the number of columns on grid
JavaScript:
var dataItem = this.dataItem($(e.target).closest("tr"));
var code = dataItem.CODE;
// alert(code);
var crudServiceBaseUrl = "/Administrator/",
dataSource = new kendo.data.DataSource({
transport: {
read: {
url: '#Url.Action("DefinitionDetailRead", "Administrator")',
data: {DefinitionCode: code},
dataType: "json"
},
update: {
url: '#Url.Action("DefinitionDetailUpdate", "Administrator")',
type: "POST",
dataType: "text"
},
destroy: {
url: '#Url.Action("DefinitionDetailDelete", "Administrator")',
type: "POST",
dataType: "text",
},
create: {
url: '#Url.Action("DefinitionDetailCreate", "Administrator")',
type: "POST",
dataType: "text",
}
},
// batch: true,
pageSize: 9,
schema: {
data: "Data",
model: {
ID: "ID",
fields: {
ID: {editable: false, nullable: true},
DESCRIPTION: {validation: {required: true}}
}
}
}
});
$("#detailsGrid").kendoGrid({
dataSource: dataSource,
attributes: {style: "padding-left: 0px; font-size: 14px"},
pageable: {refresh: false, pageSizes: false, buttonCount: 5},
toolbar: ["create"],
columns: [
{field: "DESCRIPTION", title: "DESCRIPTION", width: "200px"},
{command: ["edit", "destroy"], title: "Operasyon", width: "100px"}],
editable: "popup"
});
Controller:
[HttpPost]
public ActionResult DefinitionDetailUpdate(Guid ID,Guid REFERENCEID,string DESCRIPTION)
{
return null;
}
[HttpPost]
public ActionResult DefinitionDetailCreate(Guid ID, Guid REFERENCEID, string DESCRIPTION)
{
return null;
}
First you might need to add parameterMap, this will help identify server side methods:
parameterMap: function (options, operation) {
var out = null;
switch (operation) {
case "create":
out = '{ "param":' + options.somevalue + '}';
break;
case "read":
out = '{ "id":' + options.somevalue + '}';
break;
case "update":
out = '{ "id":' + options.somevalue + '}';
break;
case "destroy":
out = '{ "id": ' + options.somevalue + '}';
break;
}
return out;
}
I would also suggest to keep all the dataTypes as dataType: "json"
Also you seem to be missing contentType in your transports definitions :
update: {
url: _op.serviceBaseUrl + "Update",
dataType: "json",
type: "POST",
contentType: "application/json; charset=utf-8",
complete: function (jqXhr, textStatus) {
}
},
i have posted answer for the same type of question, you may have a check
or
you may Use this code
js
var dataItem = this.dataItem($(e.target).closest("tr"));
var code = dataItem.CODE;
// alert(code);
var crudServiceBaseUrl = "/Administrator/",
dataSource = new kendo.data.DataSource({
transport: {
read: {
url: '#Url.Action("DefinitionDetailRead", "Administrator")',
type: "POST",
dataType: "json"
},
update: {
url: '#Url.Action("DefinitionDetailUpdate", "Administrator")' ,
type: "POST",
dataType: "json"
},
destroy: {
url: '#Url.Action("DefinitionDetailDelete", "Administrator")',
type: "POST",
dataType: "json",
},
create: {
url: '#Url.Action("DefinitionDetailCreate", "Administrator")',
type: "POST",
dataType: "json",
},
parameterMap: function (options, operation) {
if (operation !== "read" && options.models) {
return { models: kendo.stringify(options.models) };
}
} },
// batch: true,
pageSize: 9,
schema: {
data: "Data",
model: {
ID: "ID",
fields: {
ID: { editable: false, nullable: true },
DESCRIPTION: { validation: { required: true } }
}
}
}
});
$("#detailsGrid").kendoGrid({
dataSource: dataSource,
attributes: { style: "padding-left: 0px; font-size: 14px"},
pageable: {refresh: false, pageSizes: false, buttonCount: 5},
toolbar: ["create"],
columns: [
{field: "DESCRIPTION", title: "DESCRIPTION", width: "200px"},
{ command: ["edit", "destroy"], title: "Operasyon", width: "100px" }],
editable: "popup"
});
Controller
[HttpPost]
public ActionResult DefinitionDetailUpdate(string models)
{
//Deserialize to object
IList<UrObjectType> objName= new JavaScriptSerializer().Deserialize<IList<UrObjectType>>(models);
return Json(objName)
}
[HttpPost]
public ActionResult DefinitionDetailCreate(string models)
{
//Deserialize to object
IList<UrObjectType> objName= new JavaScriptSerializer().Deserialize<IList<UrObjectType>>(models);
return Json(objName)
}
Note that parameterMap: function() send updated data in serialize string format with name models so you should use "models" as parameter name in your action
i hope this will help you:)
$('#PermissionGroupGrid').jtable({
ajaxSettings: {
type: 'GET',
dataType: 'json'
},
sorting: true,
paging: true,
useBootstrap: true,
pageSize: 5,
title: 'List of Permission Group',
actions: {
listAction: '/PermissionGroup/List',
deleteAction: '/PermissionGroup/Delete',
updateAction: '/PermissionGroup/Update',
createAction: '/PermissionGroup/Create'
},
defaultSorting: 'PermissionGroupName ASC',
fields: {
Id: {
key: true,
create: false,
edit: false,
list: false
},
Permissions: {
title: 'Permissions',
width: '5%',
sorting: false,
edit: false,
create: false,
display: function (permissionData) {
var $img = $('<img src="../../Images/list_metro.png" title="Assign Permissions" />');
$img.click(function () {
console.log(permissionData);
console.table(permissionData);
$('#PermissionGroupGrid').jtable('openChildTable',
$img.closest('tr'),
{
ajaxSettings: {
type: 'GET',
dataType: 'json'
},
title: permissionData.record.PermissionGroupName + ' - Permissions',
actions: {
listAction: '/Permission/ListPermission?PermissionGroupId=1',
deleteAction: '/Demo/DeleteExam',
updateAction: '/Demo/UpdateExam',
createAction: '/Demo/CreateExam'
},
fields: {
PermissionGroupId: {
type: 'hidden',
defaultValue: permissionData.record.Id
},
Id: {
key: true,
create: false,
edit: false,
list: false
},
PermissionName: {
title: 'Permission Name'
}
}
}, function (data) {
data.childTable.jtable('load');
});
});
return $img;
}
},
PermissionGroupName: {
title: 'PermissionGroupTitle'
}
}
});
$('#PermissionGroupGrid').jtable('load');
When any of the child record is requesting for Update, child record's Id is being sent in the GET request but not the Id of the Master record. I followed the demo on jtable.org exactly. When console.log 'permissionData.record.Id' I can see the master record's Id. FTR, both Master and Child table's key column has name 'Id'.
Can some one please suggest a solution?
Based on jTable 2.4.0 debugging, defaultValue is used only on create form. If you are editting existing item record[fieldName] is used instead. In your case record["PermissionGroupId"]. That means you need to include PermissionGroupId field on your child record object to make it work.
I have this code that gets json object from a static url and then renders grid. But I want to use json data retrived as AJAX response and then render grid using this response text. Because for practical deployment I can't use static URL.
$("#grid").kendoGrid({
dataSource: {
type: "json",
transport: {
read: {url: "http://url/returnsjsonobject.php"}
//THIS GETS DATA FROM STATIC URL BUT I WANT TO READ DATA AS AJAX RESPONSE
//like read: somefunctioncall
//or like read: somevariable
},
schema: {
model: {
fields: {
id: {type: "string", editable: false},
name: {type: "string"}
}
}
},
pageSize: 20
},
height: 430
columns: [
{field: "id", title: "ID", width: "20px", hidden: "true"},
"name",
});
Thanks in advance for help and if you have any alternative method; I will be happy to try it.
Remember that transport.read.url does not have to be a constant but might be a function:
transport: {
read: {
url: function(options) {
return "somefunctionalcall?id=" + options.id,
},
dataType: "json"
}
or even define transport.read as a function:
transport: {
read: function (options) {
$.ajax({
dataType: "json",
url: "somefunctionalcall",
success: function (d) {
options.success(d);
}
});
}
}