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
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:
I have a checkbox column in my JqGrid which get loaded from DB, so it is either checked or not checked when it is loaded.
What i want is : If checkbox is being checked or uncheked by user i want to update DB in at same. I dont want user to press enter or anything. only 1 click and send action to DB
name: 'Aktiv', index: 'Aktiv', width: 100, edittype: 'checkbox', align: 'center',formatter: "checkbox", editable: true, formatoptions: {disabled : false}
You can set a click event handler inside of loadComplete:
loadComplete: function () {
var iCol = getColumnIndexByName ($(this), 'Aktiv'), rows = this.rows, i,
c = rows.length;
for (i = 1; i < c; i += 1) {
$(rows[i].cells[iCol]).click(function (e) {
var id = $(e.target).closest('tr')[0].id,
isChecked = $(e.target).is(':checked');
alert('clicked on the checkbox in the row with id=' + id +
'\nNow the checkbox is ' +
(isChecked? 'checked': 'not checked'));
});
}
}
where
var getColumnIndexByName = function(grid, columnName) {
var cm = grid.jqGrid('getGridParam', 'colModel'), i, l;
for (i = 1, l = cm.length; i < l; i += 1) {
if (cm[i].name === columnName) {
return i; // return the index
}
}
return -1;
};
Instead of the alert you should use jQuery.ajax to send information to the server about updating the checkbox state.
You can see a demo here.
A small correction in the loadComplete: function().
in the demo you can find that even after the checkbox is checked, if you click outside the checkbox in that cell, the value gets changed to 'false' from 'true'.
To avoid this, just give the focus exactly on the checkbox alone by doing the following.
for (i = 1; i < c; i += 1) {
$(('input[type="checkbox"]'),rows[i].cells[iCol]).click(function (e) {
var id = $(e.target).closest('tr')[0].id,
isChecked = $(e.target).is(':checked');
alert('clicked on the checkbox in the row with id=' + id +
'\nNow the checkbox is ' +
(isChecked? 'checked': 'not checked'));
});
}
and thanks for the answer :-) (#Oleg) helped me a lot..in time of course.. ;)
To change values of other column based on click of checkbox
var weightedAvgPriceIndex = getColumnIndexByName($(this), 'WeightedAveragePrice'),
rows = this.rows,
i,
c = rows.length;
for (i = 1; i < c; i += 1) {
$(('input[type="checkbox"]'),rows[i].cells[iCol]).click(function (e) {
var id = $(e.target).closest('tr')[0].id;
isChecked = $(e.target).is(':checked');
var x = $('#' + id + ' td:eq(' + weightedAvgPriceIndex + ')').text();
$('#' + id + ' td:eq(' + weightedAvgPriceIndex + ')').text(Math.abs(x) + 10);
});
}