Jqgrid Setting Options From different Javascript files - javascript

I want to centralize the options for my jqgrids into one javascript file that all my grids can use. Such as if its sortable, height, width and the methods such as onSelectRow and loadComplete. I then want to load the options which are specific to that grid such as colModel, caption and sort order in a different javascript file for example
GridMain.js
datatype: 'local',
height: 'auto',
width: 'auto',
pager: $('#pager'),
rowNum: 10,
rowList: [5, 10, 20, 50],
sortorder: "asc",
viewrecords: true,
sortable: true,
onSelectRow: function (id) {
//redirect to brand details page
document.location.href = url + id;
}
UserGrid.js
colModel: [
{ name: 'Id', index: 'Id', hidden: true, key: true },
{ name: 'Name', index: 'Name', width: 250, align: 'left' },
{ name: 'Disabled', index: 'Deleted', width: 100, align: 'left' },
{ name: 'Actions', index: 'Actions', width: 150, align: 'center', sortable: false, title: false}],
sortname: 'Name',
caption: "Users"
});
I have tried many different ways and i cant seem to figure it out. I tried using the setGridParam method but height, width, colModel cant be changed after the grid is created.
I am using tableToGrid('.table-to-grid', { options }); to initialize my grid
Any help would be appreciated. Thanks

You can include in the GridMain.js the code like
$.extend($.jgrid.defaults, {
datatype: 'local',
viewrecords: true,
height: 'auto',
...
});
(see here for more information).
You can also confider to defining column templates (see here).
I don't recommend you to use tableToGrid and better create jqGrid directly.

Related

Subgrid not getting populated in free jqGrid

I am trying to add subgrid to every row of main grid. The main grid populates fine but when i click on the expand icon of a row subgrid is not populated. Only subgrid column headers appear.
The json data is a single nested data structure which is fetched only once when grid loads first time. So when i click on the grid expand icon i expect subgrid to be populated from the data that was fetched while displaying the parent grid.
The empty subgrid is displayed when i use - datatype: "local".
If i set datatype: "json" then a server side call is made to fetch data if i click on expand icon.
So how can i display subgrid using the single json data that was already fetched. Thanks
Please find sample code below,
$(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/items",
datatype: "json",
mtype: "POST",
autowidth: true,
loadBeforeSend: function(jqXHR) {
jqXHR.setRequestHeader("X-CSRF-TOKEN", $("input[name='_csrf']").val());
},
colNames: ["Id", "Item Type", "Item Code"],
colModel: [
{ name: "id", width: 35, sorttype:"int", search: false, editable: false, key: true, hidden: true},
{ name: "itemType", width: 100},
{ name: "itemCode", width: 120}
],
maxHeight: 400,
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",
subGrid: true,
subGridRowExpanded: function (subgridId, rowid) {
var subgridTableId = subgridId + "_t";
$("#" + subgridId).html("<table id='" + subgridTableId + "'></table>");
$("#" + subgridTableId).jqGrid({
datatype: "local",
data: $(this).jqGrid("getLocalRow", rowid).itemDetails,
colNames: ["Id", "Unit", "Stock", "Batch No.", "Expiry Date", "Quantity Per Unit", "Price"],
colModel: [
{ name: "id", width: 35, sorttype:"int", search: false, editable: false, key: true, hidden: true},
{ name: "unit", width: 70, search: false},
{ name: "availableQuantity", width: 55, search: false, formatter: "number",},
{ name: "batchNumber", width: 80, search: false},
{ name: "expiryDate", width: 80, search: false, sorttype: "date", formatoptions: {srcformat:'d/m/Y', newformat:'d/m/Y'}},
{ name: "quantityPerUnit", width: 80, search: false, formatter: "number"},
{ name: "price", width: 55, search: false, formatter: "number"}
],
height: "100%",
rowNum: 10,
idPrefix: "s_" + rowid + "_",
cmTemplate: {editable: true},
editurl: "${pageContext.request.contextPath}/billing/saveItem"
});
}
}).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 });
});
The sample json data:-
[{"id":1,"itemCode":"Omez","itemType":"Medicine","itemDesc":"Omez for acidity","itemDetails":[{"id":1,"batchNumber":"batch1","expiryDate":"01/06/2018","unit":"bottle","subUnit":"tablet","availableQuantity":120.0,"quantityPerUnit":60.0,"price":122.0}]}]
First of all it's important to understand that the data, returned from url will be read and saved locally in case of usage loadonce: true option of jqGrid. By default it read only the data for the columns of the grid and the property id (can be configured by id property of prmNames parameter). Free jqGrid allows to read and save any other additional properties. To specify the properties one can use additionalProperties. The simplest for of the usage would be
additionalProperties: ["itemDetails"]
It informs jqGrid to read and save locally itemDetails property of every item. After that $(this).jqGrid("getLocalRow", rowid).itemDetails will work.
Additionally you can remove the column id from colModel. jqGrid set id attribute of the rows based on the value of id property of input data (returned from the server). Thus you don't need to hold the duplicate information in hidden <td> cell of every row. You can remove the id column from both main grid and the subgrid.
If you want to set search: false for all columns of subgrid then you can use cmTemplate: {search: false} option of subgrid and remove search: false from all columns. In the same way you can include in cmTemplate the property width: 80 (cmTemplate: {search: false, width: 80}) to change the default value 150 for the width property to 80. After that you can remove width: 80 from tree columns of subdrid too.
You can remove sortorder: "asc" and height: '100%' properties, because there are default for free jqGrid. You can use
searching: {
stringResult: true,
searchOnEnter: false,
defaultSearch: 'cn'
}
The property autosearch: true (not autoSearch: true) are default. After that you can use filterToolbar without additional parameters.
I would recommend you to use additional option of navGrid: reloadGridOptions: { fromServer: true } which informs to reload the data from the server (by restoring original value of datatype) if the user clicks on Refresh button of navigator bar.

