customize: POST output in jqGrid without changing source file? - session

I'm trying to turn jqGrid within MODx, as do other data exchange using "$. ajax", move the call from a URL to a resource protected by a password and from there call a snippet of code in PHP, so the security framework, the ajax call is guaranteed
This is one example of a chunk $.ajax:
$.ajax ({
url :'[[~94]]',
type: 'post',
async: false,
success: function(rsp) {
$.Cookie("xxxxxx-tipodirlist", rsp);
}
});
*[[~94]] is a protected resource is within a snippet call [[!SnpBridgedata_blabla]]
the system works perfectly well throughout the web application, receiving and sending data safely and securely.
Now a customer asked me for a completed application wanted web results in a good grid and after seeing a bit of code I decided to use jqGrid for my project.
integration was quick and I am very happy to have changed "DataTable" with "jqGrid," but when I finished the test, change the absolute path to xxxxxx.php with the call to snippet
this is the code for jqGrid:
chargeSedi function (idx)
{
// Test with file. Php !work fine!
// Var esURL = 'http://xxxxx.com/xxxxxxx.php?IDX =' + idx;
// Test with MODx resource !not work!
esURL var = '[[~ 97]] & IDX =' + idx;
csURL var = '[[~ 96]] & IDX =' + idx;
tipodirlist = $ var. cookie ("xxxxxxxx-tipodirlist");
tiposedelist = $ var. cookie ("xxxxxxx-tiposedelist");
$("#sediTable").ready(function() {
$("#sediTable").jqGrid({
url:csURL,
datatype: "json",
height: 250,
autowidth:true,
colNames:[ 'ID','CODICE', 'NOME','TDIR', 'DIR','COMUNE', 'PROVINCIA','CAP', 'TSEDE','NOTA'],
colModel:[
{name:'ID',index:'ID', width:25, editable: false},
{name:'CODICE',index:'CODICE', width:60, editable: true},
{name:'NOME',index:'NOME', width:60, editable: true},
{name:'TDIR',index:'TDIR', width:60, editable: true,edittype:"select",editoptions:{value:tipodirlist}},
{name:'DIR',index:'DIR', width:200, sortable:false,editable: true},
{name:'COMUNE',index:'COMUNE', width:170, sortable:false,editable: true},
{name:'PROVINCIA',index:'PROVINCIA', width:170, sortable:false,editable: true},
{name:'CAP',index:'CAP', width:40, sortable:false,editable: true},
{name:'TSEDE',index:'TSEDE', width:90, editable: true,edittype:"select",editoptions:{value:tiposedelist}},
{name:'NOTA',index:'NOTA', width:170, sortable:false,editable: true,edittype:"textarea", editoptions:{rows:"2",cols:"10"}} ],
sortname: 'ID',
viewrecords: true,
sortorder: "desc",
loadonce: true,
editurl: esURL ,
caption: "Sedi" });
});
]
and for my surprise the MODx deny Access to jqGrid ajax calls, as if you were out of session, but after hours testing and watching the traffic with wireshark I realized that jqGrid sends a POST variable called "id" and call MODx a GET variable "id". this in other environments is possible without problem, but it is not possible MODx and there's the problem.
my question is how I can change the name of the POST variable "id" jqGrid, without changing the source of jqGrid?
at the same time wanted to ask, you can customize the import of a select the value and not the index
example of trame POST:
{Name: 'TDIR', index: 'TDIR', width: 60, editable: true, EditType: "select" editoptions: {value: tipodirlist}}
tipodirlist = 1:via;2:piazza;3:ect
TDIR=2
CODICE=1&NOME=principale&TDIR=2&DIR=Roma&COMUNE=Torino&PROVINCIA=Torino&CAP=10000&TSEDE=2&NOTA=NO=edit&id=0
for this:
TDIR=piazza
CODICE=1&NOME=principale&TDIR=piazza&DIR=Roma&COMUNE=Torino&PROVINCIA=Torino&CAP=10000&TSEDE=2&NOTA=NO=edit&id=0
without having to filter the results on the server.
I hope I've explained well and clear. as I asked myself, the team "StackOverflow" before asking this question
Thank you so much
Regards
niro.
PS.I hope that GOD "Oleg" help me:)

