jqGrid send edited/delete inline information serialized JSON format - javascript

I'm trying to do an inline edit with a column with formatter: 'actions' and want to send the information to the server in JSON format, but I cant. I already tried many things, but with no results. Still sending information without serializing.
Also tried $.extend($.jgrid.edit, (...)); at the initialization $(function(){...}); with no result.
My formatoptions looks like this:
formatoptions: {
keys: true,
editbutton: true,
delbutton: true,
//url: url,
editOptions: {
url: url,
ajaxEditOptions: {
//url: url,
contentType: 'application/json;charset=utf-8',
type: 'POST',
datatype: 'json'
}
},
delOptions: {
url: url,
ajaxDelOptions: {
//url: url,
contentType: 'application/json;charset=utf-8',
type: 'POST',
datatype: 'json'
}
}
}}
But still not working :S I dont know what im doing wrong.
I'd appreciate if you help me.
PS: I writted too many url properties, becuase I was checking where I have to write it to do it work. For edit, only works if I put the url out of editOptions, only if I put it in formatoptions. But for delete, it don't cares if I put it in/out delOptions, including ajaxDelOptions. If you could help me with that too, I'd appreciate.
UPDATED
Delete works fine with this config, but inline editing save button still not working. I pasted the same config, changing options for editing and still not working.
delOptions: {
url: url,
mtype: 'POST',
reloadAfterSubmit: true,
ajaxDelOptions: {
contentType: "application/json"
},
serializeDelData: function(postdata) {
return JSON.stringify(postdata);
}
}
UPDATED 2
Here is my JS.
$(function() {
$.mask.definitions['2'] = '[0-2]';
$.mask.definitions['5'] = '[0-5]';
$.extend($.jgrid.defaults, {
ajaxRowOptions: {
contentType: "application/json",
dataType: "json",
success: function() {
},
error: null
},
serializeRowData: function(data) {
delete data.oper;
return JSON.stringify(data);
}
});
});
function loadGrid(identifier) {
$("#list").jqGrid({
url: 'foo.html?identifier=' + identifier,
type: 'GET',
datatype: 'json',
repeatitems: false,
autowidth: true,
altRows: false,
hidegrid: false,
cmTemplate: {
sortable: false,
resizable: false
},
colNames: ["id", "column1", "column2", "column3", "column4", "column5", "column6", "column7", " "],
colModel: [
{name: "id", label: "id", hidden: true},
{name: "columnData1", label: "columnData1", key: true, hidden: true},
{name: "columnData2", label: "columnData2", edittype: "select", editable: true,
editoptions: {
dataUrl: 'foo/bar.html'
}},
{name: "columnData3", label: "columnData3", width: 75, editable: true},
{name: "columnData4", label: "columnData4", width: 100, edittype: "select", editable: true,
editoptions: {
dataUrl: 'foo/bar.html'
}},
{name: "columnData5", align: "right", label: "columnData5", width: 55, formatter: 'number',
formatOptions: {
decimalPlaces: 2
}, editable: true},
{name: "columnData6", align: "right", label: "columnData6", width: 55, formatter: 'number',
formatOptions: {
decimalPlaces: 2
}, editable: true},
{name: "columnData7", align: "right", label: "columnData7", width: 55, formatter: 'number',
formatOptions: {
decimalPlaces: 2
}},
{name: "actions", formatter: "actions", width: 35}
],
pager: '#pager',
rows: '',
rowList: [],
pgbuttons: false,
pgtext: null,
viewrecords: false,
gridview: true,
caption: 'MyCaption',
subGrid: true,
subGridRowExpanded: function(subgrid_id, row_id) {
var subgrid_table_id, pager_id;
subgrid_table_id = subgrid_id + "_t";
pager_id = "p_" + subgrid_table_id;
$("#" + subgrid_id).html("<table id='" + subgrid_table_id + "'></table><div id='" + pager_id + "'></div>");
$("#" + subgrid_table_id).jqGrid({
url: 'foo/bar.html?identifier=' + identifier + '&rowId=' + row_id,
type: 'GET',
datatype: 'json',
repeatitems: false,
autowidth: true,
altRows: false,
hidegrid: false,
cmTemplate: {
sortable: false,
resizable: false
},
colNames: ['column1', 'column2', 'column3', 'column4', 'column5', 'column6', ' '],
colModel: [
{name: 'columnData1', hidden: true, key: true},
{name: 'columnData2', width: 75, formatter: 'date',
formatoptions: {
srcformat: 'Y-m-d',
newformat: 'd/m/Y'
},
editoptions: {
readonly: 'readonly',
dataInit: function(elem) {
$(elem).width("75%");
$(elem).datepicker({
dateFormat: "dd/mm/yy",
showOn: "button",
buttonImage: "../css/images/calendar.gif",
buttonText: "Muestra el calendario.",
buttonImageOnly: true
});
}}
, editable: true},
{name: 'columnData3', width: 75,
formatter: function(cellval, opts) {
if (!/^([0-1][0-9]|2[0-3]:[0-5][0-9])/.test(cellval)) {
var date = new Date(cellval);
opts = $.extend({}, $.jgrid.formatter.date, opts);
return $.fmatter.util.DateFormat("", date, 'H:i', opts);
} else {
var date = new Date();
var time = cellval.split(":");
date.setFullYear(1899);
date.setMonth(12);
date.setDate(30);
date.setHours(time[0]);
date.setMinutes(time[1]);
date.setSeconds(0);
opts = $.extend({}, $.jgrid.formatter.date, opts);
return $.fmatter.util.DateFormat("", date, 'H:i', opts);
}
},
editoptions: {dataInit: function(elem) {
$(elem).mask("29:59");
}},
editrules: {custom: true, custom_func: function(value) {
if (/^([0-1][0-9]|2[0-3]:[0-5][0-9])/.test(value)) {
return [true, ""];
} else {
return [false, " no es un formato de hora válido.<br/>Por favor, introduzca una hora en un formato <b>hh:mm</b> válido."];
}
}}, editable: true},
{name: 'columnData4', width: 80, editable: true},
{name: 'columnData5', width: 200, editable: true},
{name: 'columnData6', align: 'right', width: 50, editable: true, formatter: 'number',
formatoptions: {
decimalPlaces: 2
}},
{name: 'actions', formatter: 'actions', width: 40,
formatoptions: {
//keys: false,
editbutton: true,
delbutton: true,
url: "foo/bar/edit.html?identifier=" + identifier + "&rowId=" + row_id,
editOptions: {
keys: true,
//url: "foo/bar/edit.html?identifier=" + identifier + "&rowId=" + row_id,
mtype: "POST"
},
delOptions: {
url: "foo/bar/delete.html?identifier=" + identifier + "&rowId=" + row_id,
mtype: 'POST',
reloadAfterSubmit: true,
ajaxDelOptions: {
contentType: "application/json"
},
serializeDelData: function(postdata) {
delete postdata.oper;
return JSON.stringify(postdata);
}
}
}}
],
height: 190,
pager: pager_id,
rows: '',
rowList: [],
pgbuttons: false,
pgtext: null,
viewrecords: false,
gridview: true,
loadError: function(xhr, status, error) {
alert(xhr + " : " + status + " : " + error);
},
jsonReader: {
repeatitems: false
},
gridComplete: function() {
$("div.ui-inline-save").click(function() {
var dlgDiv = $("#info_dialog");
dlgDiv.width(600);
var parentDiv = dlgDiv.parent();
var dlgWidth = dlgDiv.width();
var parentWidth = parentDiv.width();
var dlgHeight = dlgDiv.height();
var parentHeight = parentDiv.height();
dlgDiv.css('top', Math.round((parentHeight - dlgHeight) / 2));
dlgDiv.css('left', Math.round((parentWidth - dlgWidth) / 2));
});
$("div.ui-inline-del").click(function() {
var dlgDiv = $("#delmod" + subgrid_table_id);
dlgDiv.width(600);
var parentDiv = dlgDiv.parent();
var dlgWidth = dlgDiv.width();
var parentWidth = parentDiv.width();
var dlgHeight = dlgDiv.height();
var parentHeight = parentDiv.height();
dlgDiv.css('top', Math.round((parentHeight - dlgHeight) / 2));
dlgDiv.css('left', Math.round((parentWidth - dlgWidth) / 2));
});
$("#gbox_" + subgrid_id + "_t").removeClass('ui-corner-all');
$("#" + pager_id).removeClass('ui-corner-bottom');
disableSelection(document.getElementById(subgrid_table_id));
}
}).navGrid("#" + pager_id, {add: true, edit: false, del: false, search: false, view: false, refresh: true}, {},
{afterShowForm: function(form) {
var dlgDiv = $("#editmod" + subgrid_table_id);
dlgDiv.width(600);
var parentDiv = dlgDiv.parent();
var dlgWidth = dlgDiv.width();
var parentWidth = parentDiv.width();
var dlgHeight = dlgDiv.height();
var parentHeight = parentDiv.height();
dlgDiv.css('top', Math.round((parentHeight - dlgHeight) / 2));
dlgDiv.css('left', Math.round((parentWidth - dlgWidth) / 2));
}
});
},
loadError: function(xhr, status, error) {
alert(xhr + " : " + status + " : " + error);
},
jsonReader: {
repeatitems: false
},
gridComplete: function() {
$("div.ui-inline-save").click(function() {
var dlgDiv = $("#info_dialog");
dlgDiv.width(600);
var parentDiv = dlgDiv.parent();
var dlgWidth = dlgDiv.width();
var parentWidth = parentDiv.width();
var dlgHeight = dlgDiv.height();
var parentHeight = parentDiv.height();
dlgDiv.css('top', Math.round((parentHeight - dlgHeight) / 2));
dlgDiv.css('left', Math.round((parentWidth - dlgWidth) / 2));
});
$("div.ui-inline-del").click(function() {
var dlgDiv = $("#delmodlist");
dlgDiv.width(600);
var parentDiv = dlgDiv.parent();
var dlgWidth = dlgDiv.width();
var parentWidth = parentDiv.width();
var dlgHeight = dlgDiv.height();
var parentHeight = parentDiv.height();
dlgDiv.css('top', Math.round((parentHeight - dlgHeight) / 2));
dlgDiv.css('left', Math.round((parentWidth - dlgWidth) / 2));
});
disableSelection(document.getElementById("list"));
}
}).navGrid("#pager", {add: true, edit: false, del: false, search: false, view: false, refresh: true}, {},
{afterShowForm: function(form) {
var dlgDiv = $("#editmodlist");
dlgDiv.width(600);
var parentDiv = dlgDiv.parent();
var dlgWidth = dlgDiv.width();
var parentWidth = parentDiv.width();
var dlgHeight = dlgDiv.height();
var parentHeight = parentDiv.height();
dlgDiv.css('top', Math.round((parentHeight - dlgHeight) / 2));
dlgDiv.css('left', Math.round((parentWidth - dlgWidth) / 2));
}
});
var height = $("body").height();
$('.ui-jqgrid-bdiv').height(height);
}
Changed column names, etc. for security (obviusly). This is my JS. I had to use jqGrid in a function and getting identifier as parameter, because I have a JSP that is loaded into a Iframe and that JSP has another Iframe that loads this JS. I needed to send the identifier that I recieve in the JSP to build the grid. The best way I found is that.
Thats the identifier value.
Also, I need that identifier and the row_id to update data, because I have as 3 primary keys to identify an specific item. I need identifier, parent row_id and actual row_id that I'm editing. Last one I get it from the JS Object in JSON format.
It's like it does not recognize editOptions property, because it does not get keys: true. It didn't let me accept the edit with Enter key.
If you still needing more information, just ask.

