Retain filter text in filter toolbar on grid reload - jqgrid

I'm using jqgrid in which i'm trying to retain the filter text after the grid reload.
I have cell update functionality,
//Code:
$.ajax({
url: '#Url.Action("UpdateComments", "Home")',
datatype: 'json',
data: { 'resultData': filterResult, 'action': postdata.oper },
type: 'POST',
success: OnCompleteComments,
error: function (xhr, status, error) {
if (xhr.statusText == "Session TimeOut/UnAuthorized") {
alert(xhr.statusText);
window.location.href = '#Url.Action("LogOut", "Account")';
}
else
alert(xhr.responseText);
}
});
//After update Load the grid.
function OnCompleteComments(result) {
myfilter = $('#TransactionsGrid').jqGrid("getGridParam", "postData").filters;
Loadgrid($('#TransactionsGrid').getGridParam('page'));
}
After the successful udpate of the cell i'm reloading the grid for the cell to reflect the udpated values. In the OnComplete i'm getting the filter assigned to a golbally declared variable(myfilter).
//Grid:
datatype: 'local',
hoverrows: false,
colNames: colHeader,
colModel: colname,
localReader: { id: 'TransactionId' },
rowNum: 10,
hidegrid: false,
rownumbers: true,
pager: '#TransactionsGridPager',
viewrecords: true,
caption: "Transaction Details",
height: 'auto',
scrollOffset: 0,
page: PageNumber,
gridview: true,
shrinkToFit: true,
autoencode: true,
ignoreCase: true,
mySelection: {},
onInitGrid: function () {
// get reference to parameters
var p = $(this).jqGrid("getGridParam");
// set data parameter
p.data = gridData.BuildTransactionsDataTable;
},
In grid reload(ajax function is called), once the grid is loaded i'm re assigning the filter. In this place i'm getting the filtered results in the grid exactly bu the text which i used to filter the results is not in the filter toolbar. Its empty.
GridReload(Retain filter):
jQuery("#TransactionsGrid").jqGrid({
});
if (myfilter) {
var searchFiler = JSON.parse(myfilter).rules[0].data, grid = $("#TransactionsGrid"), f;
if (searchFiler.length === 0) {
grid[0].p.search = false;
$.extend(grid[0].p.postData, { filters: "" });
}
f = { groupOp: "OR", rules: [] };
f.rules.push({ field: JSON.parse(myfilter).rules[0].field, op: "cn", data: searchFiler });
grid[0].p.search = true;
$.extend(grid[0].p.postData, { filters: JSON.stringify(f) });
grid.trigger("reloadGrid", [{ page: 1, current: true }]);
}
Now i need the filtered text to be retained in the filter toolbar. how can i achieve this?

Related

jqGrid filterToolbar with local data

