jqgrid - dynamically enabling grouping - jqgrid

I was able to implement grouping feature from examples in the jqgrid demo page. But I don't want to enable grouping by default but on the change of a select list I would like to enable the grouping feature. I have tried several options but none of them were successful? Could some one please help me here, may be I am missing something. Here is my code...
$("#dynamicGrouping").change(function() {
var value = $(this).val();
if(value) {
if(value == '') {
$('#grid').jqGrid('groupingRemove', true);
} else {
$('#grid').jqGrid('setGridParam', { grouping:true });
$('#grid').jqGrid('groupingGroupBy', value);
$('#grid').trigger('reloadGrid');
}
}
});
My grid definition:
jQuery(function() {
$('#grid').jqGrid({
.....
.....
grouping: false,
groupingView : {
groupField : ['field_name'],
groupColumnShow : [true],
groupText : ['<b>{0} - {1} Item(s)</b>'],
groupCollapse : false,
groupOrder: ['asc'],
groupDataSorted : true
},
.......
.......
});
});

I supposed that you made some error in the code. The code which you posted seem me correct, but you don't need to set grouping:true and trigger reloadGrid additionally because groupingGroupBy do this you automatically.
The demo demonstrates setting or removing of grouping dynamically.
So you can use
$("#dynamicGrouping").change(function () {
var groupingName = $(this).val();
if (groupingName) {
$('#grid').jqGrid('groupingGroupBy', groupingName);
} else {
$('#grid').jqGrid('groupingRemove');
}
});
or a little more advanced version
$("#dynamicGrouping").change(function () {
var groupingName = $(this).val();
if (groupingName) {
$('#grid').jqGrid('groupingGroupBy', groupingName, {
groupOrder : ['desc'],
groupColumnShow: [false],
groupCollapse: true
});
} else {
$('#grid').jqGrid('groupingRemove');
}
});
UPDATED: Everything works with JSON data too: see the demo.
UPDATED 2: I looked in the code one more time and I found out that gridview will set to true at the initialization of grid: see the lines. If you don't have gridview: true and use initially grouping: false then you will be not able to change just grouping: true. You have to set also other parameters from the grouping limitations correctly.
So you have to hold the rules from limitations yourself:
scroll: false,
rownumbers: false,
treeGrid: false,
gridview: true,
By the way I recommend always use gridview: true because of better performance.

Related

jqGrid: How to load only rows that an attribute is set to true

I have a JSON Object as the following:
{
"rows": [
{
"id":1,
"name": "Peter",
"hasData": true,
},
{
"id":2,
"name": "Tom",
"hasData": false,
}]
}
And I want the jqGrid to load only rows that have data, meaning when "hasData" == true.
I am firstly wondering what is the best way to do such and secondly wondering how to do it.
UPDATE:
I have tried the following:
gridComplete: function(){
var rowObjects = this.p.data;
for(var i = 0; i<rowObjects.length;i++){
if(rowObjects[i].hasData == false){
$(this).jqGrid('delRowData',rowObjects[i].id);
}
}
},
but the problem is when I go to the next page, all the data is loaded new from the JSON.
I suppose that you load the data from the server using datatype: "json" in combination with loadonce: true option. The solution is very easy if you use free jqGrid fork of jqGrid. Free jqGrid allows to sort and to filter the data, returned from the server, before displaying the first page of data. One need to add forceClientSorting: true to force the applying the actions by jqGrid and postData.filters with the filter, which you need, and the option search: true to apply the filter:
$("#grid").jqGrid({
...
datatype: "json",
postData: {
// the filters property is the filter, which need be applied
// to the data loaded from the server
filters: JSON.stringify({
groupOp: "AND",
groups: [],
rules: [{field: "hasData", op: "eq", data: "true"}]
})
},
loadonce: true,
forceClientSorting: true,
search: true,
// to be able to use "hasData" property in the filter one has to
// include "hasData" column in colModel or in additionalProperties
additionalProperties: ["hasData"],
...
});
See the demo https://jsfiddle.net/OlegKi/epcz4ptq/, which demonstrate it. The demo uses Echo service of JSFiddle to simulate server response.
I can recommend you another solution (in case you use Guriddo jqGrid) , which can be used with any datatype and any settings. The idea is to use beforeProcessing event to filter the needed data.
For this purpose we assume that the data is like described from you. Here is the code:
$("#grid").jqGrid({
...
beforeProcessing : function (data, st, xhr) {
var test= data.rows.filter(function (row) {
if(row.hasData == true ) { // true is not needed but for demo
return true;
} else {
return false;
}
});
data.rows = test;
return true;
}
...
});
I suppose the script will work in free jqGrid in case you use them

