jqgrid 4.5.4 jsonReader not using id correctly - jqgrid

I am defining the id field in the jsonReader. In jqgrid Version 4.4.5, this works great, but in Version 4.5.4, the id is ignored and the row numbers are always used. I have created two jsfiddles to demonstrate:
Double click on the row to get the id for that row.
This one correctly displays the id based on what's set in the jsonReader
(Scroll to bottom to see example grid code. I couldn't find external link to 4.4.5)
Version 4.4.5: http://jsfiddle.net/cVk59/1/
This one incorrectly displays the rowNumber for the id. It ignores what's set in jsonReader.
Version 4.5.4: http://jsfiddle.net/cnsgH/
jsonReader:{ repeatitems:false, id:'0'}

You use wrong value for jsonReader.id. Your current data, returned from the server, have the following format
...
rows: [
{id: 48803, thingy: "what"}
]
...
So the data for a row will be represented by an object like
var obj = {id: 48803, thingy: "what"};
To get id from the object one need to use jsonReader: { repeatitems: false, id: 'id' }. Because id: 'id' is already default value, you can use just jsonReader: { repeatitems: false }.
I try to explain the reason why id: '0' is wrong property of jsonReader in your case. jqGrid just use obj[jsonReader.id] to get the id for every row of data. So if you use jsonReader:{ repeatitems:false, id:'0'} then jqGrid trying to use obj['0'] which is wrong (undefined value). If you use jsonReader: { repeatitems: false, id: 'id'} instead (or just jsonReader: { repeatitems: false}) then obj[jsonReader.id] will be equal to obj['id'] or obj.id and the id will be successful read.
The property like jsonReader: { id: '0' } will be used if the data, represented a row, is array like
var obj = [48803, "what"];
In the case obj[jsonReader.id] will be equal obj['0'] or obj[0].

Related

Programmatically changing a bound check box in Kendo Grid not holding its new value

I am in need of assistance in an attempt to programmatically check/uncheck a checkbox in a kendo grid.
I have part of my Grids datasource for this relevant field as...
receivereport: {
editable: true,
nullable: false,
required: false,
type: 'boolean',
validation: {
required: false
}
},
And the grids configuration is...
$("#contactGrid").kendoGrid({
dataSource: contactGridDS,
navigatable: true,
dataBound: mapContactTypes,
editable: true,
edit: function (input) {
},
toolbar: ["save", "cancel"],
pageable: false,
columns: [
{ field: 'email', title: 'Email', hidden: false, attributes: { "class": 'contactCell_email' } },
{ field: 'receivereport', title: 'Receive Reports?', hidden: false, attributes: { "class": 'contactCell_receivereport' }, template: '<input type="checkbox" #= receivereport ? "checked=checked" : "" # value="" disabled="disabled" ></input>' }
],
//filterable: true,
sortable: {
mode: 'single',
allowUnsort: false
}
});
For brevity sake, I cut some of the other code out that's not relevant, such as other fields not involved here.
So, I have an email method that has a regex in it that works, and what I want to do is, if on focus, or focus out of the email field, if that email is invalid, make the receive report field false, but it's not registering dirty editing, and I even tried forcing it by appending some CSS rules and classes, which makes it "look" dirty, but when I change the value of the checkbox, on save, it goes back to what it was.
The data is bound to the receivereport data. So I think I read on the forums here that I need to do something like datasource.set("receivereport", false); And maybe a sync? The syncinc fires but it doesn't help and I must be calling the set incorrectly because the console says its firing on an unidentified object.
Here's the real kicker, I know how to access that check box and render it as false, but it flips right back to what it was bound to! It's not holding. Unless I click into that cell and do a click on the check box, it doesn't hold...
...unless I can simulate a fake click event on the target, being the checkbox...
I looked at the example here, Disable/Enable the checkbox in kendo grid based on column Value, but it seems a bit different and not what I need.
Bottom line - if the checkbox is true/checked, and a user goes back into the email field and renders it invalid, I want to automatically uncheck that checkbox, as well as make that checkbox disabled, until the user makes the email valid again. This also implies that a null email, means the checkbox must be false and disabled.
Anyways, any help would be immensely appreciated. Thanks.
This can be done using the "change" event of the dataSource:
dataSource = new kendo.data.DataSource({
change: function(e) {
if (e.action == "itemchange" && e.field == "email") {
//you can check the email value as well:
//var model = e.items[0];
e.items[0].set("receivereport", false)
}
},
Here is the full example:
Grid: change field value depending on another field

Kendo UI dataSource sync on button

i have kendo ui datasource sync.
Here is the link: http://jsbin.com/uhamer/3/
When you click on list, article will show in grid list(down), then if you click again on same article, it will increse quantity +1.
In that new dataSource that should be synced, schema.model.id is set to id.
When i click on Send data button, it shows me error.
Firebug:
TypeError: r is undefined
Chrome:
Uncaught TypeError: Cannot read property 'data' of undefined
What am i doing wrong here?
Thanks.
I'm not sure if this is part of your error, but with the Kendo UI DataSource it only considers the record to be "new" if its ID column is set to the default (0 since it is a number column). When you copy the row over to the new DataSource you are also copying the ID, so now Kendo thinks that the server already knows about this record since it has an ID.
You can see this by adding a record to your grid's DataSource, then running this JS in the console:
gridNewData.data()[0].isNew(); // returns false because the id column is not 0
When you call .sync() it looks for new records to push to the server but finds none.
You may want to consider having 2 different IDs here; one that is the ID of the Article, and one that is the ID of the DB row (Kendo expects the specified ID column to be the unique DB row ID)
for example:
var gridNewData = new kendo.data.DataSource({
...
schema: {
model: {
id: "id",
fields: {
id: { type: "number" }, // unique DB row ID
articleid: { type: "number" }, // article's ID
name: { type: "string" },
quantity: { type: "number" },
price: { type: "string" }
}
}
}
...
});
Then copy the article's ID into the grid's Article ID:
if (have_in === false) {
gridData.add({
id: 0, // leave this set to 0 or undefined, so Kendo knows it is new.
articleid: addData.id, // copy article's id to new row's articleid
name: addData.name,
quantity: 1,
price: addData.price.toFixed(2),
});
}
I edited your jsbin and you can view it here. Now when the "send data" button is clicked Kendo does a POST of the JSON data:
[{"articleid":1,"name":"Article 1","quantity":2,"price":"20.00","id":0}]
Also note that on the server side, the server should insert this new record into the DB then respond with JSON of the same records but with the "id" set to a non-zero value. For example if the server does a SQL INSERT into a table, that table would probably have some kind of auto generated sequence for the ID column, so if it was created with ID 123, then the server should send an HTTP response with the data:
[{"articleid":1,"name":"Article 1","quantity":2,"price":"20.00","id":123}]
Kendo DataSource will then insepct the HTTP response, fetch that id:123, and update the previously added record in the DataSource to have that id of 123. From that point the record is no longer "new" since its ID is not 0 or undefined, so additional calls to .sync() will not try to send that same record to the server again.
(if the server does not send a response with an id set for the new record, then Kendo will leave the id of the record int he DataSource set to 0, so each time you click "send data" it will keep sending that record over and over)

Jqgrid datatype local loading from array

During my question about how to re-apply the toolbar filter after the underline data is refreshed from a local js var question asked here, Oleg has provided me an solution:
1 use the combination of datatype:"local" and data:localvar.
Now I am facing a different problem which after a week I was not able to solve.
According to the Jqgrid wiki when using local datasource the default localreader looks like
The initial configuration of the localReader is the same as those from jsonReader
localReader = {
root: "rows",
page: "page",
total: "total",
records: "records",
repeatitems: false,
cell: "cell",
id: "id",
userdata: "userdata",
subgrid: {root:"rows", repeatitems: true, cell:"cell"}
}
I found this is not the case. Because in every examples that i can find using dataype:"local", it always uses a straight js array in stead of an js object, looking like this:
var mydata = [
{id:"1",invdate:"2007-10-01",name:"test",note:"note",amount:"200.00",tax:"10.00",total:"210.00"},
{id:"2",invdate:"2007-10-02",name:"test2",note:"note2",amount:"300.00",tax:"20.00",total:"320.00"},
{id:"3",invdate:"2007-09-01",name:"test3",note:"note3",amount:"400.00",tax:"30.00",total:"430.00"}];
I have tried using the default localReader (with repeatitems set to true) to process
var locObj = {"rows":[
{"id":0,"cell":["val1","val2","val3"]},
{"id":1,"cell":["val1","val2","val3"]}
],
"page":"1",
"total":"1",
"records":"2"
}
with
datatype:"local",
data:locObj
this will not work, because it wont pass the array check in the addlocaldata function. if I change the option to be
datatype:"local",
data:locObj.rows
I got a grid with correct number of rows but each cell has an empty value. I think that is becasue the addlocaldata function can not handle an array formatted like locObj.rows.
is there a way to actually process a json object (or string) with the datatype:"local" using the customised localreader (in stead of having to re-create an array on the client side)?
Any help is greatly appreciated.
Casbby
What you need to do is just the usage of
data: locObj.rows,
localReader: {repeatitems: true}
See the corresponding demo.

Passing different column id in jqgrid showLink formatter

I had a bean object with me in the colmodel of jqgrid. the object hold two attributes name and id. I used a showLink formatter to form the hyperlink in one of the column. Now i have names the colum with object.name and on click i want to send the id in URL. Any inputs on how to work on this.
Any inputs could help me
code :
colModel :[
{name:'xxx', label:'xxx', width:200,align:'left'},
{name:'yyy', label:'yyy', width:110,align:'left'},
{
name:'zzz',
label:'zzz',
width:100,
sorttype:'int',
formatter:'currency',
formatoptions:{decimalSeparator:".", thousandsSeparator: ",", decimalPlaces: 0, prefix: "$ "},
align:'center'
},
{name:'aaa', label:'aaa', width:80,align:'left'},
{name:'bbb', label:'bbb', width:100,align:'left'},
{
name:'strategies.name',
label:'strategies',
width:160,
align:'left',
formatter:'showlink',
formatoptions:{baseLinkUrl:'MyLink.html',addParam: '',showAction:'',idName:'id'}
}]
jQuery("#gridtableid").jqGrid('filterToolbar',{defaultSearch : "cn",stringResult: true,searchOnEnter : false});
Thanks in advance....
In JQgrid, you can call a javascript function and do any required formatting . You have the entire row data to play with it.
What needs to be done is call a function showlink in your case and remove formatoptions from that row. HAve a separate js function showlink as below and return the prepared link back to the grid.
function showLink(cellvalue, options, rowObject) {
var link = "'+ rowObject.columnName + "";
}

jqGrid - edit data

I am quite new to jquery and jqgrid. I use ASP.NET WebForms. I am able to get some data prom server and show it in grid. I use PageMethods to get data from server. Usually my code is
function CreateGrid(){
$("#sestGrid").jqGrid({
datatype: GetData,
//toolbar: [true, "top"],
colNames: ['Name', 'Age'],
colModel: [
{ name: 'Name', index: 'Name', width: 170, align: 'left',
sortable: false, key: true },
{ name: 'Age', index: 'Age', width: 40, align: 'center',
sortable: false, editable: true },
],
ondblClickRow: function () {
var row_id = $("#sestGrid").getGridParam('selrow');
$('#sestGrid').editRow(row_id, true);
}
});
}
function GetData() {
PageMethods.GetSestevalniStevecData(GotData);
}
function GotData (data) {
$("#sestGrid").clearGridData(false);
for (var j = 0; j <= data.length; j++)
$("#sestGrid").jqGrid('addRowData', j + 1, data[j]);
}
So, now I would like to edit some data and post it to server. How can I do that using PageMethods? Should I use any other approach?
And one more thing. I checked the demos http://trirand.com/blog/jqgrid/jqgrid.html and in all edit examples you are able to edit only one row and then you have to save changes… Is it possible to edit more than one row and save all changes in one step?
Thanks all.
jqGrid is designed to be used together with ajax services. So if the user change the data of some row then the changes will be send to the server: to the URL which you configure through jqGrid parameter editurl. So the easiest way to implement row editing will be to include an ASMX web-service or a WCF service in you web site. It is not important whether you use ASP.NET WebForms, ASP.NET MVC or just pure HTML for your pages. So just choose the technology which you prefer and add the corresponding page to your site.
The ASMX or WCF should has a method with the signature like
public string MyDataEdit (string Age, string oper, string id)
(see this old answer for more information). The method should return the id of the new added item (the Name in your case) in case of Add operation.
One more small remark. You can change the definition of the ondblClickRow function from function() to function(row_id) and remove the line used getGridParam('selrow').
I used your example and changed it a bit:
ondblClickRow: function (rowid) {
if (rowid && rowid != lastsel) {
changedRows.push(rowid); //keep row id
jQuery('#jqgrid').editRow(rowid, true);
}
}
Under the save button click event:
$.each(changedRows, function () {
var row = $("#jqgrid").getRowData(this);
var Id = row['ID'];
var price = $(row['Price']).val(); //this is an input type
});
HTH someone :)

Resources