I have a jQgrid that loads data initially via an ajax call from backend(java struts). Again, this is one time load and once loaded, the jqGrid should operate on the data available locally.
Initially, datatype:json and once loadcomplete, set datatype:local.
Now is there a way to use filterToolbar for local datatype with the following options in free jqgrid;
autocomplete enabled in the toolbar
excel like filtering options
Jqgrid Options:
jQuery("#listTable").jqGrid({
url:'/WebTest/MainAction.do',
datatype: "json",
colNames: ['Label','Value'],
colModel: [
{name:'label',index:'label',width: 40,search:true, stype:'text',sorttype:'int'},
{name:'value',index:'value',width: 56,search:true, stype:'text',sorttype:'text'}
],
autowidth: true,
autoResizing: { compact: true, widthOfVisiblePartOfSortIcon: 13 },
rowNum: 10,
rowList: [5, 10, 20, "10000:All"],
viewrecords: true,
pager: true,
toppager: true,
rownumbers: true,
sortname: "label",
sortorder: "desc",
caption: "Test 235",
height: "200",
search: true,
loadonce: true,
loadComplete: function (data) {
},
gridComplete: function(){
jQuery("#listTable").jqGrid('setGridParam', { datatype: 'local' });
}
}) .jqGrid("navGrid", { view: true, cloneToTop: true})
.jqGrid("filterToolbar")
.jqGrid("gridResize");
All the features are enabled by default if I understand you correctly. The server just have to return all data instead of one page of data to make loadonce: true property work correctly. You need just call filterToolbar after creating the grid. All will work like with local data. You should consider to set sorttype property for correct local sorting and stype and searchoptions for correct filtering of data.
To have "autocomplete" and "excel like filtering options" you need additionally to follow the answer which set autocomplete or stype: "select", searchoptions: { value: ...} properties based on different values of input data. You can do this inside of beforeProcessing callback. The code from the answer use this.jqGrid("getCol", columnName) which get the data from the grid. Instead of that one have access to data returned from the server inside of beforeProcessing callback. So one can scan the data to get the lists with unique values in every column and to set either autocomplete or stype: "select", searchoptions: { value: ...} properties.
UPDATED: I created JSFiddle demo which demonstrates what one can do: http://jsfiddle.net/OlegKi/vgznxru6/1/. It uses the following code (I changed just echo URL to your URL):
$("#grid").jqGrid({
url: "/WebTest/MainAction.do",
datatype: "json",
colNames: ["Label", "Value"],
colModel: [
{name: "label", width: 70, template: "integer" },
{name: "value", width: 200 }
],
loadonce: true,
pager: true,
rowNum: 10,
rowList: [5, 10, "10000:All"],
iconSet: "fontAwesome",
cmTemplate: { autoResizable: true },
shrinkToFit: false,
autoResizing: { compact: true },
beforeProcessing: function (data) {
var labelMap = {}, valueMap = {}, i, item, labels = ":All", values = [],
$self = $(this);
for (i = 0; i < data.length; i++) {
item = data[i];
if (!labelMap[item.label]) {
labelMap[item.label] = true;
labels += ";" + item.label + ":" + item.label;
}
if (!valueMap[item.value]) {
valueMap[item.value] = true;
values.push(item.value);
}
}
$self.jqGrid("setColProp", "label", {
stype: "select",
searchoptions: {
value: labels,
sopt: ["eq"]
}
});
$self.jqGrid("setColProp", "value", {
searchoptions: {
sopt: ["cn"],
dataInit: function (elem) {
$(elem).autocomplete({
source: values,
delay: 0,
minLength: 0,
select: function (event, ui) {
var grid;
$(elem).val(ui.item.value);
if (typeof elem.id === "string" && elem.id.substr(0, 3) === "gs_") {
grid = $self[0];
if ($.isFunction(grid.triggerToolbar)) {
grid.triggerToolbar();
}
} else {
// to refresh the filter
$(elem).trigger("change");
}
}
});
}
}
});
// one should use stringResult:true option additionally because
// datatype: "json" at the moment, but one need use local filtreing later
$self.jqGrid("filterToolbar", {stringResult: true });
}
});

Cancel edit event in jqGrid inline edit