Search and sorted doesn't work in JqGrid (json)

I am working with JqGrid.
I have some JSON from server
[{"Id":1,"Name":"product1","Price":234,"Size":"Small"},{"Id":18,"Name":"product2","Price":3242,"Size":"Large"}]
and Jquery code
$("#table").jqGrid({
url: '#Url.Action("GetProductsAtJSON", "Product")',
datatype: 'json',
mtype: 'GET',
colNames: ['Id', 'Name', 'Price', 'Size'],
colModel: [
{ name: 'Id', index: 'Id', width: 55, key: true, editable: true, editoptions: { readonly: true }, sortable: true, search:true },
{ name: 'Name', index: 'Name', width: 150, editable: true, editoptions: { size: 25 }, editrules: { required: true }, search: true },
{ name: 'Price', index: 'Price', width: 100, align: 'center', editable: true, editoptions: { size: 25 }, editrules: { required: true, number: true, minValue: 1, maxValue: 10000 } },
{ name: 'Size', index: 'Size', width: 150, editable: true, edittype: "select", editoptions: { value: "0:Large;1:Medium;2:Small" } }
],
pager: '#pager',
rowNum: 10,
rowList: [10, 20, 30],
sortname: 'Id',
sortorder: "asc",
viewrecords: true,
caption: 'All product',
height: '400',
jsonReader: {
repeatitems: false,
loadonce: true,
id: "Id",
root: function (obj) { return obj; },
page: function (obj) { return 1; },
total: function (obj) { return 1; },
records: function (obj) { return obj.length; }
}
});
I have read the documentation and a lot of forums, but I don't understand why sorting and search doesn't work. Maybe my JSON format is incorrect and I must write total page records, but that's not working either. I use key: true from rows id, but it's not working.
What am I doing wrong?
There are some small errors in your code:
loadonce: true is jqGrid option and not the property of jsonReader
You should use sorttype property for columns which content should be interpreted not as a text. For example you should add sorttype: "integer" to the definition of 'Id' and 'Price' columns
I recommend you to consider whether the value editoptions: {value: "0:Large;1:Medium;2:Small"} is what you need. It will be important for edition only.
I recommend you additionally to use gridview: true to improve performance of the grid, use autoencode: true to interpret the values in JSON input as textes instead of HTML fragments and use height: 'auto' to have better look of the grid.
To have local searching of data you need either use navGrid or filterToolbar.
The demo is an example of fixing of your code.

Why does jqGrid refuses to call it's Ajax Call more than once using the OnSelectRow Event