jqGrid Trying to apply filter(s) on Grid creation

I have an object that contains the following filter string:
prefs.filters={"groupOp":"AND","rules":[{"field":"FirstName","op":"cn","data":"max"}]}
Here is my grid create, where I am trying to apply the filters in the postData setting:
// Set up the jquery grid
$("#jqGridTable").jqGrid(
{
// Ajax related configurations
url: jqDataUrl,
datatype: "json",
mtype: "GET",
autowidth: true,
// Configure the columns
colModel: columnModels,
// Grid total width and height
height: "100%",
// customize jqgrid post init
gridComplete: function()
{
CRef.updateJqGridPagerIcons("jqGridTable");
},
// Paging
toppager: true,
rowNum: 20,
rowList: [5, 10, 20, 50, 100],
viewrecords: true, // Specify if "total number of records" is displayed
// Default sorting
sortname: typeof prefs.sortCol !== "undefined" ? prefs.sortCol : "LastName",
sortorder: typeof prefs.sortCol !== "undefined" ? prefs.sortOrd : "asc",
sorttype: "text",
sortable: true,
postData: typeof prefs.filters !== "undefined" ? { filters: prefs.filters } : {},
//also tried this...
//postData: typeof prefs.filters !== "undefined" ? { JSON.stringify(filters: prefs.filters) } : {},
//remaining property settings excluded from post to keep short.
Update: Using .navGrid on grid as follows:
.navGrid("#jqGridTable",
{ refresh: true, add: false, edit: false, del: false, refreshtitle: getRefreshText('#Model.Instruction'), searchtitle: searchText },
{}, // settings for edit
{}, // settings for add
{}, // settings for delete
{ closeAfterSearch: true, closeOnEscape: true, multipleSearch: true, multipleGroup: true });
When grid is created, the filter in postData is not applied. I also tried triggering reload event after the initial create and that to did not apply filter either.
From other posts, I believe I'm on correct path, but appear to be missing something.
Update after comments:
I added the following code to loadComplete...
if ($("#jqGridTable").jqGrid("getGridParam", "datatype") === "json") {
setTimeout(function () {
$("#jqGridTable").jqGrid("setGridParam", {
datatype: "local",
postData: { filters: prefs.filters, sord: prefs.sortOrd, sidx: prefs.sortCol },
search: true
});
$("#jqGridTable").trigger("reloadGrid");
}, 50);
}
and it successfully retains the filters. :)
However, now I have interesting issue side effect. I can sort on columns and some columns will change to sort asc/desc correctly, but when I go to others and sort, they sort but in the order that they originally loaded which is neither asc or desc.
You have to set search: true option of jqGrid if you want that filters will be applied. Moreover you use datatype: "json". It means that the filters will be just send to the server and your server code have to decode the filters and to use there. One more remark. The correct value for postData would be { filters: JSON.stringify(prefs.filters) }.
UPDATED: I recommend you upgrade to the latest version (4.12.1) or free jqGrid. It's the fork of jGrid which I develop since the end of 2014. To use free jqGrid you can just change the URLs to jqGrid files to URLs described in the wiki article. After that you can use the following options:
loadonce: true,
forceClientSorting: true,
search: true,
postData: { filters: prefs.filters },
sortname: prefs.sortCol,
sortorder: prefs.sortOrd
and remove the loadComplete code which you posted in "Update after comments" part of your question. Free jqGrid will load all data returned from the server, apply the filter prefs.filters locally, sort the results locally and display the first page of the results (based on the page size rowNum: 20).
The old demo loads the JSON data from the server, sort the data locally and filter by isFinal === 1 and finally display the first page of results. The demo uses additionally custom sorting using sortfunc, additionalProperties, which allows to saved additionally properties in local data.
You can additionally include reloadGridOptions: { fromServer: true } to other options of navGrid which you use (refresh: true, add: false, ...). It will change the behavior of the Refresh button of the navigator bar to reload the data from the server if the user clicks on the button. See another answer, which I posted today for more information about new options of free jqGrid and loadonce: true.

ExtJs Grid Remote Sorting and Remote filtering

I have a grid in ExtJs 4.2. I need to apply remote sorting, remort filtering and pagination. So my store look like this:
storeId: 'mainStore',
pageSize: 10,
autoLoad: {
start: 0,
limit: 10
},
autoSync: true,
remoteSort: 'true', //For Remote Sorting
sorters: [{
property: 'COM_KOP_Vertriebsprojektnummer'
direction: 'ASC'
}],
remoteFilter: true, //For Remote Filtering
proxy: {
type: 'rest',
filterParam: 'filter',
url: PfalzkomApp.Utilities.urlGetData(),
headers: {
'Content-Type': "application/xml"
},
reader: {
type: 'xml',
record: 'record',
rootProperty: 'xmlData'
}
}
I do not want to set buffered = true case that will load my pages in advance and I have 1000 pages and I don't want to do that.
Remote filtering, Pagination, sorting is working fine But when I try to filter some thing, a seprate request for sorting is going as well. How can I stop it?
two requests when I try to filter some thing:
http://127.0.0.1/projektierungen/?_dc=1437058620730&page=1&start=0&limit=10&sort=[{"property":"COM_KOP_Vertriebsprojektnummer","direction":"DESC"}]
http://127.0.0.1/projektierungen/?_dc=1437058620734&page=1&start=0&limit=10&sort=[{"property":"COM_KOP_Vertriebsprojektnummer","direction":"DESC"}]&filter=[{"property":"COM_KOP_Vertriebsprojektnummer","value":"2882"}]
How can I stop the first request?
My code for filtering column is this:
{
text: 'Vertriebsprojektnr',
dataIndex: 'COM_KOP_Vertriebsprojektnummer',
flex: 1,
items : {
xtype:'textfield',
flex : 1,
margin: 2,
enableKeyEvents: true,
listeners: {
keyup: function() {
var store = Ext.getStore('mainStore');
store.clearFilter();
if (this.value) {
//debugger;
//debugger;
store.filter({
property : 'COM_KOP_Vertriebsprojektnummer',
value : this.value,
anyMatch : true,
caseSensitive : false
});
}
},
buffer: 1000,
}
}
}
Due to this auto genrated request, my view is not working fine. As the result after filtering are replaced by this sorting request.
Kindly help.
The extra request is not there because of sorting but because of the call to store.clearFilter(). Try to call store.clearFilter(true) that suppresses the event what could prevent that extra request.
Why are you clearing you filters when the value is empty? Why not filter on an empty value? I almost got the same situation, but I think my solution works well without clearing anything. Besides that I don't want to know which store to filter or have the property name hardcoded. Here is my filterfield:
Ext.define('Fiddle.form.TextField', {
extend: 'Ext.form.field.Text',
alias: 'widget.filterfield',
emptyText: 'Filter',
width: '100%',
cls: 'filter',
enableKeyEvents: true,
listeners: {
keyup: {
fn: function(field, event, eOpts) {
this.up('grid').getStore().filter(new Ext.util.Filter({
anyMatch: true,
disableOnEmpty: true,
property: field.up('gridcolumn').dataIndex,
value : field.getValue()
}));
},
buffer: 250
}
}
});
And here is the view declaration:
dataIndex: 'company',
text: 'Company',
flex: 1,
items: [{
xtype: 'filterfield'
}]

rowpos and colpos in beforShowForm

Is there an option to include rowpos and colpos in beforShowForm. I understand that it should be used under formoption setting of colModel. but my grid has customised edit (say status) and normal edit. I want different alignment for these two. below are my code for reference
bulkgrid.jqGrid('navGrid','#bulkktrackpager',{
edit: true,
add: true,
del: true,
search: true,
view: true,
//cloneToTop: true,
}).navButtonAdd('#bulkktrackpager',{
caption:"Status",
buttonicon:"ui-icon-lightbulb",
position:"last",
});
any idea???? many thanks..
}).navButtonAdd('#bulkktrackpager',{
caption:"Status",
buttonicon:"ui-icon-lightbulb",
position:"last",
onClickButton: function(){
var $self = $(this);
$self.jqGrid("editGridRow", $self.jqGrid("getGridParam", "selrow"),
{
beforeInitData: function(formid) {
bulkgrid.setColProp('status', {
formoptions : {
rowpos : 1,
colpos: 1,
},
});
bulkgrid.setColProp('ctno', {
formoptions : {
rowpos : 1,
colpos: 2,
},
});
//similaryly other elements
},
beforeShowForm: function(form) {
$("#tr_agent").hide();
},
recreateForm: true,
editData: {//Function to Add parameters to the status
oper: 'status',
},
closeAfterEdit: true,
reloadAfterSubmit: true,
});
}
});
Images
Image2
You can use rowpos and colpos properties of formoptions. You can set the values dynamically inside of beforeInitData callback. You should use recreateForm: true option additionally to be sure that jqGrid uses the current values.
The demo created for the answer demonstrate "static" usage of rowpos and colpos properties of formoptions. If you need to change alignment of all labels of the you can set text-align style (see the answer). Alternatively you can set CSS style text-align for specific labels only. You need to set the style inside of beforeShowForm callback for example.

