jqGrid tree grid with local data - javascript

jqGrid docs for tree grid says:
"Currently jqGrid can work only with data returned from server. There are some tricks and articles which describes how to work with local data."
Fair enough, but I was unable to find such articles. Any hints on how I can achieve it, preferably with equivalent of datatype=local?

Probably this old answer could help you. The demo which used the last current version of jqGrid you can find here.
UPDATED: Now I would be prefer to use datatype: "jsonstring" which is almost the same as datatype: "local". One need to use datastr: mydata instead of data: mydata in the case. Additionally one have to use jsonReader as function. As the result one will have the following modified demo.
The corresponding code of the demo you find below
var mydata = [
{ id:"1", name:"Cash", num:"100", debit:"400.00",credit:"250.00", balance:"150.00", enbl:"1",
level:"0", parent:"", isLeaf:false, expanded:false, loaded:true },
{ id:"2", name:"Cash 1", num:"1", debit:"300.00",credit:"200.00", balance:"100.00", enbl:"0",
level:"1", parent:"1", isLeaf:false, expanded:false, loaded:true },
{ id:"3", name:"Sub Cash 1", num:"1",debit:"300.00",credit:"200.00", balance:"100.00", enbl:"1",
level:"2", parent:"2", isLeaf:true, expanded:false, loaded:true },
{ id:"4", name:"Cash 2", num:"2",debit:"100.00",credit:"50.00", balance:"50.00", enbl:"0",
level:"1", parent:"1", isLeaf:true, expanded:false, loaded:true },
{ id:"5", name:"Bank\'s", num:"200",debit:"1500.00",credit:"1000.00", balance:"500.00", enbl:"1",
level:"0", parent:"", isLeaf:false, expanded:true, loaded:true },
{ id:"6", name:"Bank 1", num:"1",debit:"500.00",credit:"0.00", balance:"500.00", enbl:"0",
level:"1", parent:"5", isLeaf:true, expanded:false, loaded:true },
{ id:"7", name:"Bank 2", num:"2",debit:"1000.00",credit:"1000.00", balance:"0.00", enbl:"1",
level:"1", parent:"5", isLeaf:true, expanded:false, loaded:true },
{ id:"8", name:"Fixed asset", num:"300",debit:"0.00",credit:"1000.00", balance:"-1000.00", enbl:"0",
level:"0", parent:"", isLeaf:true, expanded:false, loaded:true }
],
grid = $("#treegrid");
grid.jqGrid({
datatype: "jsonstring",
datastr: mydata,
colNames:["Id","Account","Acc Num","Debit","Credit","Balance","Enabled"],
colModel:[
{name:'id', index:'id', width:1, hidden:true, key:true},
{name:'name', index:'name', width:180},
{name:'num', index:'acc_num', width:80, align:"center"},
{name:'debit', index:'debit', width:80, align:"right"},
{name:'credit', index:'credit', width:80,align:"right"},
{name:'balance', index:'balance', width:80,align:"right"},
{name:'enbl', index:'enbl', width: 60, align:'center',
formatter:'checkbox', editoptions:{value:'1:0'},
formatoptions:{disabled:false}}
],
height: 'auto',
gridview: true,
rowNum: 10000,
sortname: 'id',
treeGrid: true,
treeGridModel: 'adjacency',
treedatatype: "local",
ExpandColumn: 'name',
caption: "Demonstrate how to use Tree Grid for the Adjacency Set Model",
jsonReader: {
repeatitems: false,
root: function (obj) { return obj; },
page: function (obj) { return 1; },
total: function (obj) { return 1; },
records: function (obj) { return obj.length; }
}
});
UPDATED 2: One should use parent:"null" or parent:null instead of parent:"".

Related

JavaScript display fetched object in html table