I think that the origin of your problem is misunderstanding about how formatter: 'actions' works.
There are tree main editing mode supported by jqGrid: inline editing, form editing and cell editing. If you don't use editformbutton: true option of formatter: 'actions' inside of formatoptions then Edit button will use inline editing. Delete button uses always form editing because there are no delete method in the inline editing module.
So if you includes some option inside of editOptions of formatoptions of formatter: 'actions' then it should be an option of editRow (see properties of editparameters object in the documentation). So you can specify for example
editOptions: {
url: url,
mtype: "POST", // is already default and can be removed
keys: true
}
but the ajaxEditOptions will be ignored here. $.jgrid.edit can be used to change default values for editGridRow which is part of forme editing, but to change defaults of editRow you need use $.jgrid.inlineEdit instead.
delOptions allows you specify parameters of delGridRow. The UPDATED part of your question uses correct options. So Delete operation works correctly.
By the way you can use editurl option of jqGrid to specify URL used for both inline editing and form editing. So editurl: url on one place will be better as specifying url: url multiple times.
What you need to do for successful editing is adding ajaxRowOptions and serializeRowData as jqGrid options
ajaxRowOptions: { contentType: "application/json", dataType: "json" },
serializeRowData: function (data) { return JSON.stringify(data); }
or to set it in $.jgrid.defaults.
UPDATED: You misunderstand the value of unique id. HTML standard don't allows to have two elements with the same id attribute on the page. The demo which you posed don't use idPrefix in subgrids. If you opens subgrids for who rows and examine HTML code of the page with respect of Developer Tools (press F12 in IE) you will see the following
So you have to use idPrefix for subgrids. I recommend you to use the value which depends on rowid of the parent grid (something like idPrefix: "s_" + row_id + "_"). Look at here for more my answer about the subject.
UPDATED 2: I looked in the code of formatter: "actions" one more time and I see that it uses url option of formatter for inline editing operations (see the documentation) and uses delOptions for delete and editOptions for form editing. So editOptions.url will be used only if you would use editformbutton: true option.

Related

How to set grid post param dynamically and trigger reload with the new URL?

