jqGrid change dynamically edittype for specific row
cell, jqgrid
Solution
I think that many from the problems in your code common. So I tried to answer on you question more detailed.
First of all you posted wrong JSON data. The line
{"cell"[4,"Service,"Administratif","select","0:Administratif;1:Commercial;2:Magasin;3:M\u00e9canique;4:Rejointage;5:Soudure;6:Tests"]},
contains two errors:
- no ':' after "cell"
- no `"` after `"Service`
After the changes the line will be so
{"cell":[4,"Service","Administratif","select","0:Administratif;1:Commercial;2:Magasin;3:M\u00e9canique;4:Rejointage;5:Soudure;6:Tests"]},
and JSON data could be read. The next problem is the usage of numbers together with string in one array. Because the bug in the line of jqGrid code
idr = ccur !== undefined ? ccur[idn] || idr : idr;
ids could not be integer value 0. I posted the bug report about the error. To fix the problem using existing code of jqGrid you should use strings instead of numbers. For example the line
{"cell":[0,"Nom ","LEBRUN","text",""]},
should be changed to
{"cell":["0","Nom ","LEBRUN","text",""]},
Without the changes you will have id duplicates. Both first lines (`{"cell":[0,"Nom ","LEBRUN","text",""]}` and `{"cell":[1,"Pr\u00e9nom ","Jacques","text",""]},`) will get the same id equal to 1 instead of 0 and 1. It was the main reason of the problem which you described.
Additionally I would recommend you the following:
- remove `cellEdit:true` option. You use `editRow` later in the code. It means that you use inline editing instead of cell editing which means `cellEdit:true`. You can't combine both editing modes in one grid.
- replace `height:250` option to `height:"auto"`
- remove all `index` properties from `colModel`. Remove all properties of `colModel` with default values (`edittype:'text'`, `editable:false`)
- remove options of jqGrid with default values (`mtype:'GET'`, `scroll:false`)
- all parameters of functions in JavaScript are optional. So if you don't use for example any parameters of `cellattr` callback you can replace `cellattr: function (rowId, val, rawObject, cm, rdata) {...}` to `cellattr: function () {...}`
- the callback `loadComplete` has one parameter `data` which can provide you all data which returned from the server. So you don't need to use `getDataIDs` and `getRowData`. The array `data.rows` can by directly used.
- if you use `data` parameter of `loadComplete` callback you can remove unneeded `'type'` and `'data'` columns from the grid.
- if you place information about `id` after `'Label','Information'` then you can use `id` property of `jsonReader` and remove hidden `id` column from the grid too. For example if you move `id` as the last in the `cell` array you can use `jsonReader: {id: 4}` and remove hidden `id` column from the grid. If you add additionally `cell: ""` property in `jsonReader` you can remove `"cell":` from the input data. If you would use `root` property of `jsonReader` defined as function (see the documentation) you can remove some unneeded data from the server response.
For example the server can produce the simplified data
[
["Nom ","LEBRUN","text","","0"],
["Pr\u00e9nom ","Jacques","text","","1"],
["Initiales ","LJ","text","","2"],
["Fonction ","","text","","3"],
["Service","Administratif","select","0:Administratif;1:Commercial;2:Magasin;3:M\u00e9canique;4:Rejointage;5:Soudure;6:Tests","4"],
["T\u00e9l\u00e9phone ","","text","","5"],
["Email ","","text","","6"],
["Statut ","CDI","select","0:CDI;1:CDD;2:App;3:Stg;4:Int","7"],
["Entr\u00e9 le ","2008-10-06","text","","8"],
["Sorti le ","0000-00-00","text","","9"]
]
The corresponding jqGrid could be
$("#dlgpers").jqGrid({
url: "pers.php?id=" + dataRow.id,
datatype: "json",
height: "auto",
cmTemplate: {sortable: false},
gridview: true,
colNames: ["Label", "Information"],
colModel: [
{name: "label", align: "right", width: 100,
cellattr: function () {
return ' style="font-weight:bold;margin-right:5px;border-left:0;border-top:0;" class="ui-state-active"';
}},
{name: "info", width: 200, editable: true}
],
jsonReader: {id: 4, cell: "", root: function (obj) { return obj; } },
loadComplete: function (data) {
var $self = $(this),
cm = $self.jqGrid("getColProp", "info"),
idPrefix = $self.jqGrid("getGridParam", "idPrefix"),
l = data.length,
i,
item;
for (i = 0; i < l; i++) {
item = data[i];
cm.edittype = item[2] === "select" ? "select" : "text";
cm.editoptions = { value: item[3] };
$self.jqGrid("editRow", idPrefix + item[4]);
}
},
idPrefix: "dlg",
rowNum: 10000 // to have no paging
});
See the demo:
Problem
Following to this post where I found some way to do that I would want to get, I meet some trouble with it. Here is my code : ``` var myDlg = $("#dlgpers"),lastsel; myDlg.jqGrid({ url:'pers.php?id='+dataRow.id, mtype:'GET', datatype: "json", ajaxGridOptions: { cache: false }, height:250, cmTemplate: {sortable:false}, gridview: true, cellEdit:true, scroll:false, colNames:['Id','Label','Information','Type','Data'], colModel:[ {name:'id',index:'id',hidden:true,key:true}, {name:'label',index:'label',align:'right',width:100,editable:false, cellattr: function (rowId, val, rawObject, cm, rdata) { return ' style="font-weight:bold;margin-right:5px;border-left:0;border-top:0;" class="ui-state-active"' ; } }, {name:'info',index:'info',width:200,editable:true,edittype:'text'}, {name:'type',index:'type',width:30,hidden:true}, {name:'data',index:'data',width:30,hidden:true} ], loadComplete: function () { var rowIds = myDlg.jqGrid('getDataIDs'); $.each(rowIds, function (i, row) { var rowData = myDlg.jqGrid('getRowData',row); if (rowData.type == 'select') { myDlg.jqGrid('restoreRow', row); var cm = myDlg.jqGrid('getColProp', 'info'); cm.edittype = 'select'; cm.editoptions = { value: rowData.data }; myDlg.jqGrid('editRow', row); cm.edittype = 'text'; cm.editoptions = null; cm.editable = true; }else{ myDlg.jqGrid('restoreRow', row); var cm = myDlg.jqGrid('getColProp', 'info'); cm.edittype = 'text'; cm.editoptions = null; cm.editable = true; myDlg.jqGrid('editRow', row); cm.edittype = 'text'; cm.editoptions = null; cm.editable = true; } }); } }); ``` and the result as image : and the JSON response : ``` {"page":1,"total":1,"records":1,"rows":[ {"cell":[0,"Nom ","LEBRUN","text",""]}, {"cell":[1,"Pr\u00e9nom ","Jacques","text",""]}, {"cell":[2,"Initiales ","LJ","text",""]}, {"cell":[3,"Fonction ","","text",""]}, {"cell"[4,"Service,"Administratif","select","0:Administratif;1:Commercial;2:Magasin;3:M\u00e9canique;4:Rejointage;5:Soudure;6:Tests"]}, {"cell":[5,"T\u00e9l\u00e9phone ","","text",""]}, {"cell":[6,"Email ","","text",""]}, {"cell":[7,"Statut ","CDI","select","0:CDI;1:CDD;2:App;3:Stg;4:Int"]}, {"cell":[8,"Entr\u00e9 le ","2008-10-06","text",""]}, {"cell":[9,"Sorti le ","0000-00-00","text",""]}]} ``` Two questions I submit to your knowledge: - As you can see, the second line (Prénom) don't seem editable, but it is. - I don't understand why these inputs are visible, as I would want they appear only if I edit some cell. Many thanks for all your kind help for resolve (and explain) my wrong way. JiheL UPDATED 2013-03-29 I have applied your answer code and that run fine ! Many thanks. But I have created another form in such a way for another subject, and that cause me some troubles. Here is the code of this new form : ``` var showAbs=function(){ $('#EditDialog').empty(); var $table=$('<table></table>') .attr('id','dlgcong') .appendTo($('#EditDialog')); var myCong = $("#dlgcong"); myCong.jqGrid({ url:'xpabs.php?id='+id+'&y='+y, datatype: "json", height:"auto", cmTemplate: {sortable:false}, gridview: true, colNames:['Type absence','Début','Fin','id'], colModel:[ {name:'abs',index:'abs',width:155,editable:true,edittype:'select', editoptions:{ dataUrl:"selabs.php", dataEvents: [ { type: 'change', fn: function(e) { $(this).parent().css('background-color','#'+$(this).find('option:selected').attr('colr')); if($(this).find('option:selected').attr('colr')=='ffffff'){ $(this).parent().parent().find('input').datepicker('disable'); }else{ $(this).parent().parent().find('input').datepicker('enable'); $(this).parent().parent().attr('changed',true); } } } ] }, cellattr: function (rowId, val, rawObject, cm, rdata) { return ' style="background-color:#'+rawObject[4]+';color:white;"'; } }, {name:'debut',index:'debut',align:'center',width:70,editable:true}, {name:'fin',index:'fin',align:'center',width:70,editable:true}, {name:'id',index:'id',hidden:true} ], jsonReader: { cell: "", root: function (obj) { return obj; } }, loadComplete: function (data) { var $self = $(this), cm = $self.jqGrid("getColProp", "debut"), idPrefix = $self.jqGrid("getGridParam", "idPrefix"), l = data.length, i, item; for (i = 0; i < l; i++) { item = data[i]; cm.editoptions = { dataInit: function(element) { $(element).datepicker({ setDate:item[1], minDate:'01/01/'+y, maxDate:'31/12/'+y, onSelect: function( selectedDate,inst ) { $(element).val(selectedDate ); $(element).parent().parent().attr('changed',true); } }) } } } var cm = $self.jqGrid("getColProp", "fin"); for (i = 0; i < l; i++) { item = data[i]; cm.editoptions = { dataInit: function(element) { $(element).datepicker({ setDate:item[2], minDate:'01/01/'+y, maxDate:'31/12/'+y, onSelect: function( selectedDate,inst ) { $(element).val(selectedDate ); $(element).parent().parent().attr('changed',true); } }) } } $self.jqGrid("editRow", idPrefix + item[3]); } myCong.find('select').each(function(){ $(this).css({ backgroundColor:'transparent', color:'white', border:0, width:155 }); }); }, idPrefix: "cong", rowNum: 10000 }); //******************** // Button ' Valider ' //******************** $('<input />') .attr({ type:'button', }) .css({ float:'right', marginTop:'5px' }) .click(function(){ var toBeSaved=''; myCong.find('tr[changed=true]').each(function(idx){ if(toBeSaved.length>0){ toBeSaved+='|'; } toBeSaved+=$(this).find('td:eq(3)').text()+';'; toBeSaved+=$(this).find('select option:selected').val()+';'; toBeSaved+=$(this).find('input:eq(0)').val()+';'; toBeSaved+=$(this).find('input:eq(1)').val(); }); if(toBeSaved.length>0){ $.ajax({ url:'majpabs.php?id='+id+'&data='+toBeSaved, async:false, dataType:'json', success:function(data){ myGrid.trigger('reloadGrid'); $('#newAbs').val(' Nouveau ').attr('disabled',false); } }); } }) .val(' Valider les absences ') .appendTo($('#EditDialog')); //******************* // Button ' Retour ' //******************* $('<input />') .attr({ type:'button', id:'newAbs' }) .css({ float:'left', marginTop:'5px' }) .click(function(){ showPers(); }) .val(' Retour ') .appendTo($('#EditDialog')); //******************** // Button ' Nouveau ' //******************** $('<input />') .attr({ type:'button', disabled:false }) .css({ float:'left', marginTop:'5px', marginLeft:'7px' }) .click(function(){ if($(this).val()==' Nouveau '){ var myRow = {abs:"0", debut:'00/00/'+y, fin:'00/00/'+y, id:'0'}; myCong.jqGrid('addRowData','',myRow, 'last'); $(this).val(' Sauver ').attr('disabled',true); }else{ } }) .val(' Nouveau ') .appendTo($('#EditDialog')); } ``` and the result as image : - As you can see, the first row does not receive select and datepicker as other rows. Strange ! - When I add new row, it does not receive select and datepicker as the first row. I think I'm wrong in understanding this method. I'm worry to bother you with these questions, I had a look in wiki without success to find any way to make these points correct. I would like to find some more detailed tutorial which show some cases examples. Thank you VERY MUCH if you can spend again some time for give me a way to be more efficient with jqGrid.JiheL UPDATED 2013-04-01 I have applied Oleg's suggestions and that works now. But a trouble remains. here is the image : For the first row, select box is OK. The first input field receive datepicker, but the second (the column called 'fin') not ! All others rows receive well datepickers, but not the last field of first row. Here is the code : ``` loadComplete: function (data) { var $self = $(this), idPrefix = $self.jqGrid("getGridParam", "idPrefix"), l = data.length, i, item, cm; for (i = 0; i < l; i++) { item = data[i]; cm = $self.jqGrid("getColProp", "debut"); cm.editoptions = { dataInit: function(element) { //alert('deb'+i); $(element).datepicker({ setDate:item[1], minDate:'01/01/'+y, maxDate:'31/12/'+y, onSelect: function( selectedDate,inst ) { $(element).val(selectedDate ); $(element).parent().parent().attr('changed',true); } }) } }; $self.jqGrid("editRow", idPrefix + item[3]); // cm = $self.jqGrid("getColProp", "fin"); cm.editoptions = { dataInit: function(element) { //alert('fin'+i); $(element).datepicker({ setDate:item[2], minDate:'01/01/'+y, maxDate:'31/12/'+y, onSelect: function( selectedDate,inst ) { $(element).val(selectedDate ); $(element).parent().parent().attr('changed',true); } }) } }; $self.jqGrid("editRow", idPrefix + item[3]); } myCong.find('select').each(function(){ $(this).css({ backgroundColor:'transparent', color:'white', border:0, width:155 }); }); }, ``` Another time, I hope you can help me to resolve this trouble and close this request. Many thanks for all the time you spend to help newbies. JiheL