I'm using jqgrid inline edit in which i have a scenario to invoke the "cancel edit" button event and throw a message "Are you sure to cancel?".
//Code:
//Unload the grid.
$('#CommentsData').jqGrid('GridUnload');
//Comments grid start.
$("#CommentsData").jqGrid({
datastr: tableSrc,
hoverrows: false,
datatype: "jsonstring",
jsonReader: {
id: 'CommentId',
repeatitems: false
},
height: 'auto',
width: 'auto',
hidegrid: false,
gridview: true,
sortorder: 'desc',
sortname: 'DateTime',
pager: '#CommentsPager',
rowList: [], // disable page size dropdown
pgbuttons: false, // disable page control like next, back button
pgtext: null, // disable pager text like 'Page 0 of 10'
viewrecords: false, // disable current view record text like 'View 1-10 of 100'
caption: "Comments",
colNames: ['DateTime', 'UserName', 'Comments'],
colModel: [
{
name: 'DateTime', index: 'DateTime', width: 120, formatter: "date", sorttype: "date",
formatoptions: { srcformat: "ISO8601Long", newformat: "m/d/Y h:i A" }
},
{ name: 'UserName', index: 'UserName' },
{ name: 'CommentText', index: 'CommentText', editable: true }],
//Events to add and edit comments.
serializeRowData: function (postdata) {
var filterResult;
var jsonResult;
if (tableSrc == "")
jsonResult = $.parseJSON(commentDetails);
else
//Parse values bind to the comments.
jsonResult = $.parseJSON(tableSrc);
var newResult = new Object();
//Check if operation is edit.
if (postdata.oper == "edit") {
//Filter the edited comments from main source.
newResult = Enumerable.From(jsonResult).Where(function (s) { return s.CommentId = postdata.id }).First();
newResult.CommentText = postdata.CommentText;
}
else {
filterResult = Enumerable.From(jsonResult).First();
newResult.CommentText = postdata.CommentText;
newResult.TransactionId = filterResult.TransactionId;
newResult.TaskId = filterResult.TaskId;
}
filterResult = JSON.stringify(newResult);
$.ajax({
url: '#Url.Action("UpdateComments", "Home")',
datatype: 'json',
data: { 'resultData': filterResult, 'action': postdata.oper },
type: 'POST',
success: OnCompleteComments,
error: function (xhr, status, error) {
if (xhr.statusText == "Session TimeOut/UnAuthorized") {
alert(xhr.statusText);
window.location.href = '#Url.Action("LogOut", "Account")';
}
else
alert(xhr.responseText);
}
});
//After update Load the grid.
function OnCompleteComments(result) {
selectTaskComment = false;
$('#dialog').dialog("close");
myfilter = $("#TransactionsGrid").jqGrid("getGridParam", "postData").filters;
rowList = $('.ui-pg-selbox').val();
Loadgrid($("#TransactionsGrid").getGridParam('page'));
}
},
onSelectRow: function (id) {
selectTaskComment = true;
var thisId = $.jgrid.jqID(this.id);
$("#" + thisId + "_iledit").removeClass('ui-state-disabled');
$("#del_" + thisId).removeClass('ui-state-disabled');
var selectValues = jQuery('#CommentsData').jqGrid('getRowData', id);
thisId = $.jgrid.jqID(this.id);
if (selectValues.UserName == '#ViewBag.UserName' || '#ViewBag.IsAdmin' == 'True') {
$("#" + thisId + "_iledit").removeClass('ui-state-disabled');
$("#del_" + thisId).removeClass('ui-state-disabled');
}
else {
$("#" + thisId + "_iledit").addClass('ui-state-disabled');
$("#del_" + thisId).addClass('ui-state-disabled');
}
}
});
jQuery("#CommentsData").jqGrid('navGrid', '#CommentsPager', { edit: false, add: false, del: true, search: false, refresh: false }, {}, {},
{
//Delete event for comments
url: '#Url.Action("UpdateComments", "Home")',
serializeDelData: function (postData) {
return {
resultData: JSON.stringify(postData.id),
action: JSON.stringify(postData.oper),
}
},
errorTextFormat: function (xhr) {
if (xhr.statusText == "Session TimeOut/UnAuthorized") {
window.location.href = '#Url.Action("LogOut", "Account")';
} else {
return xhr.responseText;
}
},
beforeSubmit: function () {
myfilter = $("#TransactionsGrid").jqGrid("getGridParam", "postData").filters;
return [true, '', ''];
},
afterSubmit: function (response, postdata) {
selectTaskComment = false;
Loadgrid($("#TransactionsGrid").getGridParam('page'));
return [true, '', ''];
}
});
$('#CommentsData').jqGrid('inlineNav', '#CommentsPager', { edit: true, add: true, save: true, del: false, cancel: true });
$("#CommentsData_iledit").addClass('ui-state-disabled');
$("#del_CommentsData").addClass('ui-state-disabled');
In which event i have to write the code and throw the alert message?
Also if possible, need to know if the above code could be optimized. Because the delete event is written in a separate place comparing edit and add. I'm bit confused if this is right method.
The easiest way to invoke the "cancel edit" button would be executing the code
$("#CommentsData_ilcancel").click(); // trigger click event on Cancel button
where CommentsData is the id of the grid.

Jqgrid - Multiselectected rows no longer persist after triggering a JqGrid reload