I have a fetch function that looks like this
let url = 'someurl.com';
var dataObject_ = [];
fetch(url)
.then((res) => res.json())
.then(output => {
var huj = output;
// console.log(huj);
dataObject_.push.apply(dataObject, huj);
}
);
console.log(huj) outputs -> Array(10)
0: {wine_country: "France", wine_name: "Lafite Rothschild", wine_region: "Bordeaux Premier Cru - left bank", wine_year: 2016}
1: {wine_country: "France", wine_name: "Lafite Rothschild", wine_region: "Bordeaux Premier Cru - left bank", wine_year: 2000}
etc...
and I have table that looks like that
var hotSettings = {
data: dataObject_,
columns: [
{
data: 'wine_name',
type: 'text'
},
{
data: 'wine_year',
type: 'numeric'
},
{
data: 'wine_region',
type: 'text'
},
{
data: 'wine_country',
type: 'text'
},
],
stretchH: 'all',
width: 805,
autoWrapRow: true,
height: 487,
maxRows: 22,
manualRowResize: true,
manualColumnResize: true,
rowHeaders: true,
colHeaders: [
'Wine',
'Year',
'Region',
'Country'
],
manualRowMove: true,
manualColumnMove: true,
contextMenu: true,
filters: true,
dropdownMenu: true
};
My goal is to use dataObject_ to display it in the table. When I create a variable and just copypaste json from API it works fine, but when I get data from API call and push it to the array it doesnt output it somehow. I tried different ways of doing it, nothing works. The JSON itself looks like this
{
"wine_country": "France",
"wine_name": "Petrus",
"wine_region": "Bordeaux Pomerols - right bank",
"wine_year": 1990
},
{
"wine_country": "France",
"wine_name": "Petrus",
"wine_region": "Bordeaux Pomerols - right bank",
"wine_year": 1989
}
I am sorry, i am a completely beginner in JavaScript / front-end and if this looks ridiculous
Basically, once you define variable g, that gets stored in global memory with the value that h has. It won't update once h changes because it has no idea what h is. It was only concerned about the value it was holding while initialization.

How to make dojo treeGrid categorized by two columns?

I have a simple dojo treeGrid that is categorized just by first column. But how to make it categorized/collapsible by second as well? Note the treeGrid has totals shown in each category. Also, is there a way to move totals to the category level but not to the bottom?
var layout = [
{ cells: [
[ {field: "year", name: "Year"},
{field: "childItems",
children: [ { field: "unid", name: "unid", hidden: true},
{ field: "geography", name: "Geography"},
{ field: "country", name: "Coungtry"},
{ field: "status", name: "Status"},
{ field: "credit", name: "Credit"},
{ field: "debit", name: "Debit"}
],
aggregate: "sum"
}
]] } ]
var jsonStore = new dojo.data.ItemFileWriteStore({ url: <...............>});
var grid = new dojox.grid.TreeGrid({
structure: layout,
store: jsonStore,
query: {type: 'year'},
queryOptions: {deep: true},
rowSelector: true,
openAtLevels: [false],
autoWidth: true,
autoHeight: true
},
dojo.byId("treeGrid"));
grid.startup();
dojo.connect(window, "onresize", grid, "resize");
sample JSON store:
{
"identifier": "id",
"label": "name",
"items": [
{
"id": "2018",
"type": "year",
"year": "2018",
"childItems": [
{
"id": "id0",
"geography": "Asia Pacific",
"country": "Australia",
"programname": "Program 1",
"totalPlanned": 0,
"totalForecasted": 0
},
{
.....
}
]
},
{
.....
}
]
}
You can find completely working example over here:
Now, let me try to explain it:
Data
First of all to support multiple levels in the grid you must have your data in the same format. For tree with n levels, you need to have n-1 level grouping in your data itself.
For example, JSON object below have 2 levels of grouping (year, geography) to support tree with 3 levels (root, parent, and child).
{
"identifier":"id",
"label":"name",
"items":[
{
"id":"2018",
"type":"year",
"year":"2018",
"geography":[
{
"id":"id1",
"geography":"Asia Pacific",
"childItems":[
{
"id":"ci1",
"country":"Australia",
"programname":"Program 1",
"credit":100,
"debit":50
}
]
}
]
}
]
}
Layout
To render a tree with n-levels you have to make sure layout of the tree is properly configured with same nesting as your data. To support data structure from JSON object above you need to set layout to:
[
{
cells:
[
[
{ field:"year", name:"Year" },
{
field:"geography",
children:
[
{ field:"geography", name:"Geography" },
{
field:"childItems",
children:[
{ field:"unid", name:"unid", hidden:true },
{ field:"country", name:"Country" },
{ field:"programname", name:"Program" },
{ field:"credit", name:"Credit" },
{ field:"debit", name:"Debit" }
],
aggregate:"sum",
},
]
}
]
]
}
]
You can see that, for each child level(s) you have to add a group (as I would like to call it) field and set first field within that group to your actual group field.
I hope this example will clear your doubt.
PS: In the jsfiddle version I have used formatters just to hide aggregate values for string fields.