jqGrid DatePicker filtering without hitting Enter key

I'm building my first ASP.NET MVC 3 app and using jqGrid. One of my columns, "Flavor Created", is a date column and I'd like to filter the grid on that column using the DatePicker. Here's what currently happens: The user clicks on the column header filter box, the date picker is displayed and then the user chooses the year, month and clicks a day. The picker goes away and leaves the date, say, 03/28/2009, in the text box. To actually get the filter to work, I have to click into that box and hit the Enter key, which is a bit annoying for the user.
Is there a way to have the filter automatically fire when the user clicks that day?
(As an aside, I am not sure what the use of the 'Done' button is for since the picker goes away whenever I click a day. Perhaps that is a setting I'm missing.)
Anyone else needed this functionality and solved it?
I tried to do something like this:
dataInit: function (elem) {
$(elem).datepicker({ changeYear: true, changeMonth: true, showButtonPanel: true,
onSelect: function (dateText, inst) {
$("#icecreamgrid")[0].trigger("reloadGrid");
}
})
}
as I saw someone on some website suggest, but that didn't seem to work.
You can try with
dataInit: function (elem) {
$(elem).datepicker({
changeYear: true,
changeMonth: true,
showButtonPanel: true,
onSelect: function() {
if (this.id.substr(0, 3) === "gs_") {
// in case of searching toolbar
setTimeout(function(){
myGrid[0].triggerToolbar();
}, 50);
} else {
// refresh the filter in case of
// searching dialog
$(this).trigger("change");
}
}
});
}
UPDATED: Starting with the version 4.3.3 jqGrid initialize the DOM of grid as this of dataInit. Thus one don't need to use myGrid variable in the above code. Instead of that one can use:
dataInit: function (elem) {
var self = this; // save the reference to the grid
$(elem).datepicker({
changeYear: true,
changeMonth: true,
showButtonPanel: true,
onSelect: function() {
if (this.id.substr(0, 3) === "gs_") {
// in case of searching toolbar
setTimeout(function () {
self.triggerToolbar();
}, 50);
} else {
// refresh the filter in case of
// searching dialog
$(this).trigger("change");
}
}
});
}
Free jqGrid calls with the second options parameter of dataInit, which contains additional information, like the mode property. The value of mode property is "filter" in case of calling inside of the filter toolbar (and "search" in case of searching dialog). Thus one can use the following code
dataInit: function (elem, options) {
var self = this; // save the reference to the grid
$(elem).datepicker({
changeYear: true,
changeMonth: true,
showButtonPanel: true,
onSelect: function() {
if (options.mode === "filter") {
// in case of searching toolbar
setTimeout(function () {
self.triggerToolbar();
}, 0);
} else {
// refresh the filter in case of
// searching dialog
$(this).trigger("change");
}
}
});
}

Resources