I have a multi-selected Jqgrid. Initially on loading the grid with the Json reponse from the server, the multiselected rows persist correctly as I navigate from one page to another.
The ids of the rows selected are stored in an Array and this Array is updated on paging. I use this array to check the already selected rows on returning back to the page. Sorting works fine and I faced no problem so far.
On applying a filter on a particular field, a request is sent to the server which returns the new filtered result in Json and then reloads the grid with it.
The first page is rendered correctly with the selected rows checked but on changing the page and returning back the rows are no longer selected. However the array still contains the ids and is also containing the new added ids.
How is that the Multiselected feature stops working after a reload??? Or is it not even because of the reload??
Here is the code:
<script type='text/javascript'>
var selectedFieldsMap={};
var selectedFieldsObjs = [];
var selectedFieldIds = [];
$(function() {
//function called when applying a filter
$('#ApplyFilterBtn').click(function() {
saveGridState();
$('#Grid').setGridParam({ url: getUrl() });
$('#Grid').trigger('reloadGrid');
});
});
function saveGridState() {
var selectedIds = $('#Grid').getGridParam('selarrrow');
$('#Grid').data(current_page, selectedIds);
_.each(selectedIds, function(id) {
selectedFieldIds.push(id);
});
var idsToBeAdded = _.difference(selectedIds, getExistingRowIdsForGrid('#list'));
selectedFieldsMap[current_page] = idsToBeAdded;
_.each(idsToBeAdded, function(id) {
selectedFieldsObjs.push($('#Grid').getRowData(id));
});
}
function getExistingRowIdsForGrid(gridSelector) {
var existingFields = $(gridSelector).getRowData();
return _.map(existingFields, function(obj) { return obj.Id; });
function resetFilterValuesAndReloadGrid() {
//reset filters and set grid param
$('#Grid').setGridParam({
sortname: 'Id',
sortorder: 'asc',
page: 1,
url: getUrl()
});
$('#Grid').jqGrid('sortGrid', 'Id', true);
$("#Grid").trigger('reloadGrid');
}
$("#Grid").jqGrid({
url: getUrl(),
datatype: "json",
edit: false,
add: false,
del: false,
height: 330,
mtype: 'GET',
colNames: ['Id', 'Type', 'Category'],
jsonReader: {
root: "DataRoot",
page: "CurrentPage",
total: "TotalPages",
records: "TotalRecords",
repeatitems: false,
cell: "",
id: "0"
},
colModel: [
{ name: 'Id', index: 'Id', width: 95, align: 'center', sorttype: "int" },
{ name: 'Type', index: 'ValueTypeName', width: 110, align: 'left',sortable: true },
{ name: 'Category', index: 'Category', width: 72, align: 'left', sortable: true },
],
pager: '#pager',
rowNum: pageCount[0],
rowList: pageCount,
sortname: 'Id',
sortorder: 'asc',
viewrecords: true,
gridview: true,
multiselect: true,
loadComplete: function () {
if(selectedFieldIds) {
$.each(_.uniq(selectedFieldIds), function(index, value) {
$('#Grid').setSelection(value, true);
});
}
} ,
onPaging : function () {
saveGridState();
},
loadBeforeSend: function() {
current_page = $(this).getGridParam('page').toString();
} ,
onSortCol: function () {
saveGridState();
}
});
}
function getUrl() {
//return url with the parameters and filtering
}
</script>
The problem is solved, what happens is on reload of the grid the function which checks the row is called as it is in the document.ready()and the on grid loadComplete the same function is called. Toggle happens and the selection is removed. I've added an if condition to see if the grid is selected or not.
loadComplete: function () {
var selRowIds = jQuery('#Grid').jqGrid('getGridParam', 'selarrrow');
if (selRowIds.length > 0) {
return false;
} else {
var $this = $(this), i, count;
for (i = 0, count = idsOfSelectedRows.length; i < count; i++) {
$this.jqGrid('setSelection', idsOfSelectedRows[i], false);
}
}
}

validate jqgrid data on the server, callback function

I am using autocomplete in a textbox on my jqgrid. But i should not allow the user to select the same item twice. Because of pagination he wont see all data all times. Is there a way that on sending new row to server check for duplicate data in the server and send a status back to jqgrid maybe poping up an alert sayign "row already exist on table". What would be the bst approach to do this validation and notify the user? thanks.
$("#assessmentproduct").jqGrid({
url: 'orthofixServices.asmx/GetProductList',
colNames: ['id', 'Product Description', 'Commission Rate'],
colModel: [
{ name: 'id', hidden: true },
{ name: 'description', index: 'desc', width: 320, editable: true },
{ name: 'commissionrate', index: 'com', width: 120, editable: true, unformat: percentUnFormatter, formatter: percentFormatter, editrules: { number: true} }
],
serializeRowData: function(data) {
var params = new Object();
params.id = 0;
params.prdid = $("#prdid").val();
params.description = data.description;
params.commissionrate = data.commissionrate;
var result = JSON.stringify({ 'passformvalue': params, 'oper': data.oper, 'id': data.id });
return result;
},
mtype: "POST",
rowNum: 4,
height: 93,
width: 400,
pager: '#assessmentpager',
editurl: "orthofixServices.asmx/ModifyProductList"
});
$("#assessmentproduct").jqGrid('navGrid', '#assessmentpager', { add: false, edit: false, del: true, refresh: false, search: false }, {}, {}, { serializeDelData: function(postData) {
return JSON.stringify({ 'passformvalue': null, 'oper': postData.oper, 'id': postData.id });
}
});
$("#assessmentproduct").jqGrid('inlineNav', '#assessmentpager', { addParams: { position: "last", addRowParams: {
"errorfunc": duplicateRow, "aftersavefunc": function() { var grid = $("#assessmentproduct"); reloadgrid(grid); }
}
}, editParams: { "aftersavefunc": function() { var grid = $("#assessmentproduct"); reloadgrid(grid); } }
});
You should just hold the simple rule: if an error occur on the server (for example because of validation error) the server response should contains some error HTTP status code. In the case error message will be displayed to the user.
The exact error processing and the displayed error message format depends from the editing mode which you use. In case of inline editing I would recommend you to use errorfunc and restoreAfterError parameters of the editRow method. In case of form editing the errorTextFormat callback can be very helpful.