I have the following jQgrid Free (version: 4.15.2) definition:
$(document).ready(function () {
var $load_form = $("#load_form"),
$form_id = sessionStorage.getItem('form_id') === null ? 1 : sessionStorage.form_id,
$questions_grid = $("#questions");
$(document).on("click", $load_form, function (ev) {
// get the new form_id value and reload the grid by passing
// the new form_id as post parameter for the AJAX request
});
$questions_grid.jqGrid({
url: '/ajax/questions/get/' + $form_id,
datatype: "json",
colNames: ['id', 'grid_id', 'seq', 'type', 'text'],
colModel: [
{name: 'field_id', index: 'id', width: 100, editable: false, editoptions: {readonly: true, size: 10}},
{name: 'grid_id', index: 'grid_id', width: 50, editable: false, editoptions: {readonly: true, size: 10}},
{name: 'field_seq', index: 'seq', width: 45, editable: true, editoptions: {size: 10}},
{name: 'type', index: 'type', width: 125, editable: false, editoptions: {readonly: true, size: 10}},
{
name: 'field_name',
index: 'text',
width: 585,
editable: true,
edittype: "textarea",
editoptions: {rows: "5", cols: "45"}
}
],
autowidth: true,
iconSet: "fontAwesome",
rowNum: 100,
guiStyle: "bootstrap",
pager: 'questions_pager',
pgbuttons: false,
pginput: false,
sortname: 'seq',
viewrecords: true,
caption: "Questions",
width: 100,
height: "auto",
editurl: 'ajax/questions/edit',
multiselect: true,
subGrid: false,
subGridUrl: 'ajax/questions/get_options',
subGridModel: [{name: ['id', 'text', 'is required'], width: [55, 200, 20]}],
gridComplete: function () {
// Don't need the +1 because it includes ".jqgfirstrow"
var seq_number = this.rows.length;
$("#next_seq_num").val(seq_number);
$("#field_seq").empty();
$("#grid_field_seq").empty();
for (var i = 1; i <= seq_number; i++) {
var sel = (i == seq_number) ? 'selected' : null;
$("#field_seq").append("<option " + sel + ">" + i + "</option>");
$("#grid_field_seq").append("<option " + sel + ">" + i + "</option>");
}
$(window).trigger('resize');
},
onSelectRow: function (ids) {
if (ids !== null) {
$("#option_field_id").val(ids);
$(".field_seq_section").hide();
$.ajax({
type: "POST",
url: "ajax/questions/get_grid_example/" + ids,
success: function (msg) {
if (msg !== "") {
jQuery('#options_ids').empty();
}
jQuery('#grid_cells_example').html(msg);
}
});
edit_question("<?php echo site_url('ajax/questions/get_by_id') ?>/" + ids, false);
}
}
}).jqGrid('hideCol', 'cb');
});
At some point and dynamically I am setting the value of the property data-formid for $("#load_form"). Since $("#load_form") is a button (see definition below) I would like to trigger the reloadGrid event using the new $formid value so I get a new fresh data from the DB.
<button type="submit" class="btn btn-default" data-formid="" id="load_form">
Load form
</button>
In a few logical steps:
Set the value for data-formid
Click on the button
Trigger reloadGrid with $("#load_form").data("formid")
I have found this: how to set postData in jqgrid AFTER it has been constructed? but I am not sure how to apply on my scenerio.
How I can achieve this?
If I understand you correctly you want to change url parameter. The code of the click-event handler could be close to the following:
$(document).on("click", $load_form, function (ev) {
var p = $questions_grid.jqGrid("getGridParam");
p.url = "/ajax/questions/get/" + $("#load_form").data("formid");
$questions_grid.trigger("reloadGrid");
});

jqGrid FilterToolbar with mostly working daterange picker