I don't know and don't use MODx. Nevertheless I hope that your problem is: how to rename the name of the id parameter to have no conflict with the id parameter used by MODx.
If I understand your question correct you should just add additional prmNames parameter which set the new name of id parameter used in editing operations:
prmNames: {id: 'myId'}
The example will rename the default id parameter name ({id: "id"}) to myId which you should you in your server part.

Related

Mapping data to JQGrid with Ajax call

I'm just trying to display a very simple JQGrid with data from an ajax call to a controller. All I'm seeing is the grid headers, no data. Can someone please help me figure out what I'm doing wrong? Thanks in advance!
Here's the Ajax call and JQGrid setup..
$("#grid").jqGrid({
url: '#Url.Action("GetLoanReport", "Report")',
datatype: "json",
height: "auto",
colNames: ['Name', 'Random Stuff'],
colModel: [
{ name: 'Name', index: 'Name', width: 150, sortable: true },
{ name: 'RandomStuff', index: 'RandomStuff', width: 500, sortable: false }
],
jsonReader: {
repeatitems: true,
root: 'rowdata',
page: 'currpage',
total: 'totalpages',
records: 'totalrecords'
},
rowNum: 10,
rowList: [5, 10, 30],
rownumbers: false,
gridview: true,
loadonce: true,
pager: "#page",
caption: "Flat Data Example"
});
Here's the controller code...
Function GetLoanReport() As JsonResult
ViewData("Ribbon") = "partials/_statsRibbon"
Dim response As New Response
Dim model As New ReportModel
model.Name = "Mark"
model.RandomStuff = "Highfield"
response.currpage = 1
response.totalpages = 1
response.totalrecords = 1
response.rowdata = model
Return Json(response, JsonRequestBehavior.AllowGet)
End Function
The main problem: rowdata should be array of items (array of objects) instead of one object only with Name and RandomStuff properties.
Additionally you should decide whether you implement server side paging of data or you want to return all the data from GetLoanReport at once and jqGrid should make local paging, sorting and filtering/sorting the data? In the case you should use loadonce: true option. Additionally it's important to choose the fork of jqGrid, which you use: free jqGrid, commercial Guriddo jqGrid JS or an old jqGrid in version <=4.7. I develop free jqGrid fork, which I can recommend you. If you use it, then I would recommend you to add forceClientSorting: true option additionally to loadonce: true. It will allows you to use sortname and sortorder options to sort the data returned from the server before it will be displayed.

jqGrid : searchrules in single Field searching