jqGrid Problem Binding Subgrid

I have a jqGrid that is not correctly displaying the subgrid rows. When I load the page, the regular grid rows display fine as well as the plus sign next to each of them, but when I click the plus button to expand them, the "Loading..." message just remains and nothing happens. I don't know if it makes a difference, but I am trying to do it on client side (loadonce: true).
Here is the code for creating the grid:
$("#Grid1").jqGrid({
// setup custom parameter names to pass to server
prmNames: {
search: null,
nd: null,
rows: "numRows",
page: "page",
sort: "sortField",
order: "sortOrder"
},
datatype: function(postdata) {
$(".loading").show(); // make sure we can see loader text
$.ajax({
url: 'WebServices/GetJSONData.asmx/getGridData',
type: "POST",
contentType: "application/json; charset=utf-8",
data: JSON.stringify(postdata),
dataType: "json",
success: function(data, st) {
if (st == "success") {
var grid = $("#Grid1")[0];
grid.addJSONData(JSON.parse(data.d));
//Loadonce doesn't work, have to do its dirty work
$('#Grid1').jqGrid('setGridParam', { datatype: 'local' });
//After rows are loaded, have to manually load subgrid rows
var subgridData = JSON.parse(data.d).subgrid;
var lista = jQuery("#Grid1").getDataIDs();
var rowData;
//Iterate over each row in grid
for (i = 0; i < lista.length; i++) {
//Get current row data
rowData = jQuery("#Grid1").getRowData(lista[i]);
}
}
},
error: function() {
alert("Error with AJAX callback");
}
});
},
// this is what jqGrid is looking for in json callback
jsonReader: {
root: "rows",
page: "page",
total: "totalpages",
records: "totalrecords",
cell: "cell",
id: "id", //index of the column with the PK in it
userdata: "userdata",
repeatitems: true
},
coNames: ['Inv No', 'Amount', 'Store', 'Notes'],
colModel: [
{ name: 'InvNum', index: 'InvNum', width: 200 },
{ name: 'Amount', index: 'Amount', width: 55 },
{ name: 'Store', index: 'Store', width: 50 },
{ name: 'Notes', index: 'Notes', width: 100 }
],
subGrid: true,
subGridModel: [{
name: ['InvNum', 'Name', 'Qauntity'],
width: [55, 200, 80],
params: ['InvNum']
}],
rowNum: 10,
rowList: [10, 20, 50],
pager: '#Div1',
viewrecords: true,
width: 500,
height: 230,
scrollOffset: 0,
loadonce: true,
ignoreCase: true,
gridComplete: function() {
$(".loading").hide();
}
}).jqGrid('navGrid', '#Div1', { del: false, add: false, edit: false }, {}, {}, {}, { multipleSearch: true });
Here the code that I am using in the webservice call to create the JSON data:
IEnumerable orders = getOrders();
IEnumerable items = getItems();
int k = 0;
var jsonData = new
{
totalpages = totalPages, //--- number of pages
page = pageIndex, //--- current page
totalrecords = totalRecords, //--- total items
rows = (
from row in orders
select new
{
id = k++,
cell = new string[] {
row.InvNum.ToString(), row.Amount.ToString(), row.Store, row.Notes
}
}
).ToArray(),
subgrid = (
from row in items
select new
{
cell = new string[] {
row.InvNum.ToString(), row.Name, row.Quantity.ToString()
}
}
).ToArray()
};
result = Newtonsoft.Json.JsonConvert.SerializeObject(jsonData);

Resources