Related
I have a JQGrid that updates via an ajax call to a web service.
It's all working fine, except from when I update the grid (and write it back to my database), the changes are not reflected in the grid.
I have read numurous posts with people reporting similar issues, but have tried on the suggestions to no avail.
loadonce is set to false, I reset my datatype to JSON and I have tried to destroy the grid before reloading it.
Here is my code thus far;
function LoadGrid2() {
//jgcontracts Grid
$.ajax({
type: "POST",
contentType: "application/json",
url: "../WebService1.asmx/getDataContacts",
dataType: "json",
success: function (data) {
data = data.d;
$("#jqcontacts").jqGrid({
datatype: "local",
colNames: ['Contact ID', 'Customer ID', 'First Name', 'Last Name', 'Email'],
colModel: [
{ name: 'contid', key: true, index: 'contid', width: 55, editable: true },
{
name: 'cust_name', index: 'cust_name', width: 80, align: "left", editable: true, edittype: "select",
editoptions: {
value: {}
}
},
{ name: 'first_name', index: 'first_name', width: 55, editable: true },
{ name: 'last_name', index: 'last_name', width: 55, editable: true },
{ name: 'email', index: 'email', width: 170, editable: true }
],
data: data,
caption: "Contacts",
viewrecords: true,
height: 200,
rowNum: 10,
pager: "#jqcontactsPager"
});
$('#jqcontacts').navGrid('#jqcontactsPager',
// the buttons to appear on the toolbar of the grid
{ edit: true, add: true, del: true, search: false, refresh: false, view: false, position: "left", cloneToTop: false },
// options for the Edit Dialog
{
url: "../WebService1.asmx/modifyDataContacts",
editData: {},
editCaption: "The Edit Dialog",
beforeShowForm: function (form) {
$('#contid', form).attr("disabled", true);
},
reloadAfterSubmit: true,
recreateForm: true,
checkOnUpdate: true,
checkOnSubmit: true,
closeAfterEdit: true,
errorTextFormat: function (data) {
return 'Error: ' + data.responseText
}
},
// options for the Add Dialog
{
url: "../WebService1.asmx/addDataContacts",
addData: {},
editCaption: "The Add Dialog",
beforeShowForm: function (form) {
$('#contid', form).attr("disabled", true);
},
closeAfterAdd: true,
recreateForm: true,
errorTextFormat: function (data) {
return 'Error: ' + data.responseText
}
},
// options for the Delete Dailog
{
url: "../WebService1.asmx/deleteDataContacts",
delData: {},
delCaption: "The Delete Dialog",
errorTextFormat: function (data) {
return 'Error: ' + data.responseText
}
});
},
error:
function (msg) {
alert(msg.status + " " + msg.statusText);
}
});
}
Here is my WebMethod
[WebMethod]
public object getDataContacts()
{
SqlConnection con = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["Indigo2.Properties.Settings.Constr"].ConnectionString);
SqlCommand cmd = new SqlCommand();
cmd.CommandText = "SELECT [contid] ,cust.[cust_name] ,[first_name] ,[last_name] ,[email] FROM [Indigo].[dbo].[contacts] con LEFT JOIN [Indigo].[dbo].[customers] cust on con.custid = cust.custid";
cmd.CommandType = CommandType.Text;
cmd.Connection = con;
con.Open();
SqlDataAdapter da = new SqlDataAdapter(cmd);
con.Close();
DataSet ds = new DataSet();
da.Fill(ds);
object obj = new JavaScriptSerializer().DeserializeObject(Newtonsoft.Json.JsonConvert.SerializeObject(ds.Tables[0]));
return obj;
}
Any help greatly appreciated.
You do not need of this code.
afterSubmit: function () {
$("#jqcontacts").setGridParam({ datatype: 'json'}).trigger('reloadGrid');
return [true];
},
Like you do, you do two ajax calls. If you set editurl in grid parameters or url like you do the edited data is posted automatically to the server with ajax call instead that your datatype is local.
jqGrid looks for url(editurl) parameter and not for the datatype when posting edited data.
Remove the afterSubmit event and test. If the data is not saved you will need to see what you posted to the server and your server side code for saving data.
Guriddo jqGrid is server side independent javascript lib when we speak about saving, retrieving, sorting,... data from server side.
UPDATE
I see why is this caused.
Let me explain.
Question: How do you obtain your initial data?
Answer: You obtain your data with your own ajax call and then pass this data to a grid with datatype local.
Q: How do you update your data?
A: You update your data remotely to the server with separate call using a build in jqGrid functionality.
Problem: if data type is local and updating is server side the update does not reflect the local data in grid since reloading it, it reloads the current local data which is not affected from the update.
How to solve? You have more than one options.
Reconstruct your grid so that it obtain a data direct using the grid option url and jsonReader. Maybe you will need here to read the docs - i.e all your interactions with the data are server side.
In case you do not want to make server sorting, paging and etc. you can use the grid option loadonce to true with combination of url obtaining data from the servrer and jsonReader . In this case you will need to return all the data from the server (not in portion). If you do so then you can set datatype to json in beforeSubmit event so that when the grid reloads after update, then it will read the updated data from the server.
Do not change you current grid configuration, but in this case you will need to set the option reloadAfterSubmit to false in navigator and write additional for updating the local grid data.
I prefer you to use the option2.
I see that there is a small problem with the grid in this situationand we will try to fix it in the future release.
I am using jqgrid version 4.5.2. I have a role list combobox outside of the grid and on change of the options I need to reload the grid. Below is the defination of my grid.
var finalUrl='';
var queueStatus=jQuery('#queueStatus option:selected').val();
finalUrl= "http://localhost:8080/ui/paw/loadworkflowqueuedata.raws?selRole="+ selectedRole+"&"+queueStatus;
var queueStatus=jQuery('#queueStatus option:selected').val();
finalUrl= "http://localhost:8080/ui/paw/loadworkflowqueuedata.raws?timezone="+&selRole="+ selectedRole+"&"+queueStatus;
jq("#grid").jqGrid('GridUnload');
jq("#grid").jqGrid({
url:finalUrl,
ajaxGridOptions: {cache: false},//added the option to always reload the grid and not to cache the result.
datatype: 'json',
mtype: 'GET',
colNames:[ 'Requestor Name'],
colModel:[
{name:'requestor',index:'requestor',sortable: true, width:100,editable:false, editrules:{required:true}, editoptions:{size:10}}
],
postData: {
},
height: 'auto',
autowidth: true,
rownumbers: true,
pager: '#pager',
viewrecords: true,
sortorder: "asc",
emptyrecords: "Empty records",
loadonce: true,
rowNum:20,
ignoreCase: true,
prmNames: {
nd: null
},
loadComplete: function() {
},
jsonReader : {
root: "rows",
repeatitems: false,
page:"page",
total: "total",
records: "records",
cell: "cell",
id: "id"
}
});
jQuery("#grid").jqGrid('navGrid','#pager',{edit:false,add:false,del:false,search: false, refresh:true})
.navButtonAdd('#pager',{caption:"Export All",buttonicon:"ui-icon-document",onClickButton: function(){window.open(excelUrl,'_self');},position:"last"});
jQuery("#grid").jqGrid('filterToolbar', { stringResult: true, searchOnEnter: false, defaultSearch: "cn",ignoreCase: true });
The grid above works fine(refreshes properly on change of rolelist combobox) only if I keep the below statement.
jq("#grid").jqGrid('GridUnload');
If I remove the above statement and reload the page than for the first time grid loads properly but after that If I change the option in my role list combo box it is not able to refresh the grid data neither it is throwing any error.
May I know why I need to unload the grid for refresh? Isn't there a way through which I can refresh the grid with out unloading the grid? Did I miss any options in grid defination that is the reason why grid reload is not working?Please do let me know if need more details for the above question for the solution.
You use loadonce: true options which is very helpful to load all the server data to the client side at once and then working with the data on the client side (paging, filtering and so on) without any communication with the server. To do this jqGrid changes datatype parameter of the grid to "local" after the first loading of data. So you need to reset the value of datatype parameter back to "json" before trigger reloadGrid event.
The corresponding code will be like
// create the initial grid
jQuery("#grid").jqGrid({
...
url: finalUrl,
datatype: 'json',
loadonce: true,
...
});
jQuery('#queueStatus').change(function () {
jQuery("#grid").jqGrid("setGridParam", {
datatype: "json",
url: "basePartOfUrl?" + jQuery.param({
timezone: "blabla",
selRole: jQuery('#queueStatus').val();
})
}).trigger("reloadGrid");
});
I use above jQuery.param instead of direct construction of parameters in the string to make the code more correct. Alternatively one should use encodeURIComponent to construct the parameter values appended to URL. It's clear that one can use queueStatus directly if it has no space, no special characters and so on, but the usage of encodeURIComponent or jQuery.param is still recommended and make the code working independent from the value of the string parameter.
I work with jqGrid on my project and I have a problem that can not seem to solve even after reading the forums on the same subject.
I would reload the grid when a user clicks a button after selecting a date. I want the data recharge correspodent to choose the date.
I use the following code:
var loadfacture = false;
$('#btn-facture').click(function(){
if(!loadfacture){
$("#factures").jqGrid({
url:'loadfactureencours.json',
datatype: "json",
autowidth: true,
height:250,
colNames:['#','Numero','Date', 'Client','Serveur','Prix Total','Avance','Regler','Notes'],
colModel:[
{name:'idfac',index:'idfac', width:45,align:"center"},
{name:'numfac',index:'numfac', width:80,align:"center"},
{name:'datefac',index:'datefac', width:150,align:"center"},
{name:'client',index:'client', width:145,align:"center"},
{name:'utilisateur',index:'utilisateur', width:125,align:"center"},
{name:'montant',index:'montant', width:70,align:"center"},
{name:'avance',index:'avance', width:60,align:"center"},
{name:'regler',index:'regler', width:50,align:"center"},
{name:'description',index:'description', width:150, sortable:false}
],
rowNum:10,
rowTotal: 2000,
rowList : [10,20,30,40,50,60],
loadonce:true,
mtype: "GET",
postData: {
day: function () {
return $('#daySelect').val();
}
},
rownumbers: false,
rownumWidth: 40,
gridview: true,
pager: '#paging',
sortname: 'idfac',
viewrecords: true,
sortorder: "desc",
caption: "",
ondblClickRow: function(rowid,iRow,iCol,e){
var rowData = jQuery(this).getRowData(rowid);
console.log(rowData);
window.location = "ecrancommandebar.html?num="+rowData.numfac;
}
});
$("#factures").jqGrid('navGrid','#paging',{del:false,add:false,edit:false});
loadfacture = true;
}else{
var grid = $("#factures");
grid.trigger("reloadGrid",[{current:true}]);
}
});
I built this piece of code by reading the forum on the same subject but the grid load the first time then when I click on the button after changing the date nothing happens.
What is wrong with you? Thank you for your feedback.
You use loadonce:true option which changes datatype from initial "json" to "local" after the first loading of the data from the server. It allows to support local sorting, paging and filtering of data. So you should understand that grid.trigger("reloadGrid",[{current:true}]); will just reload the data from previously saved previous response. So no reloading from the server will take place till you reset the value of datatype parameter to "json". In other words you should rewrite else part to about the following
...
} else {
$("#factures").jqGrid("setGridParam", {datatype: "json"})
.trigger("reloadGrid", [{current: true, page: 1}]);
}
You can try with this:
}else{
var grid = $("#factures");
$.ajax({
url: "loadfactureencours.json",
dataType: "json",
success: function(data){
grid.trigger("reloadGrid",[{current:true}]);
},
error: function(){}
});
}
I have a very specific problem: I have a small form with four options. You may fill them out or not, and when you click 'Ok', I load a jqGrid with data depending on those options. But since I do not know what my columns look like, I let my servlet generate the column model and column name; thus I have to make an AJAX request to load the data and then fill it in jqGrid as "local" data. I would like to use pagination though.
Thus my question: How may I load more data into a jqGrid after it is already established through local data?
here's the code:
$.ajax({
type : 'GET',
url : 'data.jsp',
data : reqData,
dataType : 'json',
error: function() {
$("#dialog-message").dialog("open");
$("#ajax-loader").css("display", "none");
},
success : function(result) {
jQuery("#results").jqGrid({
data : result.rows,
datatype : "local",
colNames : result.columnNames,
colModel : result.columnModel,
pager : $('#pager'),
rowNum : 1000,
scroll : true,
viewrecords : true,
sortname : 'TITEL',
width : window.innerWidth - 30,
height : window.innerHeight - 190,
altRows : true,
loadError: function() {
$("#dialog-message").dialog("open");
$("#ajax-loader").css("display", "none");
},
loadComplete: function() {
$("#ajax-loader").css("display", "none");
}
}).jqGrid("navGrid", "#pager", {
edit: false,
add: false,
del: false,
search: true,
refresh: false
}).jqGrid("gridResize");
}
});
/edit: I've tried to do the following, but that still doesn't solve the problem that the grid doesn't know how many total pages there actually are (actually, at that point, I don't even know), and also, after loading, it thinks it only gets local data. Is there maybe an onScroll event or something? I haven't found one.
datatype : !json ? "local" : function(postdata) {
$.ajax({
type: 'GET',
url: 'data.jsp',
data: $.merge(postdata, reqData),
dataType: 'json',
success: function(data, status, jqXHR) {
var mygrid = jQuery("#results")[0];
var myjsongrid = eval("("+jqXHR.responseText+")");
mygrid.addJSONData(myjsongrid);
}
});
},
Can you not do something like this...get the grid, clear the data, define the url to get the data from (it may change depending on what option your user selected) and then change the dataformat to json instead of local.
var grid = $('#TargetGridID');
grid.clearGridData();
grid.setGridParam({ url: '../controller/action?datatype=Option1' });
grid.setGridParam({ datatype: 'json' });
grid.trigger('reloadGrid');
We use this methodology and it works great...use this with stored procedures capable of paging and the grids are blazing fast! I know a 20,000 row grid takes us roughly 700ms with a page count of 500 rows.
If you are using SQL for your data I can upload a sample on how to support paging in a SQL Stored Proc, very useful stuff.
the question is like this
i init a jqgrid without postData ,
and set hiddengrid:true,
i want to init table at first with no request,
then will request data by hand,
js
var showRoleList = function($entityList,pagerId)
{
$entityList.jqGrid({
url:'servlet/RoleAction',
datatype: 'json',
height: 'auto',
jsonReader:
{
repeatitems : false,
userdata: "rows"
},
colNames:['ID','roleName','detail','action'],
colModel:
[
{name:'id',index:'id',hidden:true},
{name:'name',index:'name', width:100,sortable:false},
{name:'description',index:'description', width:400,sortable:false},
{name:'action',index:'action', width:40,sortable:false}
],
rowNum:10,
altRows:true,
autowidth:true,
mtype: "POST",
rownumbers: true,
rownumWidth: 30,
imgpath:'css/images',
sortorder:'desc',
viewrecords: true,
multiselect:true,
loadui:'disable' ,
gridview:true,
hiddengrid:true,
page:1,
pginput:true,
pager: pagerId,
sortname: 'dateEntered',
altclass:'ui-priority-secondary_1',
});
}
showRoleList($("#entityList0"),"#pEntityList0");
**$entityList0.jqGrid("setGridParam", {
postData:{ACTION:'userRelation',userId:user.id,typeName:'role',flag:true},
});**
**$entityList0.trigger("reloadGrid", [{page:1}]);**
html:
<table id="entityList0"></table>
<div id="pEntityList0"></div>
but failed
when i called trigger, request can be sent,but without postData
no param can post to server
but if i click refresh button it can work
how can i resolve this question
thank you for you answer
I can't reproduce your problem. The only clear syntax error is flag:true},}) muss be replaced to flag:true}}) (remove comma). In the same way you should replace altclass:'ui-priority-secondary_1',} to altclass:'ui-priority-secondary_1'}.
Is all the code inside of $(document).ready(function() {/*here*/});?
In the code variables user and $entityList0 are not initialized. Are you sure, that use set $entityList0=$("#entityList0") and initialize user at least as {} in the code above?
You should also remove deprecated imgpath parameter and replace sortname: 'dateEntered' to sortname: 'name' for example.
If you post any test data which you use I could give you url to the code which you posted and which work at me without any problem.
UPDATED: OK! Now having the code which one can test I see where your problem is. The problem is that you try to start the second ajax request before the first one is ended.
Your grid has datatype: 'json'. In the line showRoleList($entityList0,'#pEntityList0'); you start the first ajax request and then immediately start the second one with respect of $entityList0.trigger("reloadGrid"). The first request set internal variable $("#entityList0")[0].grid.hDiv.loading to true and all other requests which you start will be just ignored till the timeout or the response or error returned from the server.
Probably you not really want to send the first request till you set the postData parameters. So you should use datatype: 'local' at the initialization time of jqGrid (in the showRoleList function). Then you should set datatype: 'json' additionally to the postData:
$entityList0.jqGrid(
"setGridParam",
{
datatype: 'json',
postData: {
ACTION:'userRelation',
userId:'1111',
typeName:'role',
flag:true
}
}
);
Alternative you will need to abort the previous ajax call before reloading of the grid. If it is really needed I could explain how you can implement this.
ok i just make a test.html
<html ...
<script type="text/javascript">
var $entityList0;
$(function(){
$entityList0 = $("#entityList0");
showRoleList($entityList0,'#pEntityList0');
$entityList0.jqGrid("navGrid",'#pEntityList0',{});
$entityList0.jqGrid("setGridParam",
{
postData:{ACTION:'userRelation',userId:'1111',typeName:'role',flag:true}
}).showCol("action");
$entityList0.trigger("reloadGrid");
});
var showRoleList = function($entityList,pagerId) {
$entityList.jqGrid({
url:'servlet/RoleAction',
datatype: 'json', height: 'auto',
jsonReader: {
repeatitems : false,
userdata: "rows"
},
colNames:['ID','roleName','detail','actiokn'],
colModel:
[
{name:'id',index:'id',hidden:true},
{name:'name',index:'name', width:100,sortable:false},
{name:'description',index:'description',
width:400,sortable:false},
{name:'action',index:'action',
width:40,sortable:false}
],
rowNum:10,
altRows:true,
autowidth:true,
mtype: "POST",
rownumbers: true, rownumWidth: 30,
//imgpath:'css/images',
sortorder:'desc',
viewrecords: true,
multiselect:true,
loadui:'disable' ,
gridview:true,
hiddengrid:true,
page:1,
pginput:true,
pager: pagerId,
sortname: 'dateEntered', altclass:'ui-priority-secondary_1',
}); } </script>
</head>
<body>
<table id="entityList0"></table>
<div id="pEntityList0"></div>
</body>
</html>
when the first time open the url test.html
HeadersPostPutHTMLXML
application/x-www-form-urlencoded
_search false
nd 1300458295847
page 1
rows 10
sidx dateEntered
sord desc
_search=false&nd=1300458295847&rows=10&page=1&sidx=dateEntered&sord=desc
an then i click refresh button
HeadersPostPutHTML
application/x-www-form-urlencoded
ACTION userRelation
_search false
flag true
nd 1300458310960
page 1
rows 10
sidx dateEntered
sord desc
typeName role
userId 1111
_search=false&nd=1300458310960&rows=10&page=1&sidx=dateEntered&sord=desc&ACTION=userRelation&userId=1111&typeName=role&flag=true
you can test it
you can see the result is different
this is a simple page ,you can test easily ! if you can find something wrong please tell me thank you