Related
I have received as a assignment create 2 applications, one optimized and one unoptimized and i am using free jqGrid to display the data from DB.
I have successfully created both but i would like to track the speed at witch the local operations are done(paging,search,sorting).
I have tried to set up events for each button that triggers the operations, but they dont seem to trigger... i was wondering if there is something better that is built into jqGrid that i could use or a advice that would help me resolve this.
My jqGrid code goes like this:
$(function () {
var colModelSettings = [
{name:'id', label:'id',key: true, hidden: true, width:10,sorttype:'number',editable: true},
{name:'judet',label:'Judet',width:70, align: 'center',editable:true},
{name:'localitate',label:'Localitate',width:80,editable:true,searchoptions: {sopt: ['eq','bw','ew','cn']},align: 'center'},
{name:'tipStrada',label:'tipStrada',editable:true,searchoptions: {sopt: ['eq','bw','ew','cn']},width:100,align: 'center' },
{name:'denumire',label:'denumire',editable:true,width:100,searchoptions: {sopt: ['eq','bw','ew','cn']},align: 'center'},
{name:'cod',label:'cod',width:90,editable:true,align: 'center'}
];
var beforeEvent = 0;
$("#gridAdrese").jqGrid({
pager: $("#pagerGrid"),
url: "/UnoptimizedProject/rest/fetchData",
datatype: "json",
mtype: "POST",
loadonce: true,
forceClientSorting:true,
height: window.innerHeight-250,
sortname: 'id',
ajaxGridOptions: { contentType: 'application/json; charset=utf-8' },
serializeGridData: function (postData) {
if (postData.searchField === undefined) postData.searchField = null;
if (postData.searchString === undefined) postData.searchString = null;
if (postData.searchOper === undefined) postData.searchOper = null;
return JSON.stringify(postData);
},
rowNum: 5000,
viewrecords: true,
loadComplete: function(){
if(beforeEvent !== undefined){
var afterEvent = new Date().getTime();
console.log(afterEvent- beforeEvent);
beforeEvent = 0;
}
},
sortorder: 'asc',
caption:'Coduri Postale Neoptimizat' ,
autowidth: true,
colModel: colModelSettings,
});
$("#gridAdrese").jqGrid('navGrid', "#pagerGrid", {edit:false, add:false, del:false, save:false, cancel:false, search:true, searchtext: 'Search', refresh: false});
$("#jqgh_gridAdrese_judet, #jqgh_gridAdrese_localitate, #jqgh_gridAdrese_tipStrada, #jqgh_gridAdrese_denumire, #jqgh_gridAdrese_cod ").on("click",function(){
beforeEvent = new Date().getTime();
console.log("Sorting");
})
$("#fbox_gridAdrese_search").on("click",function(){
beforeEvent = new Date().getTime();
console.log("searching");
});
$("#next_pagerGrid , #last_pagerGrid, #prev_pagerGrid, #first_pagerGrid").on("click",function(){
beforeEvent = new Date().getTime();
console.log("paging");
})
});
You can do about the following:
var startTime, measureTime = false, timeInterval,
startMesure = function () {
startTime = new Date();
measureTime = true;
};
startMesure();
$("#gridAdrese").jqGrid({
url: "/UnoptimizedProject/rest/fetchData",
...
onSortCol: function () {
startMesure();
},
onPaging: function (pgButton, options) {
//if (pgButton === "records") {
startMesure();
//}
},
searching: {
closeAfterSearch: true,
closeAfterReset: true,
closeOnEscape: true,
searchOnEnter: true,
beforeSearch: function () {
startMesure();
return false; // allow filtering
},
onSearch: function () {
startMesure();
},
onReset: function () {
startMesure();
},
},
loadComplete: function () {
if (measureTime) {
timeInterval = new Date() - startTime;
setTimeout(function () {
alert("Total loading time: " + timeInterval + "ms\nFull time: " +
(new Date() - startTime));
}, 50);
measureTime = false;
}
}
}).jqGrid("filterToolbar").jqGrid("navGrid");
We reset startTime with respect of startTime = new Date(); to the current time at the beginning of sorting, paging or filtering.
I would like capture the colModel for my jqGrid when the page unloads and store it in session so the next time the user comes to the page it can be loaded automatically. But, the information returned by ('#contract_grid').getGridParam('colModel') is missing part or all of the information in searchoptions for the grid columns.
Any idea why this is or how to capture the full colModel? The grid works great on the initial load but without the other searchoptions params, the filter bar features/menus don't work when I refresh the page from the colModel stored in session.
Create the default colModel for the grid
var defaultColModel =
[
{name:'REQUESTID'
,index:'requestID'
,label:'Request ID'
,search:true
,stype:'text'
,width:75
,key:true
,hidden:false
},
{name:'REQUESTEDDATE'
,index:'requestedDate'
,label:'Request Date'
,sorttype:"date"
,search:true
,width:50
,searchoptions:{
dataInit:function(el){jQuery(el).daterangepicker(
{
arrows:false
, dateFormat:'yy-mm-dd'
, onClose: function(dateText, inst){ jQuery("#contract_grid")[0].triggerToolbar();}
, onOpen: function() {
jQuery('div.ui-daterangepickercontain').css({"top": jQuery('#mouseY').val() + 'px', "left": jQuery('#mouseX').val() + 'px' });
}
});
}
}
,hidden:false
},
{name:'BUSINESSOWNERPERSONID'
,index:'businessOwnerPersonID'
,label:'Business Owner'
,search:true
,stype:'select'
,width:100
,hidden:false
,searchoptions: {
dataUrl: 'cfc/com_common.cfc?method=getAjxPeople&role=businessOwnerPersonID',
buildSelect: function(resp) {
var sel= '<select><option value=""></option><option value="7583,1636">My Reports</option>';
var obj = $.parseJSON(resp);
$.each(obj, function() {
sel += '<option value="'+this['lk_value']+ '">'+this['lk_option'] + "</option>"; // label and value are returned from Java layer
});
sel += '</select>';
return sel;
},
dataEvents: [{
type: 'change',
fn: function(e) {
alert(this.value)
}
}]
}
}
];
When user navigates away from page, save the grid to session so it loads when they come back
$(window).on('beforeunload', function(){
takeSnapshot();
});
function takeSnapshot(){
var gridInfo = new Object();
gridInfo.colModel = jQuery('#contract_grid').getGridParam('colModel');
gridInfo.postData = jQuery('#contract_grid').jqGrid('getGridParam', 'postData');
var snapshotData = JSON.stringify(gridInfo);
$.ajax({
url: "actions/act_filter.cfc?method=takeSnapshot",
type: "POST",
async: false,
data: {gridName:'contract_grid'
,gridParamName:'contractGridParams'
,filterData:snapshotData
}
});
}
Create grid variable
var myGrid = jQuery("#contract_grid").jqGrid({
url: 'cfc/com_ajxRequestNew.cfc?method=getReqJSON&returnformat=json',
datatype: 'json',
postData: {filters: myFilters},
mtype: 'POST',
search: true,
colModel: defaultColModel,
altRows: true,
emptyrecords: 'NO CONTRACTS FOUND',
height: 400,
width: 1200,
sortname: lastSortName,
sortorder: lastSortOrder,
page: lastPage,
pager: jQuery('#report_pager'),
rowNum: lastRowNum,
rowList: [10,20,50,100],
viewrecords: true,
clearSearch: false,
caption: "Contracts Dashboard",
sortable: true,
shrinkToFit: false,
ajaxSelectOptions: {type: "GET"},
gridComplete: function() {
//set the selected toolbar filter values
var myFields = JSON.parse(myFilters);
//set fields in form at top. filter contains index value so get corresponding name value because its used in the column label #gs
if ( myFields['rules'].length > 0 ) {
for (var i=0; i < myFields['rules'].length; i++ ) {
$.each(defaultColModel, function(j) {
if(this.index == myFields['rules'][i]['field'] ) {
thisFieldName = this.name;
jQuery('#gs_' + thisFieldName).val( myFields['rules'][i]['data'] );
}
})
}
}
}
});
jQuery("#contract_grid").navGrid('#report_pager',{
edit:false,
add:false,
del:false,
search:false,
refresh:false
}).navButtonAdd("#report_pager",{ caption:"Clear",title:"Clear Filters", buttonicon :'ui-icon-trash',
onClickButton: function() {
jQuery.ajax({
url: "/assets/js/ajx_clearFilter.cfm?showHeader=0",
async: false,
type: "POST",
data: ({variableName:'session.contractGridParams'})
});
myGrid[0].clearToolbar();
}
}).navButtonAdd("#report_pager",{ caption:"Restore",title:"Restore Default Grid Columns and Filters", buttonicon :'ui-icon-refresh',
onClickButton: function() {
window.location = '?page=dsp_requestListingNew&clearSession=1';
}
}).navButtonAdd("#report_pager",{
caption: "Export",
title: "Export to Excel",
buttonicon :'ui-icon-document',
onClickButton: function(e){
jQuery("#contract_grid").jqGrid('excelExport',{url:'includes/act_requestListingExport.cfm'});
}
}).navButtonAdd("#report_pager",{
caption: "Columns",
buttonicon: "ui-icon-calculator",
title: "Select and Reorder Columns",
jqModal: true,
onClickButton: function(e){
$('#contract_grid').jqGrid('columnChooser', {
dialog_opts: {
modal: true,
minWidth: 470,
show: 'blind',
hide: 'explode'
}
});
}
}).navButtonAdd("#report_pager",{
caption: "Save",
title: "Save Snapshot",
buttonicon :'ui-icon-disk',
onClickButton: function(e){
takeSnapshot(0);
$('#fltrFrmLink').click();
}
});
jQuery("#contract_grid").jqGrid('filterToolbar', {
stringResult : true
, searchOnEnter : true
, autoSearch : true
, beforeClear : function() {
//set sortnames
var sn = jQuery("#contract_grid").jqGrid('getGridParam','sortname');
//set sort orders
var so = jQuery("#contract_grid").jqGrid('getGridParam','sortorder');
so = "desc";
//set grid params
jQuery("#contract_grid").jqGrid('setGridParam',{ sortorder:so, sortname:sn });
}
});
colModel returned by ('#contract_grid').getGridParam('colModel') on unload. searchoptions is missing everything for REQUESTEDDATE. Part of dataEvents and all of buildSelect are missing for BUSINESSOWNERPERSONID.
[{"name":"REQUESTID",
"index":"requestID",
"label":"Request ID",
"search":true,
"stype":"text",
"width":75,
"key":true,
"hidden":false,
"title":true,"lso":"",
"widthOrg":75,"resizable":true,"sortable":true},
{"name":"REQUESTEDDATE",
"index":"requestedDate",
"label":"Request Date",
"sorttype":"date",
"search":true,
"width":50,
"searchoptions:{},
"hidden":false,
"title":true,
"lso":"",
"widthOrg":50,
"resizable":true,
"sortable":true,"stype":"text"},
{"name":"BUSINESSOWNERPERSONID",
"index":"businessOwnerPersonID",
"label":"Business Owner",
"search":true,
"stype":"select",
"width":100,"hidden":false,
"searchoptions":{"dataUrl":"cfc/com_common.cfc?method=getAjxPeople&role=businessOwnerPersonID",
"dataEvents":[{"type":"change"}]},
"title":true,
"lso":"",
"widthOrg":100,
"resizable":true,
"sortable":true}]
JSON don't support serialization of functions. So the functions from searchoptions.dataInit, searchoptions.buildSelect and all other which you use in colModel will be discarded after you use JSON.stringify.
It's important to know which version of jqGrid/free jqGrid or Guriddo jqGrid JS you use. Starting with jqGrid 4.7 one can define template in colModel with string value (see the pull request). In the way you will have the main information in colModel which can be serialized using JSON.stringify.
I am running into problem, where when an Insert is completed successfully and if i continue to insert another row, in the next insert it is also sending the row that was inserted successfully earlier, so it goes like this.
On the First insert that row is posted back to webAPI and inserted successfully.
On Next Insert Two rows are sent one of them was from first step.
On third Insert it send previous two rows as well as third row and so on.
What could be the cause of this ?
This is the Code in problem.
$(document).ready(function () {
try {
var degreeYearsArray = new Array();
function GetDegreeName(dgID, degreeName) {
for (var i = 0; i < degreeYearsArray.length; i++) {
if (degreeYearsArray[i].dgID_PK == dgID) {
return degreeYearsArray[i].Name;
}
}
return degreeName;
}
var degreeYearModel = {
id: "DGYR_PK",
fields: {
DGID_FK: {
type: "number",
nullable: false,
editable: false
},
Code: {
type: "string",
validation: {
required: true,
minlength: 2,
maxlength: 160
}
},
Year: {
type: "number",
validation: {
required: true
}
},
EffectiveDate: {
type: "date",
validation: true
},
TerminationDate: {
type: "date",
validation: true
}
}
};
var baseURL = "http://localhost:3103/api/Degree";
var degreeYearTransport = {
create: {
url: baseURL + "/PostDegreeYears", // "/PutOrgSchool",
type: "POST",
// contentType: "application/json"
dataType: "json"
},
read: {
url: function () {
var newURL = "";
if (window.SelectedDegree == null)
newURL = baseURL + "/GetDegreeYears"
else
newURL = baseURL + "/GetDegreeYears?degreeID=" + window.SelectedDegree.DGID_PK;
return newURL;
},
dataType: "json" // <-- The default was "jsonp"
},
update: {
url: baseURL + "/PutDegreeYears", //"/PostOrgSchool",
type: "PUT",
// contentType: "application/json",
dataType: "json"
},
destroy: {
url: function (employee) {
return baseURL + "/deleteOrg" + employee.Id
},
type: "DELETE",
dataType: "json",
contentType: "application/json"
},
parameterMap: function (options, operation) {
try {
if (operation != "read") {
options.EffectiveDate = moment(options.EffectiveDate).format("MM-DD-YYYY");
options.TerminationDate = moment(options.TerminationDate).format("MM-DD-YYYY")
}
var paramMap = kendo.data.transports.odata.parameterMap(options);
delete paramMap.$format; // <-- remove format parameter.
return paramMap;
} catch (e) {
console.error("Error occure in parameter Map or Degree.js" + e.message);
}
}
}; //transport
var dsDegreeYears = new kendo.data.DataSource({
serverFiltering: true, // <-- Do filtering server-side
serverPaging: true, // <-- Do paging server-side
pageSize: 2,
transport: degreeYearTransport,
requestEnd: function (e) {
try {
if (e.type == "update"){
$.pnotify({
title: 'Update Sucessful',
text: 'Record was Updated Successfully',
type: 'success'
});
}
if (e.type == "create") {
$.pnotify({
title: 'Insert Sucessful',
text: 'Record was Inserted Successfully',
type: 'success'
});
}
} catch (e) {
console.error("error occured in requestEnd of dsDegreeYears datasource in DegreeYears.js" + e.message);
}
},
schema: {
data: function (data) {
return data.Items; // <-- The result is just the data, it doesn't need to be unpacked.
},
total: function (data) {
return data.Count; // <-- The total items count is the data length, there is no .Count to unpack.
},
model: degreeYearModel
}, //schema
error: function (e) {
var dialog = $('<div></div>').css({ height: "350px", overflow: "auto" }).html(e.xhr.responseText).kendoWindow({
height: "300px",
modal: true,
title: "Error",
visible: false,
width: "600px"
});
dialog.data("kendoWindow").center().open();
},
});
$("#" + gridName).kendoGrid({
dataSource: dsDegreeYears,
autoBind: false,
groupable: true,
sortable: true,
selectable: true,
filterable: true,
reorderable: true,
resizable: true,
columnMenu: true,
height: 430,
editable: "inline",
toolbar: ["create"],
pageable: {
refresh: true,
pageSizes: true,
buttonCount: 5
},
columns: [ {
field: "DGID_FK",
title: "Degree Name",
width: 140,
template: function (dataItem) {
if (window.SelectedDegree != null) {
dataItem.DGID_FK = window.SelectedDegree.DGID_PK;
return window.SelectedDegree.Name;
}
else
return "";
}
},
{
field: "Code",
title: "Code",
width: 140
},
{
field: "Year",
title: "Year",
width: 140
},
{
field: "Description",
width: 110
},
{
field: "EffectiveDate",
width: 110,
format: "{0:MM/dd/yyyy}"
},
{
field: "TerminationDate",
width: 110,
format: "{0:MM/dd/yyyy}"
},
{
command: ["edit"] , title: " ", width: "172px"
}
]
}); //grid
//Hide history pull-down menu in the top corner
$.pnotify.defaults.history = false;
$.pnotify.defaults.styling = "bootstrap";
// styling: 'bootstrap'
//styling: 'jqueryui'
} catch (e) {
console.error("Error occured in DegreeYears" + e.message);
}
}); // document
This is the Response that is sent from WebAPI
{"$id":"1","DGYR_PK":27,"DGID_FK":64,"Year":4,"Code":"4THYR","EffectiveDate":"2014-01-11T00:00:00","TerminationDate":"2014-01-11T00:00:00","CreatedByUserID_FK":1,"DateCreated":"0001-01-01T00:00:00","UpdatedByUserID_FK":1,"DateUpdated":"0001-01-01T00:00:00","RowStatusID_FK":1,"Degree":null,"DegreeYearExamSchedules":[],"User":null,"RowStatu":null,"User1":null,"DegreeYearSubjects":[]}
So i do see i am returning ID as suggested by the users in response to the question.
still wondering
After you have inserted a record, you need to return the id of that row, otherwise grid consider the previous row as a new row too.
In your create function you call the web API
baseURL + "/PostDegreeYears", // "/PutOrgSchool",
In the server side consider the below code.
public void Create(ABSModel model)
{
try
{
using (context = new Pinc_DBEntities())
{
tblAB tb = new tblAB();
tb.ABS = model.ABS;
tb.AreaFacility = model.AreaFacility;
context.tblABS.Add(tb);
Save();
model.ABSID = tb.ABSID;//this is the important line of code, you are returning the just inserted record's id (primary key) back to the kendo grid after successfully saving the record to the database.
}
}
catch (Exception ex)
{
throw ex;
}
}
please adjust the above example according to your requirement.
This will happen if you don't return the "DGYR_PK" value of the newly inserted model. The data source needs a model instance to have its "id" field set in order not to consider it "new". When you return the "ID" as a response of the "create" operation the data source will work properly.
You can check this example for fully working Web API CRUD: https://github.com/telerik/kendo-examples-asp-net/tree/master/grid-webapi-crud
Here is the relevant code:
public HttpResponseMessage Post(Product product)
{
if (ModelState.IsValid)
{
db.Products.AddObject(product);
db.SaveChanges();
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.Created, product);
response.Headers.Location = new Uri(Url.Link("DefaultApi", new { id = product.ProductID }));
return response;
}
else
{
return Request.CreateResponse(HttpStatusCode.BadRequest);
}
}
Your primary key cannot be 0 or null. If you are using auto-incrementing values then you should invoke the "re-read" of your dataSource after post. Check the values and make sure your data values are >0. Note: I have set the default value of the PK in the model to -1 in the column model to help with this.
You can attached and respond to the requestEnd event on the DataSource.
requestEnd: function(e) {
if (e.type === "create") {
this.read();
}
}
What that is saying is: "After you created a record, reread the entries (including the newly created one) into the grid". Thereby giving you the newly created entry with key and all. Of course you see that the extra read may have some performance issue.
I am using "inlineNav" for my jqgrid. It has all the required features for Addition, edit, Cancel add. but cant find anything for deletion. I tried using "navGrid" delete but then that gives error "error Status: 'Not Found'. Error code: 404".
So can something be done about it?
#Oleg I am counting for your help!!
Following your suggestion I created this code but it is not working!! Can you tell me what went wrong:
var jsonData;
var jsonData1;
var dropdownVal;
function createDataStructure()
{
var mData;
if (document.forms[0].gridData.value == "" )
"";
else
mData = document.forms[0].gridData.value
jsonData = {
"rows": [ mData ]
};
dropdownVal = "12345:Party;12346:Miscellaneous;12347:Conveyance;12348:Staff Welfare";
}
function callGrid()
{
createDataStructure();
"use strict";
var webForm = document.forms[0],
mydata = "",
grid = $("#View1"),
lastSel,
getColumnIndex = function (columnName) {
var cm = $(this).jqGrid('getGridParam', 'colModel'), i, l = cm.length;
for (i = 0; i < l; i++) {
if ((cm[i].index || cm[i].name) === columnName) {
return i; // return the colModel index
}
}
return -1;
},
onclickSubmitLocal = function (options, postdata) {
var $this = $(this),
grid_p = this.p,
idname = grid_p.prmNames.id,
grid_id = this.id,
id_in_postdata = grid_id + "_id",
rowid = postdata[id_in_postdata],
addMode = rowid === "_empty",
oldValueOfSortColumn,
new_id,
tr_par_id,
colModel = grid_p.colModel,
cmName,
iCol,
cm;
// postdata has row id property with another name. we fix it:
if (addMode) {
// generate new id
new_id = $.jgrid.randId();
while ($("#" + new_id).length !== 0) {
new_id = $.jgrid.randId();
}
postdata[idname] = String(new_id);
} else if (typeof postdata[idname] === "undefined") {
// set id property only if the property not exist
postdata[idname] = rowid;
}
delete postdata[id_in_postdata];
// prepare postdata for tree grid
if (grid_p.treeGrid === true) {
if (addMode) {
tr_par_id = grid_p.treeGridModel === 'adjacency' ? grid_p.treeReader.parent_id_field : 'parent_id';
postdata[tr_par_id] = grid_p.selrow;
}
$.each(grid_p.treeReader, function (i) {
if (postdata.hasOwnProperty(this)) {
delete postdata[this];
}
});
}
// decode data if there encoded with autoencode
if (grid_p.autoencode) {
$.each(postdata, function (n, v) {
postdata[n] = $.jgrid.htmlDecode(v); // TODO: some columns could be skipped
});
}
// save old value from the sorted column
oldValueOfSortColumn = grid_p.sortname === "" ? undefined : grid.jqGrid('getCell', rowid, grid_p.sortname);
// save the data in the grid
if (grid_p.treeGrid === true) {
if (addMode) {
$this.jqGrid("addChildNode", new_id, grid_p.selrow, postdata);
} else {
$this.jqGrid("setTreeRow", rowid, postdata);
}
} else {
if (addMode) {
// we need unformat all date fields before calling of addRowData
for (cmName in postdata) {
if (postdata.hasOwnProperty(cmName)) {
iCol = getColumnIndex.call(this, cmName);
if (iCol >= 0) {
cm = colModel[iCol];
if (cm && cm.formatter === "date") {
postdata[cmName] = $.unformat.date.call(this, postdata[cmName], cm);
}
}
}
}
$this.jqGrid("addRowData", new_id, postdata, options.addedrow);
} else {
$this.jqGrid("setRowData", rowid, postdata);
}
}
if ((addMode && options.closeAfterAdd) || (!addMode && options.closeAfterEdit)) {
// close the edit/add dialog
$.jgrid.hideModal("#editmod" + grid_id, {
gb: "#gbox_" + grid_id,
jqm: options.jqModal,
onClose: options.onClose
});
}
if (postdata[grid_p.sortname] !== oldValueOfSortColumn) {
// if the data are changed in the column by which are currently sorted
// we need resort the grid
setTimeout(function () {
$this.trigger("reloadGrid", [{current: true}]);
}, 100);
}
// !!! the most important step: skip ajax request to the server
options.processing = true;
return {};
},
editSettings = {
//recreateForm: true,
jqModal: false,
reloadAfterSubmit: false,
closeOnEscape: true,
savekey: [true, 13],
closeAfterEdit: true,
onclickSubmit: onclickSubmitLocal
},
addSettings = {
//recreateForm: true,
jqModal: false,
reloadAfterSubmit: false,
savekey: [true, 13],
closeOnEscape: true,
closeAfterAdd: true,
onclickSubmit: onclickSubmitLocal
},
delSettings = {
// because I use "local" data I don't want to send the changes to the server
// so I use "processing:true" setting and delete the row manually in onclickSubmit
onclickSubmit: function (options, rowid) {
var $this = $(this), grid_id = $.jgrid.jqID(this.id), grid_p = this.p,
newPage = grid_p.page;
// reset the value of processing option to true to
// skip the ajax request to 'clientArray'.
options.processing = true;
// delete the row
if (grid_p.treeGrid) {
$this.jqGrid("delTreeNode", rowid);
} else {
$this.jqGrid("delRowData", rowid);
}
$.jgrid.hideModal("#delmod" + grid_id, {
gb: "#gbox_" + grid_id,
jqm: options.jqModal,
onClose: options.onClose
});
if (grid_p.lastpage > 1) {// on the multipage grid reload the grid
if (grid_p.reccount === 0 && newPage === grid_p.lastpage) {
// if after deliting there are no rows on the current page
// which is the last page of the grid
newPage--; // go to the previous page
}
// reload grid to make the row from the next page visable.
$this.trigger("reloadGrid", [{page: newPage}]);
}
return true;
},
processing: true
},
initDateEdit = function (elem) {
setTimeout(function () {
$(elem).datepicker({
dateFormat: 'dd-M-yy',
//autoSize: true,
showOn: 'button',
changeYear: true,
changeMonth: true,
showButtonPanel: true,
showWeek: true
});
}, 100);
},
initDateSearch = function (elem) {
setTimeout(function () {
$(elem).datepicker({
dateFormat: 'dd-M-yy',
//autoSize: true,
//showOn: 'button', // it dosn't work in searching dialog
changeYear: true,
changeMonth: true,
showButtonPanel: true,
showWeek: true
});
}, 100);
};
grid.jqGrid({
datatype: "local",
data: jsonData.rows,
localReader: {
repeatitems: false,
id: "1"
},
colNames: ['Date','Expense Head','Amount', 'Reason','Remarks'],
colModel: [
{name:'sdate', index:'sdate', width:200, sorttype: 'date',
formatter: 'date', formatoptions: {newformat: 'd-M-Y'},
editable: true, datefmt: 'd-M-Y',
editoptions: {dataInit: initDateEdit, size: 14},
searchoptions: {dataInit: initDateSearch},
editrules: {required: true} },
{name:'expHead', index:'expHead', width:150, editable:true, sortable:true, edittype:"select", editoptions:{value:dropdownVal}, editrules: {required: true} },
{name:'expAmt', index:'expAmt', width:100, editable:true, summaryType:'sum', editrules: {required: true} },
{name:'expReason', index:'expReason', width:200, editable: true,edittype:"textarea", editoptions:{rows:"2",cols:"30"}, editrules: {required: true} },
{name:'expRemark', index:'expRemark', width:200,editable: true,edittype:"textarea", editoptions:{rows:"2",cols:"30"} }
],
loadtext: "Loading...",
sortname: 'sdate',
sortorder: 'desc',
pager: '#pView1',
caption: "Expense Table",
gridview: true,
rownumbers: true,
autoencode: true,
ignoreCase: true,
viewrecords: true,
footerrow: true,
height: "250",
editurl: 'clientArray',
beforeSelectRow: function (rowid) {
if (rowid !== lastSel) {
$(this).jqGrid('restoreRow', lastSel);
lastSel = rowid;
}
return true;
},
ondblClickRow: function (rowid, ri, ci) {
var $this = $(this), p = this.p;
if (p.selrow !== rowid) {
// prevent the row from be unselected on double-click
// the implementation is for "multiselect:false" which we use,
// but one can easy modify the code for "multiselect:true"
$this.jqGrid('setSelection', rowid);
}
$this.jqGrid('editGridRow', rowid, editSettings);
},
onSelectRow: function (id) {
if (id && id !== lastSel) {
// cancel editing of the previous selected row if it was in editing state.
// jqGrid hold intern savedRow array inside of jqGrid object,
// so it is safe to call restoreRow method with any id parameter
// if jqGrid not in editing state
if (typeof lastSel !== "undefined") {
$(this).jqGrid('restoreRow', lastSel);
}
lastSel = id;
}
},
loadComplete: function () {
var sum = grid.jqGrid('getCol', 'expAmt', false, 'sum');
grid.jqGrid('footerData','set', {ID: 'Total:', expAmt: sum});
jsonData1 = grid.jqGrid('getGridParam', 'data');
document.forms[0].gridData.value = JSON.stringify(jsonData1);
},
loadError: function (jqXHR, textStatus, errorThrown) {
alert('HTTP status code: ' + jqXHR.status + '\n' +
'textStatus: ' + textStatus + '\n' +
'errorThrown: ' + errorThrown);
alert('HTTP message body (jqXHR.responseText): ' + '\n' + jqXHR.responseText);
}
});
grid.jqGrid('navGrid', '#pView1', {}, editSettings, addSettings, delSettings, {reloadAfterSubmit:true, beforeSubmit:validate_edit}, {reloadAfterSubmit:true, beforeSubmit:validate_add}, {}, {});
}
I am not providing any data but the same will come after it has been saved in the field and will be reloaded. But when I click on Add the form opens up and when I click on Submit after entering data it just stops. So can you tell me what must be wrong with my code!
Thanks for your help you are such a savior!!!
Siddhartha
inlineNav don't support Delete button, but you can use the corresponding button from navGrid. The problem is only that navGrid add button which implemented by form editing and form editing don't support editing local grid (editurl: 'clientArray') out-of-the-box.
In the old answer I suggested one way how one can do implement delete operation in form editing. In the answer I posted even the way how form editing can be used with local data. Another answer contains updated code which work with the current version (4.4.1 and 4.4.4) of jqGrid. I recommend you to use delSettings from the answer.
jQuery.extend(
jQuery.jgrid.edit, {
ajaxEditOptions: { contentType: "application/json" }, //form editor
reloadAfterSubmit: true
// afterSubmit: function (response, postdata) {
// return [true, "", $.parseJSON(response.responseText).d];
//}
});
$.extend($.jgrid.defaults, {
datatype: 'json',
ajaxGridOptions: { contentType: "application/json" },
ajaxRowOptions: { contentType: "application/json", type: "POST" },
//row inline editing
serializeGridData: function(postData) { return JSON.stringify(postData); },
jsonReader: {
repeatitems: false,
id: "0",
cell: "",
root: function(obj) { return obj.d.rows; },
page: function(obj) { return obj.d.page; },
total: function(obj) { return obj.d.total; },
records: function(obj) { return obj.d.records; }
}
});
$("#grantlist").jqGrid({
url: 'webservice.asmx/GetGrant',
colNames: ['ID', 'Name', 'Title'],
colModel: [
{ name: 'ID', width: 60, sortable: false },
{ name: 'name', width: 210, editable: true },
{ name: 'title', width: 210, editable: true }
],
serializeRowData: function(data) {
var params = new Object();
params.ID = 0;
params.name = data.name;
params.title = data.title;
return JSON.stringify({ 'passformvalue': params, 'oper': data.oper, 'id': data.id });
},
mtype: "POST",
sortname: 'ID',
rowNum: 4,
height: 80,
pager: '#pager',
editurl: "webservice.asmx/ModifyGrant"
});
$("#grantlist").jqGrid('navGrid', '#pager', { add: false, edit: false, del: false, refresh: false, search: false });
$("#grantlist").jqGrid('inlineNav', '#pager');
//this is my server code
[WebMethod(EnableSession = true)]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public JQGrid<GrantComittee> GetGrantComittee(int? page, int? rows, string sidx, string sord, bool _search)
{
JQGrid<GrantComittee> jqgrid = new JQGrid<GrantComittee>();
List<GrantComittee> data = GetGComittee();
jqgrid.records = data.Count; //total row count
jqgrid.total = (int)Math.Ceiling((double)data.Count / (double)rows); //number of pages
jqgrid.page = page.Value;
//paging
data = data.Skip(page.Value * rows.Value - rows.Value).Take(rows.Value).ToList();
foreach(GrantComittee i in data)
jqgrid.rows.Add(i);
return jqgrid;
}
[WebMethod(EnableSession = true), ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public int ModifyGrantComittee(GrantComittee passformvalue, string oper, string id)
{
if (String.Compare(id, "_empty", StringComparison.Ordinal) == 0 ||
String.Compare(oper, "add", StringComparison.Ordinal) == 0)
{
GrantComittee data = new GrantComittee();
List<GrantComittee> set = new List<GrantComittee>();
set = (List<GrantComittee>)Session["grantcomittee"];
data = passformvalue;
data.ID = set.Max(p => p.ID) + 1;
set.Add(data);
Session["grantcomittee"] = set;
return data.ID;
}
else if (String.Compare(oper, "edit", StringComparison.Ordinal) == 0)
{
// TODO: modify the data identified by the id
return 0;
}
else if (String.Compare(oper, "del", StringComparison.Ordinal) == 0)
{
// TODO: delete the data identified by the id
return 0;
}
return 0;
}
I am using JqGrid to retrieve and add new records to database. So far i have been able to retrieve and add new items to the DB, I am using "json". I do get in the response {"d": "5"} for the id of the newly created row in the DB. However the new id does not display in the grid.
How can I update that value to new added row?
In the most cases you don't need to do anything because of default setting reloadAfterSubmit: true. It means that the full grid will be reloaded from the server after the user add new row or modify an existing one.
If you want use reloadAfterSubmit: false setting and the server returns the id of the new created row in the response you need implement afterSubmit callback function which will decode the server response and return it for the usage of by jqGrid. The corresponding code could be about the following:
afterSubmit: function (response, postdata) {
return [true, "", $.parseJSON(response.responseText).d];
}
You can define the callback by overwriting the default parameters $.jgrid.edit (see here and here).
I am using 'inlinNav' and after adding a new row i was not getting the grid to reload. The solution I found was to add parametes to the 'inlineNav' declaration. So I end up with the code i am providing as reference:
$("#grantlist").jqGrid('inlineNav', '#pager', { addParams: { position: "last", addRowParams: {
"keys": true, "aftersavefunc": function() { var grid = $("#grantlist"); reloadgrid(grid); }
}
}, editParams: { "aftersavefunc": function() { var grid = $("#grantlist"); reloadgrid(grid); } }
});
function reloadgrid(grid) {
grid.trigger("reloadGrid");
}
I was using more than one grid that is why i pass a grid parameter to the reload function.