I am using the free jqGrid v4.12.1. (Can't post links to fiddle yet so code follows post)
The primary issue is that we are trying to do all searching/filtering with the filterToolbar. Oleg had helped a few weeks back push just dates to the search modal, but the requirement has changed to get a date range picker working in the filterToolbar. We are mostly there. Using Dan Grossman's bootstrap daterange picker and calling a custom function, it works like a charm.
Entering DateRangeFirst
The problem originally came in to play when you would select another value like an invoice amount. It would then override the date range and give all values "ge" to the start date. So it was seeing the beginning date of the string. To circumvent this, I called the invoiceDateSearch function again in beforeSearch. This way it ran the function again and recognized the start date and end dates along with the new value we are asking for.
The thing that happens now is that if I put any other value in first and then select a daterange, the daterange won't fire until I key some other search criteria and back it out.
AnyOther value first
It doesn't even recognize the date range was entered yet, when clearly it is there. triggerToolbar, reload grid is called in the function for the invoice date search.
When using beforeSearch, keeps the date range as a date range and not a string...regardless of how often the toolbar is triggered and values are backed out of any other fields, which is great. The downside to it is if a user puts a value other than the date range FIRST, the date range doesn't work...unless a subsequent field is entered. Not using it, converts the date range to a string after the first time it is used and any other values entered or filtered will require re-running the date parameters, because it gives every date greater than the start date.
I've put advanced search on the grid while troubleshooting. I'd like to take it off (or at least the buttons), as users want to just use the toolbarFilter.
My questions, how can I get the date range picker working in concert with the other column values? Is there an issue running two date pickers at once? The single date date picker just isn't responding at all when it's used. It will put the date there, and once another field is fired, it will respond, but never by itself.
Sorry if I "info dumped" I am fairly new at this. I've searched quite a bit for help to this and can't find much of anything. If I keep hacking at this, I am going to tear up what I have working! :O
Thanks in advance for any help or guidance!
$(function () {
"use strict";
var $grid = $("#vGrid2"),
lastSel;
function modifySearchingFilter(separator) {
var i,
l,
rules,
rule,
parts,
j,
group,
str,
filters = $.parseJSON(this.p.postData.filters);
if (filters && typeof filters.rules !== 'undefined' && filters.rules.length > 0) {
rules = filters.rules;
for (i = 0; i < rules.length; i++) {
rule = rules[i];
if (rule.op === 'cn') {
// make modifications only for the 'contains' operation
parts = rule.data.split(separator);
if (parts.length > 1) {
if (typeof filters.groups === 'undefined') {
filters.groups = [];
}
group = {
groupOp: 'AND',
groups: [],
rules: []
};
filters.groups.push(group);
for (j = 0, l = parts.length; j < l; j++) {
str = parts[j];
if (str) {
// skip empty '', which exist in case of two separators of once
group.rules.push({
data: parts[j],
op: rule.op,
field: rule.field
});
}
}
rules.splice(i, 1);
i--; // to skip i++
}
}
}
this.p.postData.filters = JSON.stringify(filters);
}
};
//TODO: search is filtering in the grid but only from start date and either ge or le start date based on which is first in the column
//TODO: (cont)model. Need to see why end date is not picking up from function.
function invoiceDateSearch($subGrid) {
var postData = $subGrid.getGridParam("postData");
// If there is no post data for some reason, get outta here
if (!postData) {
return;
}
// Make sure the filters object is constructed
var field = "InvoiceDate";
if (!postData.filters) {
postData.filters = {
groupOp: "AND",
rules: []
}
} else {
postData.filters = jQuery.jgrid.parse(postData.filters);
// Need to clear out existing invoice date rules
for (var i = postData.filters.rules.length - 1; i >= 0; i--) {
if (postData.filters.rules[i].field === field) {
postData.filters.rules.splice(i, 1);
}
}
}
var dateRangeString = $("#gs_InvoiceDate").val();
if (dateRangeString.length > 0) {
var dateRange = dateRangeString.split("-");
var startDate = dateRange[0];
var endDate;
if (dateRange.length == 1) {
endDate = dateRange[0];
} else {
endDate = dateRange[1];
}
postData.filters.rules.push({ "field": field, "op": "ge", "data": startDate.trim() });
postData.filters.rules.push({ "field": field, "op": "le", "data": endDate.trim() });
postData.filters = JSON.stringify(postData.filters);
// Need to set the grid's search to true, not the postData's
$subGrid.setGridParam({ search: true });
$subGrid.trigger("reloadGrid", [{ current: true, page: 1 }]);
}
}
function paymentDateSearch($subGrid) {
var postData = $subGrid.getGridParam("postData");
// If there is no post data for some reason, get outta here
if (!postData) {
return;
}
// Make sure the filters object is constructed
var field = "PaymentDate";
if (!postData.filters) {
postData.filters = {
rules: []
}
} else {
postData.filters = jQuery.jgrid.parse(postData.filters);
// Need to clear out existing invoice date rules
for (var i = postData.filters.rules.length - 1; i >= 0; i--) {
if (postData.filters.rules[i].field === field) {
postData.filters.rules.splice(i, 1);
}
}
}
var dateString = $("#gs_PaymentDate").val();
if (dateString.length > 0) {
var startDate = dateRange[0];
postData.filters.rules.push({ "field": field, "op": "eq", "data": startDate.trim() });
postData.filters = JSON.stringify(postData.filters);
// Need to set the grid's search to true, not the postData's
$subGrid.setGridParam({ search: true });
$subGrid.trigger("reloadGrid", [{ current: true, page: 1 }]);
}
}
//**TO overwrite jquery.ui icons and use fontAwesome. extending allows for customization of fA icons set as default in grid**//
$.extend(true, $.jgrid.icons.fontAwesome, {
common: "fa",
sort: {
common: "fa-sort fa-lg"
//asc: "fa-sort",
//desc: "fa-sort"
},
nav: {
common: "fa",
refresh: "fa-recycle fa-lg"
}
});
//**TOOLTIP ADD ON**//
$("[title]").qtip({
position: {
my: "bottom center",
at: "top center",
viewport: $(window)
}
});
//**PRIMARY GRID**//
$grid.jqGrid({
url: "VendInvoice/Vendor",
datatype: "local",
data: gridData,
colNames: ["ID", "Vendor Number", "Vendor Name", "dba", "VendorDbaCombo"],
colModel: [
{ key: true, name: "ID", width: 0, hidden: true, sortable: false, search: false },
{
key: false,
title: false,
name: "VendorNo",
index: "VendorNo",
width: 100,
sortable: true,
search: true,
stype: "text",
searchoptions: {
sopt: ["cn"],
attr: { title: "Enter all or part of a Vendor Number." },
clearSearch: false
}
},
{
key: false,
title: false,
name: "VendorName",
//index: "VendorName",
width: 500,
sortable: true,
search: true,
clearSearch: false,
stype: "text",
searchoptions: {
sopt: ["cn"],
clearSearch: false, //removes X in column filters
attr: {
title: "Enter a Vendor Name. SEARCHTIP: Once you start typing, you will begin returning filtered data. To broaden results returned provide less information, to narrow results provide more.",
maxlength: 9080,
dataInit: function (elem) {
$(elem).width(600);
}
}
}
},
{
key: false,
title: false,
name: "Dba",
index: "Dba",
width: 500,
sortable: true,
search: true,
stype: "text",
searchoptions: {
sopt: ["cn"],
attr: { title: "Enter all or part of a dba." },
clearSearch: false
}
},
{ key: false, name: "VendorDbaCombo", index: "VendorDbaCombo", width: 1, hidden: true }
],
//**PRIMARY GRID PROPERTIES**//
cmTemplate: { autoResizable: true, editable: true },
iconSet: "fontAwesome",
hidegrid: false,
forceFit: true,
caption: "Vendor Results",
ignoreCase: true,
gridview: true,
autoencode: true,
pager: "#Pager",
toppager: true,
rowNum: 25,
rowList: [5, 10, 25],
autowidth: true,
height: "auto",
viewrecords: true,
loadonce: true,
sortName: "VendorName",
sortOrder: "ASC",
viewsortcols: [true, "vertical", true],
forceClientSorting: true,
multiselect: true,
setGridWidth: 980,
loadtext: "Fetching your data, back in a jiff!",
emptyrecords: "There were no records, try narrowing your search criteria",
loadComplete: function () {
$(this).find(">tbody>tr.jqgrow:visible:odd").addClass("myAltRowClass");
},
onSelectRow: function (row_id) {
$grid.jqGrid("toggleSubGridRow", row_id);
if (row_id !== lastSel && typeof lastSel !== "undefined") {
$grid.jqGrid("setRowData", row_id, false, "myNormal");
}
$grid.jqGrid("setRowData", row_id, false, "myBold");
lastSel = row_id;
},
//**SET SUBGRID**//
subGrid: true,
subGridOptions: {
plusicon: "fa fa-plus-square-o",
minusicon: "fa fa-minus-square-o",
reloadOnExpand: false,
expandOnLoad: false,
delayOnLoad: 50
},
jsonReader: {
id: "id",
root: "rows",
total: "total",
records: "records",
subgrid: {
root: "rows",
repeatitems: true, //must be true in subgrid and false in main grid
cell: ""
}
},
subGridRowExpanded: function (subgrid_id, row_id) {
var subgrid_table_id, pager_id;
subgrid_table_id = subgrid_id + "_t";
var selectedrow = $(this).jqGrid('getRowData', row_id);
pager_id = "p_" + subgrid_table_id;
var stat = function (subgrid_id, row_id) {
$("#vGrid2").jqGrid("setSelection", "row_id"); //Test to set selection for toggle
}
//**SUBGRID**//
$("#" + subgrid_id).html("<table id='" + subgrid_table_id + "'class='scroll'></table><div id='" + pager_id + "'class='scroll'></div>");
$("#" + subgrid_table_id).jqGrid({
url: "VendInvoice/VendInvoiceSubGridData?vendorID=" + row_id,
datatype: "local",
data: subgridData[rowId],
postData: {
vendorID: row_id,
},
colNames: ["vendorID", "Invoice Status", "Invoice No", "Invoice Date", "Invoice Amount($)", "Payment Date", "Check or ACH Number", "Check or ACH Amount($)", "Encashment Date"],
colModel: [
{ name: "vendorID", key: true, index: "vendorID", hidden: true, width: 0 },
{
name: "InvoiceStatus",
title: false,
index: "InvoiceStatus",
width: 140,
sortable: true,
search: true,
formatter: "select",
stype: "select",
searchoptions: {
sopt: ["cn"],
attr: { title: "If part of your search criteria, select an invoice status from the drop-down menu." },
value: ":Select (All);Paid:Paid;Processing for Payment:Processing for Payment;Reviewing:Reviewing"
}
},
{
name: "InvoiceNo",
title: false,
index: "InvoiceNo",
width: 125,
sortable: true,
search: true,
stype: "text",
searchoptions: {
sopt: ["cn", "eq"],
attr: { title: "Enter all or part of an invoice number." },
clearSearch: false
}
},
{
name: "InvoiceDate",
title: false,
index: "InvoiceDate",
width: 135,
formatter: "date",
formatoptions: { srcformat: "m/d/Y", newformat: "m/d/Y" },
jsonmap: function (obj) {
var d = new Date(parseInt(obj.matchstartDate, 10));
return d.getFullYear() + "/" + (d.getMonth() + 1) + "/" + d.getDate()
},
sortable: true,
sorttype: "date",
editable: true,
search: true,
stype: "text",
searchoptions: {
sopt: ["ge", "le"],
clearSearch: false,
attr: { title: "Click in the box to open the date range picker." },
dataInit: function (elem) {
$(elem).daterangepicker({
dateFormat: 'mm/dd/yy',
changeYear: true,
changeMonth: true,
todayHighlight: true,
});
//ranges: {
// "Yesterday": [moment(), subtract(1, 'days'), moment().subtract(1, 'days')],
// "Last 7 days": [moment().subtract(6, 'days'), moment()],
// "Last Month": [moment().subtract(1, 'month').startOf('month'), moment().subtract(1, 'month').endOf('month')],
// "This YTD": [moment().startOf('year'), moment().endOf('year')],
// "LastYear": [moment().subtract(1,'year').startOf('year'), moment.subtract(1,'year').endOf('year')]
// }
$(document).on('apply.daterangepicker', function () {
var $subGrid = $("#" + subgrid_table_id);
invoiceDateSearch($subGrid);
});
}
}
},
{
name: "InvoiceAmount",
title: false,
index: "InvoiceAmount",
width: 95,
sortable: true,
sorttype: "float",
formatter: "currency",
formatoptions: {
//prefix: "$",
suffix: "", thousandsSeparator: ",", decimalPlaces: 2
},
search: true,
stype: "text",
searchoptions: {
sopt: ["eq"],
attr: { title: "Enter an invoice amount." },
clearSearch: false
}
},
{
name: "PaymentDate",
title: false,
index: "PaymentDate",
width: 135,
formatter: "date",
formatoptions: { srcformat: "m/d/Y", newformat: "m/d/Y" },
jsonmap: function (obj) {
var d = new Date(parseInt(obj.matchstartDate, 10));
return d.getFullYear() + "/" + (d.getMonth() + 1) + "/" + d.getDate()
},
sortable: true,
sorttype: "date",
editable: true,
search: true,
stype: "text",
searchoptions: {
sopt: ["eq"],
clearSearch: false,
attr: { title: "Click in the box to open the date range picker." },
dataInit:
function (el) {
$(el).datepicker({
dateFormat: 'mm/dd/yy',
changeYear: true,
changeMonth: true,
todayHighlight: true,
orientation: "bottom",
immediateUpdates: true,
autoclose: true
}).on('changeDate', function () {
var $subGrid = $("#" + subgrid_table_id);
paymentDateSearch($subGrid);
$subGrid.setGridParam({ search: true });
$subGrid.trigger("reloadGrid", [{ current: true, page: 1 }]);
});
}
}
},
{
name: "PaymentNo",
title: false,
index: "PaymentNo",
width: 115,
sortable: true,
search: true,
stype: "text",
searchoptions: {
sopt: ["cn", "eq"],
attr: { title: "Enter all or part of a Check or ACH Number." },
clearSearch: false
}
},
{
name: "CheckAmount",
title: false,
index: "CheckAmount",
width: 95,
sortable: true,
sorttype: "float",
formatter: "currency",
formatoptions: { suffix: "", thousandsSeparator: ",", decimalPlaces: 2 },
search: true,
stype: "text",
searchoptions: {
sopt: ["eq"],
attr: { title: "Enter a payment amount." },
clearSearch: false
}
},
{
name: "EncashmentDate",
title: false,
index: "EncashmentDate",
width: 100,
sortable: true,
sorttype: "date",
formatter: "date",
formatoptions: { srcformat: "m/d/Y", newformat: "m/d/Y" },
search: false
}
],
//**SUBGRID PROPERTIES**//
cmTemplate: {
align: "center",
autoResizeable: true
},
idPrefix: "_s",
iconSet: "fontAwesome",
loadonce: true,
loadtext: "Grabbing those invoice, this may take a second!",
autoencode: true,
toppager: true,
autowidth: true,
sortable: true,
showOneSortIcon: true,
autoResizing: { widthOfVisiblePartOfSortIcon: 13 },
viewsortcols: [true, "vertical", true],
multiselect: true,
height: "auto",
rowNum: 500,
rowList: [25, 50, 100, 250, 500],
gridview: true,
viewrecords: true,
emptyrecords: "There were no records, try narrowing your search criteria",
prmNames: {
id: "vendorID"
},
pager: "#" + pager_id,
loadComplete: function () {
$(this).find(">tbody>tr.jqgrow:visible:odd").addClass("myAltRowClass2");
},
beforeSelectRow: function () {
return false;
}
});
jQuery("#" + subgrid_table_id).jqGrid("navGrid", "#" + pager_id, {
edit: false,
add: false,
del: false,
search: true,
refresh: true,
refreshtext: "Refresh Invoice Results",
cloneToTop: true
},
{},
{},
{},
{
multipleSearch: true,
});
jQuery("#" + subgrid_table_id).jqGrid("navButtonAdd", "#" + pager_id, {
caption: "Export to Excel",
buttonicon: "fa-file-excel-o",
onClickButton: function (e) {
exportData(e, "#" + subgrid_table_id);
},
position: "last"
});
jQuery("#" + subgrid_table_id).jqGrid("filterToolbar", {
stringResult: true,
searchOnEnter: false,
ignoreCase: true,
autoSearch: true,
autosearchDelay: 1000,
attr: {
style: "width: auto;padding:0;max-width:100%"
},
defaultSearch: "cn",
//beforeSearch: function () {
// var $subGrid = $("#" + subgrid_table_id);
// invoiceDateSearch($subGrid);
// $subGrid.trigger("reloadGrid", [{ current: true, page: 1 }]);
//}
});
$("[title]").qtip({
position: {
my: "bottom center",
at: "top center",
viewport: $(window)
}
});
var names = [
"Invoice Status", "Invoice No", "Invoice Date", "Invoice Amount", "Payment Date",
"Check or ACH No", "Check or ACH Amount", "Encashment Date"
];
var mydata = [];
var i, j;
if (mydata != null) {
for (i = 0; i < mydata.length; i++) {
mydata[i] = {};
for (j = 0; j < mydata[i].length; j++) {
mydata[i][names[j]] = mydata[i][j];
}
}
}
for (var i = 0; i <= mydata.length; i++);
$("#" + subgrid_table_id).jqGrid('addRowData', i + 1, mydata[i]);
}
}).jqGrid("navGrid", "#Pager", {
edit: false,
add: false,
del: false,
search: false,
refresh: true,
refreshtext: "Refresh Results",
cloneToTop: true
}).jqGrid("filterToolbar", {
stringResult: true,
searchOnEnter: false,
ignoreCase: true,
autoSearch: true,
autosearchDelay: 1000,
attr: {
style: "width: auto;padding:0;max-width:100%"
},
defaultSearch: "cn",
beforeSearch: function () {
modifySearchingFilter.call(this, " ");
}
}).jqGrid("gridResize");
//**TOOLTIP ADD ON**//
$("[title]").qtip({
position: {
my: "bottom center",
at: "top center",
viewport: $(window)
}
});
//**HIDE 'SELECT ALL' CHECKBOX** call after grid is loaded//
$("#cb_" + $grid[0].id).hide();
$("#vGrid2").jqGrid("hideCol", "subgrid");
//**CUSTOM TOOLTIP TEXT FOR COLUMN HEADERS IN PRIMARY GRID**//
var setTooltipsGrid = function (grid, iColumn, text) {
var thd = jQuery("thead:first", grid[0].grid.hDiv)[0];
jQuery("tr.ui-jqgrid-labels th:eq(" + iColumn + ")", thd).attr("title", text);
};
$(".hasTooltip").each(function () {
$(this).qtip({
content: {
text: $(this).next("div")
}
});
});
//setTooltipsGrid($("#vGrid2"), 0, "If exporting, ensure ONLY the row you wish to export is selected. Remove any unnecessary checks in this column.");
//**EXPORT TO EXCEL-CSV**//
function exportData(e, row_id) {
var subGrid = jQuery(row_id).getDataIDs(); // Get all the ids in array
var label = jQuery(row_id).getRowData(subGrid[0]); // Get First row to get the labels
var selRowIds = jQuery(row_id).jqGrid('getGridParam', 'selarrrow');
var obj = new Object();
obj.count = selRowIds.length;
if (obj.count) {
obj.items = new Array();
var elem;
for (elem in selRowIds) {
if (selRowIds.hasOwnProperty(elem)) {
obj.items.push(jQuery(row_id).getRowData(selRowIds[elem]));
}
}
var json = JSON.stringify(obj);
JSONToCSVConvertor(json, "csv", 1);
}
}
function JSONToCSVConvertor(JSONData, ReportTitle, ShowLabel) {
//If JSONData is not an object then JSON.parse will parse the JSON string in an Object
var arrData = typeof JSONData != 'object' ? JSON.parse(JSONData) : JSONData;
var CSV = '';
//This condition will generate the Label/Header
if (ShowLabel) {
var row = "";
//This loop will extract the label from 1st index of on array
for (var index in arrData.items[0]) {
//Now convert each value to string and comma-seprated
row += index + ',';
}
row = row.slice(0, -1);
//append Label row with line break
CSV += row + '\r\n';
}
//1st loop is to extract each row
for (var i = 0; i < arrData.items.length; i++) {
var row = "";
//2nd loop will extract each column and convert it in string comma-seprated
for (var index in arrData.items[i]) {
row += '"' + arrData.items[i][index].replace(/(<([^>]+)>)/ig, '') + '",';
}
row.slice(0, row.length - 1);
//add a line break after each row
CSV += row + '\r\n';
}
if (CSV == '') {
alert("Invalid data");
return;
}
//*** FORCE DOWNLOAD ***//
//will generate a temp "a" tag
var link = document.createElement("a");
link.id = "lnkDwnldLnk";
//this part will append the anchor tag and remove it after automatic click
document.body.appendChild(link);
var csv = CSV;
var blob = new Blob([csv], { type: 'text/csv' });
var myURL = window.URL || window.webkitURL;
var csvUrl = myURL.createObjectURL(blob);
var filename = 'UserExport.csv';
jQuery("#lnkDwnldLnk")
.attr({
'download': filename,
'href': csvUrl
});
jQuery('#lnkDwnldLnk')[0].click();
document.body.removeChild(link);
}
});
It seems to me that the usage of custom operation is the best approach to solve your problem. Of cause you can use beforeSearch callback of filterToolbar to modify the filter, but it's too low level operation and it will not work in Searching Dialog.
I would recommend you to read the wiki article which describes the feature. It provides an example with "numeric IN" operation, which you can easy modify to your requirements. The filter callback get in options all the information which you need and the callback should just verify that the data of the testing item (options.item) are inside of interval provided by the value from the date range picker (options.searchValue). I think that you will get small code, which solves your problem, in the way.
Final remark: I'd recommend you to upgrade to the latest 4.13.0 version which fix some bugs, improves performance in some cases and provides new features described in the readme.

Add/edit/delete a row in free jqGrid

I am using free jqGrid 4.12.1. I want to add, edit and delete rows in the grid and wish to make server side calls for each operation.
I have added editurl and 'actions' formatter as below,
{
name: "actions",
width: 100,
formatter: "actions",
formatoptions: {
keys: true,
editOptions: {},
addOptions: {},
delOptions: {}
}
}
I am adding 'inlineNav' as below,
$("#itemList").jqGrid('inlineNav',"#itemListPager",
{
edit: true,
add: true,
del: true,
search: true,
searchtext: "Search",
addtext: "Add",
edittext: "Edit",
deltext: "Delete"
},
{
closeOnEscape: true, //Closes the popup on pressing escape key
reloadAfterSubmit: true,
drag: true,
url: "${pageContext.request.contextPath}/billing/saveItem",
errorfunc: function (rowId, resp) {
alert(resp);
},
afterSubmit: function (response, postdata) {
if (response.responseText == "") {
$(this).jqGrid('setGridParam', { datatype: 'json' }).trigger('reloadGrid'); //Reloads the grid after edit
return [true, '']
}
else {
$(this).jqGrid('setGridParam', { datatype: 'json' }).trigger('reloadGrid'); //Reloads the grid after edit
return [false, response.responseText]//Captures and displays the response text on th Edit window
}
},
editData: {
EmpId: function () {
var sel_id = $('#itemList').jqGrid('getGridParam', 'selrow');
var value = $('#itemList').jqGrid('getCell', sel_id, '_id');
return value;
}
}
},
{
closeAfterAdd: true, //Closes the add window after add
url: "${pageContext.request.contextPath}/billing/saveItem",
afterSubmit: function (response, postdata) {
if (response.responseText == "") {
$(this).jqGrid('setGridParam', { datatype: 'json' }).trigger('reloadGrid')//Reloads the grid after Add
return [true, '']
}
else {
$(this).jqGrid('setGridParam', { datatype: 'json' }).trigger('reloadGrid')//Reloads the grid after Add
return [false, response.responseText]
}
}
},
{ //DELETE
closeOnEscape: true,
closeAfterDelete: true,
reloadAfterSubmit: true,
url: "${pageContext.request.contextPath}/billing/saveItem",
drag: true,
afterSubmit: function (response, postdata) {
if (response.responseText == "") {
$("#itemList").trigger("reloadGrid", [{ current: true}]);
return [false, response.responseText]
}
else {
$(this).jqGrid('setGridParam', { datatype: 'json' }).trigger('reloadGrid');
return [true, response.responseText]
}
},
delData: {
EmpId: function () {
var sel_id = $('#itemList').jqGrid('getGridParam', 'selrow');
var value = $('#itemList').jqGrid('getCell', sel_id, '_id');
return value;
}
}
},
{//SEARCH
closeOnEscape: true
}
);
The 'inlineNav' added above has no effect because no server side call is made on adding a new row or deleting existing row. The server side call is made only in case of edit, and that call too does not happen through 'inlineNav' code above. Because even if i remove 'inlineNav' code the server side call is still made to the 'editurl'.
So how can i make server side calls on adding/editing/deleting rows and also pass parameters to these calls. I will really appreciate if someone can point me to a working example somewhere. Thanks
UPDATE:-
I have removed 'actions' formatter and modified code to look as below,
<script type="text/javascript">
var dataGrid = $('#itemList');
var firstClick = true;
$(document).ready(function () {
$('#action').click(function () {
if (!firstClick) {
$("#itemList").setGridParam({datatype:'json'}).trigger("reloadGrid");
}
firstClick = false;
$("#itemList").jqGrid({
url: "${pageContext.request.contextPath}/billing/medicines",
datatype: "json",
//styleUI : 'Bootstrap',
mtype: "POST",
autowidth: true,
shrinkToFit: true,
sortname: "Id",
sortorder: "asc",
loadBeforeSend: function(jqXHR) {
jqXHR.setRequestHeader("X-CSRF-TOKEN", $("input[name='_csrf']").val());
},
postData: {
},
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);
},
colNames: ["Id", "Item Type", "Item Code", "Unit", "Stock", "Batch No.", "Expiry Date", "Quantity Per Unit", "Price"],
colModel: [
{ name: "itemId", width: 35, align: "left", sorttype:"int", search: false},
{ name: "itemType", width: 100, align: "left", editable: true},
{ name: "itemCode", width: 120, align: "left", editable: true},
{ name: "unit", width: 70, align: "left", search: false, editable: true},
{ name: "availableQuantity", width: 55, align: "left", search: false, formatter: "number", editable: true},
{ name: "batchNumber", width: 80, align: "left", search: false, editable: true},
{ name: "expiryDate", width: 80, align: "left", search: false, sorttype: "date", editable: true, formatoptions: {srcformat:'d/m/Y', newformat:'d/m/Y'}},
{ name: "quantityPerUnit", width: 80, align: "left", search: false, formatter: "number", editable: true},
{ name: "price", width: 55, align: "left", search: false, formatter: "number", editable: true}
],
pager: "#itemListPager",
rowNum: 50,
rowList: [50, 100, 150, 200],
rownumbers: true,
rownumWidth: 25,
sortname: "id",
sortorder: "desc",
viewrecords: true,
height: '100%',
loadonce: true,
//gridview: true,
autoencode: true,
editurl: "${pageContext.request.contextPath}/billing/saveItem",
caption: "Item List",
ondblClickRow: function(rowId){}
}).navGrid('#itemListPager',{add:false,edit:false,del:true});
$("#itemList").jqGrid('filterToolbar', {autoSearch: true, stringResult: true, searchOnEnter: false, defaultSearch: 'cn'});
$("#itemList").jqGrid('gridResize', { minWidth: 450, minHeight: 150 });
var saveparameters = {
"successfunc" : null,
"url" : "${pageContext.request.contextPath}/billing/saveItem",
"extraparam" : {},
"aftersavefunc" : null,
"errorfunc": null,
"afterrestorefunc" : null,
"restoreAfterError" : true,
"mtype" : "POST"
};
var editparameters = {
"keys" : false,
"oneditfunc" : null,
"successfunc" : null,
"url" : "${pageContext.request.contextPath}/billing/editItem",
"extraparam" : {},
"aftersavefunc" : null,
"errorfunc": null,
"afterrestorefunc" : null,
"restoreAfterError" : true,
"mtype" : "POST"
};
var parameters = {
edit: true,
editicon: "ui-icon-pencil",
add: true,
addicon:"ui-icon-plus",
save: true,
saveicon:"ui-icon-disk",
cancel: true,
cancelicon:"ui-icon-cancel",
addParams : saveparameters,
editParams : editparameters
};
$("#itemList").jqGrid('inlineNav',"#itemListPager", parameters);
});
});
</script>
The sample json dada is as,
[
{"itemDetailId":1,"itemId":1,"itemType":"Medicine","itemCode":"Aler-Dryl","itemDesc":"Aler-Dryl","batchNumber":"batch1","expiryDate":"18/02/2017","unit":"tablet","subUnit":"tablet","availableQuantity":120.0,"quantityPerUnit":60.0,"price":122.0},
{"itemDetailId":2,"itemId":2,"itemType":"Medicine","itemCode":"Benadryl","itemDesc":"Benadryl","batchNumber":"batch1","expiryDate":"18/02/2017","unit":"ml","subUnit":"ml","availableQuantity":60.0,"quantityPerUnit":120.0,"price":90.0}
]
Now the url specified in editparameters and saveparameters is getting invoked on editing and adding a row respectively.
Please suggest if above approach is a good one. Also how can we set a request header before edit or save data is posted to server. And i can not find anything like deleteparameters similar to editparameters and saveparameters so that i can use delete specific parameters.
UPDATE 2:-
I could successfully set a request header before server side code is invoked on add/edit row using following code,
$.ajaxSetup({
beforeSend: function (jqXHR, settings) {
jqXHR.setRequestHeader("X-CSRF-TOKEN", $("input[name='_csrf']").val());
}});
UPDATE 3:-
Cleaned up code as per Oleg's suggestions as below. But in the strict mode i am getting JS error now - "Uncaught ReferenceError: saveparameters is not defined"
<script type="text/javascript">
$(document).ready(function () {
"use strict";
var dataGrid = $('#itemList');
var firstClick = true;
$('#action').click(function () {
if (!firstClick) {
$("#itemList").setGridParam({datatype:'json'}).trigger("reloadGrid");
}
firstClick = false;
$("#itemList").jqGrid({
url: "${pageContext.request.contextPath}/billing/medicines",
datatype: "json",
mtype: "POST",
autowidth: true,
loadBeforeSend: function(jqXHR) {
jqXHR.setRequestHeader("X-CSRF-TOKEN", $("input[name='_csrf']").val());
},
colNames: ["Id", "Item Type", "Item Code", "Unit", "Stock", "Batch No.", "Expiry Date", "Quantity Per Unit", "Price"],
colModel: [
{ name: "itemId", width: 35, align: "left", sorttype:"int", search: false, editable: false, key: true},
{ name: "itemType", width: 100, align: "left"},
{ name: "itemCode", width: 120, align: "left"},
{ name: "unit", width: 70, align: "left", search: false},
{ name: "availableQuantity", width: 55, align: "left", search: false, formatter: "number",},
{ name: "batchNumber", width: 80, align: "left", search: false},
{ name: "expiryDate", width: 80, align: "left", search: false, sorttype: "date", formatoptions: {srcformat:'d/m/Y', newformat:'d/m/Y'}},
{ name: "quantityPerUnit", width: 80, align: "left", search: false, formatter: "number"},
{ name: "price", width: 55, align: "left", search: false, formatter: "number"}
],
cmTemplate: {editable: true},
pager: true,
rowNum: 50,
rowList: [50, 100, 150, 200],
rownumbers: true,
rownumWidth: 25,
sortname: "itemType",
sortorder: "asc",
forceClientSorting: true,
viewrecords: true,
height: '100%',
loadonce: true,
//gridview: true,
autoencode: true,
editurl: "${pageContext.request.contextPath}/billing/saveItem",
caption: "Item List"
//ajaxRowOptions: { beforeSend: myTokenSetting }, loadBeforeSend: myTokenSetting where var myTokenSetting = function(jqXHR) { jqXHR.setRequestHeader("X-CSRF-TOKEN", $("input[name='_csrf']").val()); }
}).navGrid({add:false,edit:false,del:true});
$("#itemList").jqGrid('filterToolbar', {autoSearch: true, stringResult: true, searchOnEnter: false, defaultSearch: 'cn'});
$("#itemList").jqGrid('gridResize', { minWidth: 450, minHeight: 150 });
var saveparameters = {
"successfunc" : null,
"url" : "${pageContext.request.contextPath}/billing/saveItem",
"extraparam" : {},
"aftersavefunc" : null,
"errorfunc": null,
"afterrestorefunc" : null,
"restoreAfterError" : true,
"mtype" : "POST"
};
var editparameters = {
"keys" : false,
"oneditfunc" : null,
"successfunc" : null,
"url" : "${pageContext.request.contextPath}/billing/editItem",
"extraparam" : {},
"aftersavefunc" : null,
"errorfunc": null,
"afterrestorefunc" : null,
"restoreAfterError" : true,
"mtype" : "POST"
};
var parameters = {
edit: true,
editicon: "ui-icon-pencil",
add: true,
addicon:"ui-icon-plus",
save: true,
saveicon:"ui-icon-disk",
cancel: true,
cancelicon:"ui-icon-cancel",
addParams : saveparameters,
editParams : editparameters
};
$("#itemList").jqGrid('inlineNav',parameters);
$.ajaxSetup({
beforeSend: function (jqXHR, settings) {
alert('Before Row Send');
jqXHR.setRequestHeader("X-CSRF-TOKEN", $("input[name='_csrf']").val());
}});
});
});
</script>
You should examine the options of inlineNav to find out that you use absolutely wrong options:
jQuery("#grid_id").jqGrid('inlineNav', pagerid, parameters);
where parameters have the form
{
edit: true,
editicon: "ui-icon-pencil",
add: true,
addicon: "ui-icon-plus",
save: true,
saveicon: "ui-icon-disk",
cancel: true,
cancelicon: "ui-icon-cancel",
addParams: {useFormatter : false},
editParams: {}
}
You use the options of another method navGrid
jQuery("#grid_id").jqGrid('navGrid', '#gridpager', {parameters},
prmEdit, prmAdd, prmDel, prmSearch, prmView);
which allows to use form editing.
You wrote that you want to use both formater: "actions" andinlineNav. Thus you would have to provide some options of inline editing twice. I would recommend you to read [the wiki article](https://github.com/free-jqgrid/jqGrid/wiki/New-style-of-usage-options-of-internal-methods). It describes the problems with the usage of form editing usingformatter: "actions"andnavGridtogether. The usage of inline editing have very close problems. You will have to provideaddParamsandeditParamsproperties ofinlineNavand the corresponding options offormatter: "actions"` (see here). To make the code more readable and simple free jqGrid provides another form of editing options.
You can specify all inline editing options inside of inlineEditing option of jqGrid, additional specific options of inlineNav method (if required) in navOptions or in inlineNavOptions, the options of Delete operation in formDeleting and so on. Moreover reloadGrid have the option fromServer: true to restore the original value of datatype ("json", "jsonp", "xml", ...) which you used. You can use reloadGridOptions: { fromServer: true } option of form editing or formDeleting to force reloading from the server.
Moreover your existing code contains many very suspected parts with _id and EmpId. I would strictly recommend you to include the example of format of input JSON data which you use to fill the grid. If you want to use EmpId as the name of rowid why you use _id instead? The code fragment like
EmpId: function () {
var sel_id = $('#itemList').jqGrid('getGridParam', 'selrow');
var value = $('#itemList').jqGrid('getCell', sel_id, '_id');
return value;
}
shows that the current rowid seems be wrong and _id column contains correct information which you need as rowid under the name EmpId.
You can for example use prmNames: { id: "EmpId"} and to add key: true to the column _id. The property key: true in the column _id will inform jqGrid to use the value from the column _id as the rowid and prmNames: { id: "EmpId"} will rename default id property used in Edit and Delete to EmpId. Thus jqGrid will automatically send EmpId parameter with the value from _id column during Delete and Edit operations to the server.
Probably you can remove unneeded column _id from the grid too (at least if you hold the column hidden), but I need to see input data of jqGrid to say you exact options of jqGrid which you can use.
I'm sure that you can essentially reduce your existing code and make it more readable using free jqGrid options, but you have to review your existing code carefully. I suggest you to start with the usage of correct rowid and elimination of all hidden columns which you use. Free jqGrid provides additionalProperties feature which structure is very close to the structure of colModel, but the corresponding properties of input data will be saved in the local data only and not placed in DOM of the table. I can explain all more clear if you would post your existing colModel, jsonReader and example of JSON response returned from the server (1-2 rows of data with dummy data would be enough).

Define custom sorting on free jqgrid

I have a column called InterestedValue, where I would like to allow sorting, by the label of the dropdown.
I found similar questions and I implemented the recommended solution, but it does not work.
Essentially, nothing happens, the applications behaves exactly like before we added the custom sorttype. Even adding alerts in it, nothing happens, get no errors, or anything.
{
name: 'InterestedValue', editable: true, sortable: true, formatter: 'select', width: 110, search: false, edittype: 'select',
editoptions: {
value: InterestedStatusList,
},
sorttype: function (cellvalue)
{
return InterestedStatusList[cellvalue];
}
}
I added the loadonce: true as suggested, and now I can sort the data correctly, but when I have more records than the ones shown in the first screen, I cannot visualize them.
My code is:
$(gridId).jqGrid(//'setGroupHeaders',
{
url: actionMethod,
shrinkToFit: false,
datatype: 'json',
mtype: 'GET',
loadonce: true,
//sortable: true,
colNames: [MyColumns],
colModel: [
{MyModel }
],
pager: jQuery(pagerId), //jQuery('#pager'),
rowNum: 10,
rowTotal: 2000,
rowList: [10, 20, 30, 40],
height: '100%',
//width:700,
viewrecords: true,
caption: caption,
emptyrecords: 'No records to display',
jsonReader: {
root: "rows",
page: "page",
total: "total",
records: "records",
repeatitems: false,
Id: "0"
},
//autowidth: true,
multiselect: false,
gridview: true,
editurl: '/InvestorList/Edit',
onSelectRow: function (id) {
if (id) {
$(gridId).jqGrid("editRow", id, true, '', '', '', '', reload)
//ORIGINAL CODE: $(gridId).editRow(id, true,'', '', '', '', reload);
lastSelectedId = id;
}
},
serializeRowData: function (postdata) {
//var response = JSON.stringify(postdata);
var s = '';//'<select>';
$(postdata).each(function (index, data) {
//s += '<option value="' + index + '">' + data + '</option>';
$.each(data, function (k, v) {
if (k == "InterestedValue")
s += v;//'<option value="' + k + '">' + v + '</option>';
});
});
//alert("s=" + s);
if (s.indexOf("100010002") != -1) { //"2_1") {
if (confirm('Are you sure you want to deactivate this record? ')) {
// do things if OK
return postdata;
}
else
return false;
}
return postdata;
},
Essentially I see the first ten records, and I have no way of accessing the remaining ones.
How can I fix this?

In inline editing in jqgird how to check whether any row is selected or not?

In inline editing in jqgird how to check whether any row is selected or not?
I want to display error message "Please select a row!" when user click on edit without selecting any row.
#Oleg here is the code:
gridobject.jqGrid({
url: getUrl,
datatype: 'json',
mtype: 'Get',
colNames: arryDisplayCol,
colModel: arryColSettings,
pager: jQuery(pPagerName),
rowNum: 20,
rowList: [20, 40, 80, 100],
height: '100%',
viewrecords: true,
loadonce: false,
grouping: false,
caption: caption,
emptyrecords: 'No records to display',
jsonReader: {
root: "rows",
page: "page",
total: "total",
records: "records",
repeatitems: false,
Id: "0",
},
sortable: {
update: function (relativeColumnOrder) {
var grid = gridobject;
var currentColModel = grid.getGridParam('colModel');
$.ajax({
url: urls.Common.ArrangeGridOrder,
type: 'POST',
data: JSON.stringify(currentColModel),
contentType: 'application/json; charset=utf-8',
success: function (response) {
},
error: function (xhr, status, error) {
}
});
}
},
autowidth: true,
shrinkToFit: true,
multiselect: IsCheckbox,
editData: myData,
sortname: arrColSettings[0].name,
editurl: urls.Admin.ProcessRequest,
serializeRowData: function (postdata) {
var tableNames = $("#grdData").getGridParam('caption').replace(' List', '');
var columnNames = $("#grdData").getGridParam('colNames');
var colNames = columnNames.toString();
for (var i = 0; i < columnNames.length; i++) {
var colName;
if (columnNames[i] == "Id") {
colName = "Id"
}
}
if (!colName) {
colName = columnNames[1].toString();
}
var sel_id = $("#grdData").getSelectedRowsIds();
rowData = jQuery("#grdData").getRowData(sel_id);
var colValue = rowData[colName];
return { x01: JSON.stringify(postdata), x02: tableNames, x03: colNames, x04: JSON.stringify(jsonType), x05: colName, x06: colValue };
},
reloadAfterSubmit: true,
}).navGrid(pPagerName, {
edit: false,
add: false,
del: false,
search: false,
refresh: true,
refreshtext: "Refresh",
beforeRefresh: function () {
var tableName = $("#grdData").getGridParam('caption').replace(' List', '');
ReloadGrid(tableName);
},
});
gridobject.jqGrid('inlineNav', pPagerName,
{
edit: true,
editicon: "ui-icon-pencil",
add: true,
addicon: "ui-icon-plus",
save: true,
saveicon: "ui-icon-disk",
cancel: true,
cancelicon: "ui-icon-cancel",
editParams: {
keys: false,
oneditfunc: null,
successfunc: function (val) {
if (val.responseText != "") {
var tableName = $("#grdData").getGridParam('caption').replace(' List', '');
ReloadGrid(tableName);
}
},
url: null,
aftersavefunc:null,
errorfunc: null,
afterrestorefunc: null,
restoreAfterError: true,
mtype: "POST",
alertcap: "Warning",
alerttext: "Please, select row"
},
addParams: {
useDefValues: true,
addRowParams: {
keys: true,
extraparam: {},
successfunc: function (val) {
if (val.responseText != "") {
var tableName = $("#grdData").getGridParam('caption').replace(' List', '');
ReloadGrid(tableName);
}
}
}
}
}
);
inlineNav automatically tests whether the row is selected or not. If the row is not selected then the message with the text "Please, select row" will be displayed. The default text come from $.jgrid.nav.alerttext defined in grid.locale-en.js file or other language file which you use. If your problem is in requirement of modification of the default text "Please, select row" to "Please select a row!" then you should use alerttext option of navGrid (the options should be defined on the same level as refreshtext: "Refresh").

Categories

Resources