jquery DataTables Editor: "select" field displays option value instead of label

I am using jquery's DataTables which is really working great. Then only problem I got is, that I am facing (in non-edit-view) the value of the select-field (which is an id). The user of course doesn't want to see the id of course.
Therefore I am looking for a possibility to configure that column in a way to show always the value of label property.
Here a some snippets:
$(document).ready(function() {
var table = $('#overviewTable').DataTable({
dom: "Tfrtip",
ajax: "/Conroller/GetTableData",
columns: [
{ data: "Id", className: "readOnly", visible: false },
{
data: "LoanTransactionId",
className: "readOnly readData clickable",
"fnCreatedCell": function(nTd, sData, oData, iRow, iCol) {
$(nTd).html("<a href='#'>" + oData.LoanTransactionId + "</a>");
}
},
{ data: "Id", className: "readOnly" },
{ data: "property_1", className: "readOnly" },
{ data: "Priority" },
{ data: null, className: "action readOnly", defaultContent: 'Info' }
],
order: [1, 'asc'],
tableTools: {
sRowSelect: "os",
sRowSelector: 'td:first-child',
aButtons: []
}
});
// data reload every 30 seconds
setInterval(function() {
table.ajax.reload();
}, 30000);
editor = new $.fn.dataTable.Editor({
ajax: "PostTable",
table: "#overviewTable",
fields: [
{
label: "Id",
name: "Id"
},
{
label: "Column 1",
name: "property_1"
},
{
label: "Priority",
name: "Priority",
type: "select",
options: [
{ label: "low", value: 0 },
{ label: "mid", id: 1 },
{ text: "high", id: 2 }
]
}
]
});
// Inline Edit - only those who are not readOnly
$('#overviewTable').on('click', 'tbody td:not(:first-child .readOnly)', function(e) {
editor.inline(this, {
submitOnBlur: true
});
});
How it looks in the display mode
How it looks in the edit mode
See the documentation on columns.render
You want to modify your column options for priority
Preferred Option: Your data source has a field with the priority as a string
This is the best option, as you don't want to have two places with this business logic. Keep it out of the client code.
Also, you will want to modify the editor as well so that the options used have been retrieved dynamically from the server to keep this business logic out of the client too. This is left as an exercise for the reader.
Since you don't provide details on what your data structure looks lik, I'm assuming it is an object, and it has an attribute priorityAsString so use the string option type for render.
columns: [
...
{
data: "Priority" ,
render: "priorityAsString",
},
Option 2) You write a function to map priority to string
Do this if you can't get the data from the server. But remember you will need to update many places when the priority list changes.
columns: [
...
{
data: "Priority" ,
render: renderPriorityAsString,
},
...
function renderPriorityAsString(priority) {
const priorityToString = {
0: 'low',
1: 'med',
2: 'high',
};
return priorityToString[priority] || `${priority} does not have a lookup value`;
}
"render": function ( data, type, full ) { return label;}

Datatables with serverside JSON (custom object)

I am trying to quickly create a simple display of results from an internal API using DataTables. The API returns JSON in the following structure:
obj {
status: 1,
results: 100,
offset: 25,
limit: 25,
data: [
[1]: {
title: "Blah blah one",
description: "Doesn't really matter",
misc: "Yadda yadda"
},
[2]: {
title: "Blah blah two",
description: "Doesn't really matter",
misc: "Yadda yadda"
},
]
}
I can't/don't want to change the API structure just because DataTables uses a weird structure, but I would like to access the built in functionalities for paging, dynamic loading, etc. DataTables seems to allow for custom data objects, and I've gotten the table to load with the following:
$(document).ready(function() {
$('#example').dataTable( {
"bProcessing": true,
"bServerSide": true,
"sAjaxSource": "http://api.oursite.com/api?limit=100",
"fnServerData": function( sUrl, aoData, fnCallback, oSettings ) {
oSettings.jqXHR = $.ajax( {
"url": sUrl,
"data": aoData,
"success": fnCallback,
"dataType": "jsonp",
"cache": false
} );
},
"sAjaxDataProp": "data",
"aoColumns": [
{ "mData": "title" },
{ "mData": "description" },
{ "mData": "misc" },
]
} );
});
But, none of the paging or sorting functions work. I think this is because DataTables requires a results count and paging variable in the object— "iTotalRecords" and "iTotalDisplayRecords". Is this correct? Is there any way to use the api variables instead? Thanks in advance. I'm currently not getting any errors in the dev console, so if it's erroring it's doing so silently...
While initializing the datatable, instead of directly assigning source to Ajaxsource, you can set the aaData to the javascript function where you can manipulate to return only obj.data. You need handle few things manually.
$('#tblExample').dataTable({
"bJqueryUI": true,
"bDestroy":true,
"bSortable": false,
"sAjaxSource": "",
"aaData":GetData(),
"aoColumns": [
{
"sTitle":"Index","mDataProp": null, "sWidth": "20px", "sDefaultContent": "<span class='ui-icon ui-icon-circle-close' onclick='RemoveActiveItem(this);'></span>", "bSortable": false},
{ "mDataProp": "Year"},
{ "mDataProp": "Month"},
{ "mDataProp": "Savings"}
]
});

jqGrid remove column headers from subgrid

I am using jqGrid-4.4.1 subGrid functionality.
In my case I want to remove Column headers from subGrid for each row.
I tried
var grid = $("#list");
var gview = grid.parents("div.ui-jqgrid-view");
gview.children("div.ui-jqgrid-hdiv").hide();
from this link. But, It removes header of main table, rather than subgrid.
I found an alternative but its HTML based.
How to remove the table column headers from Jqgrid subgrid
Also, How can I to remove carot sign the from the first column when row is expanded.
Here is the snapshot. I want to remove the border marked red.
In general you use the correct way to hide the column headers. The only problem is that you need to use hiding with the correct grid. Typically one creates subgrid as grid inside of subGridRowExpanded callback. jqGrid create <div> where you should place new subgrid. The id of the div you get as the first parameter of subGridRowExpanded callback (see the documentation for more details). So one creates subgrid with some id constructed typically based on the id of the div. If you would use the id of the subgrid instead of #list you will be able to hide the column headers of the subgrid.
The demo demonstrate such implementation:
Below is the code which I used for the demo
var myData = [
{
id: "10",
c1: "My Value 1",
c2: "My Value 1.1",
subgridData: [
{ id: "10", c1: "aa", c2: "ab" },
{ id: "20", c1: "ba", c2: "bb" },
{ id: "30", c1: "ca", c2: "cb" }
]
},
{
id: "20",
c1: "My Value 2",
c2: "My Value 2.1",
subgridData: [
{ id: "10", c1: "da", c2: "db" },
{ id: "20", c1: "ea", c2: "eb" },
{ id: "30", c1: "fa", c2: "fb" }
]
},
{
id: "30",
c1: "My Value 3",
c2: "My Value 3.1",
subgridData: [
{ id: "10", c1: "ga", c2: "gb" },
{ id: "20", c1: "ha", c2: "hb" },
{ id: "30", c1: "ia", c2: "ib" }
]
}
],
$grid = $("#list"),
mainGridPrefix = "s_";
$grid.jqGrid({
datatype: "local",
data: myData,
colNames: ["Column 1", "Column 2"],
colModel: [
{ name: "c1", width: 180 },
{ name: "c2", width: 180 }
],
rowNum: 10,
rowList: [5, 10, 20],
pager: "#pager",
gridview: true,
ignoreCase: true,
rownumbers: true,
sortname: "c1",
viewrecords: true,
autoencode: true,
height: "100%",
idPrefix: mainGridPrefix,
subGrid: true,
subGridRowExpanded: function (subgridDivId, rowId) {
var $subgrid = $("<table id='" + subgridDivId + "_t'></table>"),
pureRowId = $.jgrid.stripPref(mainGridPrefix, rowId);
$subgrid.appendTo("#" + $.jgrid.jqID(subgridDivId));
$subgrid.jqGrid({
datatype: "local",
data: $(this).jqGrid("getLocalRow", pureRowId).subgridData,
colModel: [
{ name: "c1", width: 178 },
{ name: "c2", width: 178 }
],
height: "100%",
rowNum: 10000,
autoencode: true,
gridview: true,
idPrefix: rowId + "_"
});
$subgrid.closest("div.ui-jqgrid-view")
.children("div.ui-jqgrid-hdiv")
.hide();
}
});
$grid.jqGrid("navGrid", "#pager", {add: false, edit: false, del: false});
UPDATED: The answer shows how to implement resizing of columns of subgrid after resizing of the columns of the main grid.

Categories