I'm trying to validate the search field for integer data alone but unfortunately am unable to do so. I have tried all possible solutions like searchrules:{required:true,integer=true} etc..
But none of them proves fruitful.
I basically launch the search dialog with the field and without inputting any data, am hitting on the 'Find' button. As per the above options, i believe a validation message should be shown to the user asking him to enter a value in the field before hitting find.
[UPDATED] - Code Snippet
var grid = $("#list");
grid.jqGrid({
url:'/index.jsp',
datatype: 'json',
mtype: 'POST',
colNames:['Name','Age', 'Address'],
colModel :[
{name:'name', index:'name', width:55,search:true },
{name:'age', index:'age',
width:90,editable:true,search:true, stype:'text',
searchrules:{required:true,integer:true}},
{name:'address', index:'address', width:80,
align:'right', editable: true,search:false }
],
pager: '#pager',
jsonReader : {
root:"address",
page: "page",
total: "total",
records: "records",
repeatitems: false
},
rowNum:10,
rowList:[10,20,30],
sortname: 'name',
sortorder: 'desc',
viewrecords: true,
gridview: true,
autowidth: true,
toppager: true,
loadtext: "Loading records.....",
caption: 'Test Grid',
gridComplete: function(){
}
});
**grid**.jqGrid('navGrid','#pager',
{view:true,edit:true,add:true,del:true,refresh:true,
refreshtext:'Refresh',addtext:'Add',
edittext:'Edit',cloneToTop:true,
edittitle: "Edit selected row"},
{},{},{},
{caption: "Search The Grid",Find: "Find Value",Reset: "Reset"},
{});
[Updated] : Am not able to make the searchrules properly work for the single/advanced searching modes.
[Updated] : Even the 'Validation in Search' in
jqGrid Demo is not working for searchrules.
The reason of described problem is a bug in jqGrid. The line
ret = $.jgrid.checkValues(val, -1, null, colModelItem.searchrules, colModelItem.label);
initialize the third parameter of $.jgrid.checkValues to null, but the last version of checkValues implementation started (see the line) with
var cm = g.p.colModel;
but g is initialized to null. The last modification which generates the error was based on my suggestion, but I don't wrote the part of the code.
One can solve the problem in different way. I would suggest to modify the line where $.jgrid.checkValues will be called with null parameter to the following
ret = $.jgrid.checkValues(val, -1, {p: {colModel: p.columns}}, colModelItem.searchrules, colModelItem.label);
Additionally, to be sure, I would suggest to modify one more line
if(!nm) { nm = g.p.colNames[valref]; }
to
if(!nm) { nm = g.p.colNames != null ? g.p.colNames[valref] : cm.label; }
The fixed version of jquery.jqGrid.src.js one can get here. I will post my bug report with the same suggestions later ti trirand.

jqgrid:getting values from a table with combobox and use it as a range to other form