I have a problem with my two jqGrid grids. First I have one grid with some data that works just fine. It has an loadComplete event which sets the first row as selected. This is so that the second jqGrid gets populated based on the selected row (id) on the first jqGrid.
I have an onSelectRow event on the first grid which calls a function which contains the $('#grid).jqGrid() call of the second grid. This second grid has en url which links to a method in a controller which gets some data from a database.
This works all fine for the first selectrow (which happends automatically after the loadComplete).
My problem is that the second jqGrid doesnt repopulate after I select a different row. The programm never gets to the method in the controller (I tested with some logging). I'm really stuck at this since it works for the first load but not the second and so on.
$("#fontsgrid").jqGrid({
url: 'getfonts',
mtype: "post",
datatype: "json",
sortable: true,
colNames: ['Name', 'Family', 'Cost', 'Lic', 'File', 'Added', 'Mod', 'Add', 'Edit'],
colModel: [
{ name: 'name', index: 'name', width: 90, sorttype: "text", sortable: true, align: 'left'},
{ name: 'family', index: 'family', width: 100, sorttype: "text", sortable: true},
{ name: 'cost', index: 'cost', width: 60, sorttype: "currency", sortable: true, formatter: 'currency', formatoptions: {decimalSeparator: ",", thousandsSeparator: ",", decimalPlaces: 2, prefix: "€ "}},
{ name: "licenses", index: "licenses", width: 30, sorttype: "int", sortable: true},
{ name: "filename", index: "filename", width: 90, sorttype: "text", sortable: true},
{ name: "date_upload", index: "date_upload", width: 80, sortable: true, sorttype: "date", formatter: "date", formatoptions: { newformat: 'Y-m-d' }},
{ name: "date_edit", index: "date_edit", width: 80, sortable: true, sorttype: "date", formatter: "date", formatoptions: { newformat: 'Y-m-d' }},
{name: "add_cart", index: 'add_cart', width: 70},
{name: "edit", index: "edit", width: 30}
],
rowNum: 100,
width: 580,
height: 359,
rowList: [100, 250, 500],
sortname: "name",
sortorder: 'asc',
viewrecords: true,
gridview: true,
caption: "Font List",
pager: $('#pager'),
loadComplete: function () {
$('#fontsgrid').jqGrid('setSelection', $("#fontsgrid tr[role]").next().attr("id"));
},
onSelectRow: function (id) {
loadInstallGridFonts(id);
}
}).navGrid('#pager', {edit: false, add: false, del: false});
function loadInstallGridFonts($fontid) {
$('#installGridFonts').jqGrid({
url: 'getinstallations',
mtype: "post",
datatype: "json",
sortable: true,
postData: {'fontid': $fontid},
colNames: ['Installation', 'Bedrijfsnaam', 'Date Installed', 'Edit'],
colModel: [
{ name: 'installation', index: 'installation', width: 90, sorttype: "text", sortable: true, align: 'left'},
{ name: 'bedrijf', index: 'bedrijf', width: 100, sorttype: "text", sortable: true},
{ name: "date_installed", index: "date_installed", width: 80, sortable: true, sorttype: "date", formatter: "date", formatoptions: { newformat: 'Y-m-d' }},
{name: "edit", index: "edit", width: 30}
],
rowNum: 50,
width: 480,
height: 359,
altRows: 'true',
rowList: [50, 75, 100],
sortname: "installation",
sortorder: 'asc',
viewrecords: true,
gridview: true,
caption: "Installation List",
pager: $('#pagerInstall')
}).navGrid('#pagerInstall', {edit: false, add: false, del: false});
}
'getfonts' and 'getinstallations' are both aliases for a controller/method used in routing (codeIgniter).
The problem is that the programm only goes to the method behind the 'getinstallations' once and not after a new rowselect.
I see many problems in your code. First of all it's important to understand that the code like
$('#installGridFonts').jqGrid({
...
});
create the grid. It means that it convert <table> element, which you placed initially on the page, to relatively complex structure of divs and tables (see here for examples). The consequence of it: you can make such call only once. If you try to create the same grid at the second time jqGrid verify that the grid already exist and do nothing. It's exactly what you can see.
One more important thing is the following: jqGrid creates the structure of divs and tables which represent the grid once, but it can fill the body of the grid (the data inside of the grid) multiple times. If you need to fill the grid with the data returned from the server you should just set parameters of the grid (url, datatype, postData and so on) and then make $("#installGridFonts").trigger("reloadGrid"). The reloading means executing new request to the server and loading the data in the the grid.
So the code could be about the following:
// we will use navGrid below more as once without editing buttons
// so we change defaults of navGrid with the folling settings
$.extend($.jgrid.nav, {edit: false, add: false, del: false});
// creates the second grid. because we don't want to make any request
// to the server at the time we will use datatype: "local"
$("#installGridFonts").jqGrid({
datatype: "local",
...
}).jqGrid("navGrid", "#pagerInstall");
// create the first grid
$("#fontsgrid").jqGrid({
...
onSelectRow: function (rowid) {
$("#installGridFonts").jqGrid("setGridParam", {
datatype: "json",
postData: {fontid: rowid}
}).trigger("reloadGrid");
}
}).jqGrid("navGrid", "#pager");
If it's required you can hide the second grid directly after creating and show it inside of onSelectRow callback.

jqGrid issue grouping - Duplicate rows get appended every time sort is changed

I'm using jqGrid and have added grouping to one of my grids. Everything worked fine when grouping was not enabled, however once I added:
grouping: true,
groupingView: { groupField: ['ProjName'], groupDataSorted: true }
I started running into some strange behavior. When I click one of the column headers to change the sort order, instead of clearing the existing rows in the grid, new rows are appended to the end of the grid with all the groups being duplicated.
In other words, when the page first draws, I see this:
Then, I click on a sort header and I get this:
My initialization code is as follows:
var gridMyTasks = $('#gridMyTasks').jqGrid({
jsonReader: { root: 'rows', repeatitems: false, id: 'ID' },
datatype: 'json',
colNames: ['Task ID', 'Task Name', 'Project Name', 'Task Stage', 'Doc Type', 'Due Date'],
colModel: [
{ name: 'ShortCode', width: 70, jsonmap: 'ShortCode' },
{ name: 'TaskName', width: 200, jsonmap: 'TaskName', formatter: 'fmtTaskName' },
{ name: 'ProjName', width: 200, jsonmap: 'ProjName', formatter: 'fmtName' },
{ name: 'TaskStage', width: 100, jsonmap: 'TaskStage' },
{ name: 'DocType', width: 130, jsonmap: 'DocType' },
{ name: 'DueDate', width: 70, jsonmap: 'DueDate' }
],
rowNum: 0,
height: 'auto',
autowidth: true,
forceFit: true,
multiselect: false,
caption: '',
altclass: 'zebra',
altRows: true,
hoverrows: false,
gridview: true,
grouping: true,
groupingView: { groupField: ['ProjName'], groupDataSorted: true }
});
My loader code (which is called again on sort) looks like this:
loader(limit, curSort, curDir, function (results) {
grid[0].addJSONData({ rows: results });
$('body').hideLoading();
link.html(expanded ? 'Show less...' : 'Show all...');
},
null);
(loader is an AJAX call to the server) - I'm thinking maybe I need to do something to clear out all the existing rows? However, why did it work perfectly fine before I had grouping enabled?
I figured it out. I had the following code:
grid.setGridParam({
onSortCol: function (index, iCol, sortorder) {
wait();
curSort = index;
curDir = (sortorder == 'desc');
loadGrid(expanded ? null : 15);
return 'stop'; // <--- Problem
}
});
When I commented out return 'stop' then the problem went away. I'm not entirely sure why I had this to begin with, I think I was trying to disable any sort of built in sorting.

JQuery jqGrid vertical spacing issue in IE

I have been developing an app to use jQuery's jqGrid plugin, and I thought I had it all wrapped up until I tried to view the grid in IE. In IE, the grid appears with a much larger height in the .ui-jqgrid-view div, but the data itself stays at a smaller size and displays at the bottom of the container div (.ui-jqgrid-view). I need to get the grid to display "properly". I don't care if it is the larger size (that IE displays) or smaller (as in FF)... I just need to have the data fill the grid area. Thanks!
I uploaded a screenshot: here
Grid Code:
$("#list").jqGrid({
url: gDataPath,
datatype: 'json',
mtype: 'GET',
colNames: ['Id', 'VId', 'First Name', 'Last Name', 'MId'],
colModel: [
{ name: 'ID1', index: 'ID1', width: 75, align: 'left' },
{ name: 'VID', index: 'VID', width: 75, align: 'left' },
{ name: 'FirstName', index: 'FirstName', width: 225, align: 'left' },
{ name: 'LastName', index: 'LastName', width: 225, align: 'left' },
{ name: 'MIDno', index: 'MIDno', width: 260, align: 'left'}],
pager: jQuery('#pager'),
rowNum: 100,
rowList: [50, 100, 200, 500],
sortname: 'ID1',
sortorder: "desc",
viewrecords: true,
imgpath: 'http://mysite/Content/images',
caption: 'Project Name Data',
ondblClickRow: function(rowid, iRow, iCol) {
var i = jQuery("#list").getRowData(rowid);
window.location = '<%=linkPath %>/'+ i.VisitID;
}
});
Try with <table id="list"></table> as container. I don't think divs is proper container for jqGrid. Then you can wrap the table tag within any div.

Categories