i had a script like this
<script type="text/javascript">
var gridimgpath = 'themes/basic/images';
//alert($("jqContextMenu"));
jQuery("#VWWMENU").jqGrid(
{
url:'loadstatic.php?q=2&t=CORE_VW_WMENUS',
datatype: "json",
mtype: "POST",
colNames:['Id', 'Module'],
colModel:
[
{
name:'id',
index:'id',
width:7,
editable:true,
edittype:'text',
editrules:{required:true},
editoptions:{maxlength:10, size:10},
formoptions:{rowpos:2, elmprefix:' '},
key:true
},
{
name:'modulename',
index:'modulename',
width:15,
editable:true,
edittype:'select',
editrules:{required:true},
editoptions:{maxlength:10, size:0, dataUrl:'combopub.php?t=MODULE'},
formoptions:{rowpos:1, elmprefix:' '}
}
...
</script>
the 'modulename' form is a combobox which taken its data from a table named 'module'. in this 'module' table there is a column named "fromid" and "toid". now how can i get these two values to be the range for the 'id' form? so when i input a value to form 'id' and then i submit it, it will show a message about id that i entered is out of range. i also don't know how to make the message that to appear when this error happened. so would you guys please help me on this?
i am still a total noob about this javascript or jquery kind of thing, so your help would be much appreciated.
i hope this would help to make it clearer of what i mean.
here is table module:table_module. from left to right (exclude column covered with the red line) idmodule, namemodule, idchildfrom, idchildto. and the module name that shown on the screen is actually a concate of idmodule and namemodule
now if you pick 2 from modulename combobox like this combobox_1 then you should get the range id from 201-400. and that means if you input a value of 300 into id and you press submit button, there would be an error message appear telling you that your input is more is out of range.
i hope this explanation can help you to understand more of what i actually wants to do
If I understand you correctly you can use relatively new feature (it exist starting with jqGrid 4.4.2) implemented based on my suggestion. It allows to use postData defined as function:
{
name: "modulename",
width: 15,
editable: true,
edittype: "select",
editrules: {required: true},
editoptions: {
maxlength: 10,
size: 0,
dataUrl: "combopub.php",
postData: function (rowid) {
return { id: rowid, t: "MODULE" };
}
},
formoptions: {rowpos: 1, elmprefix: " "}
}
See the answer and the pull request for more details.

passing csrf token through jqgrid on cell edit

I'm using Codeigniter and jqgrid to build an application. I've recently enabled Codeigniter's builtin CSRF protection for security reasons, and it broke some stuff with jqgrid. I've been able to pass the csrf token when jqgrid is instantiated so all my data loads (by adding the csrf token to the postData), but now anytime I edit a cell I get a 500 error because the csrf token isn't being passed. I can verify this by looking at the post data each time I edit a cell. I read several places that editData is what I want, but adding the token in there doesn't seem to pass it in the edit ajax request. Any ideas?
$("#cust_grid").jqGrid({
url:'/ajax/grid',
datatype: 'xml',
mtype: 'POST',
postData: {<?php echo $this->security->get_csrf_token_name().":'".$this->security->get_csrf_hash()."'"; ?>},
editData: {<?php echo $this->security->get_csrf_token_name().":'".$this->security->get_csrf_hash()."'"; ?>},
colNames:['Name1', 'Name2'],
colModel :[
{name:'name1', index:'name1', width:55, search: true},
{name:'name2', index:'name2', width:110, search: true},
],
pager: '#pager',
rowNum:25,
rowList:[10,25,50,100],
sortname: 'name1',
sortorder: 'asc',
viewrecords: true,
gridview: true,
caption: 'Customers',
height: 600,
width: 1200,
shrinkToFit: false,
altRows: true,
cellEdit: true,
cellsubmit: "remote",
cellurl: "/ajax/editCell",
},
{}
);
It seems that you can solve the problem mostly in the same way like I described here. The main difference is that you use cell editing instead of form editing. So you should use ajaxCellOptions instead of ajaxEditOptions:
ajaxCellOptions: {
loadBeforeSend: function(jqXHR) {
// you should modify the next line to get the CSRF tocken
// in any way (for example $('meta[name=csrf]').attr('content')
// if you have <meta name="csrf" content="abcdefjklmnopqrstuvwxyz="/>)
var csrf_token = '<%= token_value %>'; // any way to get
jqXHR.setRequestHeader('X-CSRF-Token', csrf_token);
}
}
I ended up finding another solution to the problem. I was investigating the cell editing link posted in the another answer and I saw the beforeSubmitCell option. Turns out if you return json data from that function it will be appended to the post data each time a cell is edited. So all I needed to do was add as an option:
beforeSubmitCell: function (rowid,celname,value,iRow,iCol) {
return {<?php echo $this->security->get_csrf_token_name().":'".$this->security->get_csrf_hash()."'";?>}
},
No answer working out after I tried. Then i found the solution for passing CSRF Token from Jqgrid inline editing to Django by using this :
onSelectRow: function(id){
if(id && id!==lastSel){
$(selector).restoreRow(lastSel);
lastSel=id;
}
var editparameters = {
extraparam: {csrfmiddlewaretoken: $('.token-data').data('token')},
keys: true,
};
$(selector).jqGrid('editRow', id, editparameters);
}
Example usage :
http://yodi.polatic.me/jqgrid-inline-editing-integration-with-django-send-csrf-token/

Fire an event after a local delete jqgrid

So what I am trying to do is fire an event AFTER a local delete has been done on the jqgrid. The reason for this is because I am dealing with a global save on the website so I am not posting directly to the server. I am storing the data in JSON form within a hidden element on the page so when the user finally saves the element value is grabbed and sent to the server along with all the other data.
The issue I am having is that when I delete a row from the jqgrid I am not able to update the hidden element with the change, so if the user saves after that it is like the remove never happened.
$("#translationMappingGrid").jqGrid({
data: mydata,
datatype: "local",
mtype: 'GET',
colNames:['From','To', 'Type'],
colModel :[
{name:'from',index:'from', width:180, align:"left",sorttype:"float", editable: true, editrules:{custom:true, custom_func:validateIPGridInput}},
{name:'to',index:'to', width:180, align:"left",sorttype:"float", editable: true, editrules:{custom:true, custom_func:validateIPGridInput}},
{name:'type',index:'type', width:200,align:"left",sorttype:"float", editable: true,
edittype:"select", formatter:'select', editoptions:{
value:"0:Never Translate;1:Always Translate;2:Only If Source;3:Only If Destination"}
},
],
pager: '#pager',
rowNum:10,
rowList:[10,20,30],
sortname: 'invid',
sortorder: 'desc',
viewrecords: true,
gridview: true,
caption: 'Mapping',
editurl: 'probe.sysinfo.ajax',
url:'clientArray',
onSelectRow: function(id){
jQuery('#translationMappingGrid').jqGrid('restoreRow',lastsel2);
//below are the parameters for edit row, the function is called after a successful edit has been done
//jQuery("#grid_id").jqGrid('editRow',rowid, keys, oneditfunc, succesfunc, url, extraparam, aftersavefunc,errorfunc, afterrestorefunc);
jQuery('#translationMappingGrid').jqGrid('editRow',id,true,"","","","",function () {
setTranslationMappingJSON(getGridDataJSONString(this));
window.parent.document.getElementById('notificationDiv').style.display= "";
});
lastsel2=id;
},
afterInsertRow: function(rowid, rowdata, rowelem ){
//alert("after insert row");
setTranslationMappingJSON(getGridDataJSONString(this));
window.parent.document.getElementById('notificationDiv').style.display= "";
}
});
//adds buttons to jqgrid nav bar
jQuery("#translationMappingGrid").navGrid('#pager',{
edit:false,add:true,del:true,search:false,refresh:true
}, {
closeAfterAdd:true,
closeAfterEdit: true
},
{
closeAfterAdd:true,
closeAfterEdit: true,
afterSubmit: function(response, postdata) {
alert("after complete row");
setTranslationMappingJSON(getGridDataJSONString(this));
window.parent.document.getElementById('notificationDiv').style.display= "";
return [true,""];
}
});
As indicated in the code above I am successfully updating the hidden element with the changes on both add and edit (inline) via afterrestorefunc, but this is not working for delete.
I have tried using afterSubmit in the code above, but this is not working either. I have been working on this for a few days now and have come to the conclusion that I might have to write my own custom code for the delete button entirely, but I am hoping this is not the case.
The OP wrote in an edit:
So it appears as though I was staring at the issue for too long and was missing the obvious....lucky me. I found out two things:
Using afterSubmit was the wrong thing to use, instead I should be using afterComplete.
I had tried using afterComplete before trying afterSubmit and the reason it was not working it because I am putting them both within the "add" parameters and NOT the delete. Once again, I feel pretty awesome for that one :)
Well now that I have figured that out here is the code snippet that saved my life:
jQuery("#translationMappingGrid").navGrid('#pager',{
edit:false,add:true,del:true,search:false,refresh:true
}, {
closeAfterAdd:true,
closeAfterEdit: true
},
{
closeAfterAdd:true,
closeAfterEdit: true
},{
afterComplete:
function () {
//saves the changed JSON string to the hidden element
setTranslationMappingJSON(getGridDataJSONString(jQuery('#translationMappingGrid')));
window.parent.document.getElementById('notificationDiv').style.display= "";
}
});
This is tested and the function is called after the delete has been performed and saves the local changes to my hidden element.
For anyone who is curious about what the format is:
/* The following is the setup
navGrid(<name>, {<buttons, true/false},
{
<edit parameters>
},
{
<add parameters>
},
{
<delete parameters>
}
*/
Thanks for everyone who might have started working on this, and definitely thanks to the developers of jqgrid. Best javascript grid I have ever worked with!

Resources