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.
Related
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.
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.
I have one widget column header by which I am selecting the value and filtering the grid store. I want exact the same on grid header as well. There for I am giving one combo with same values.
Here is my code for column header
header: {
items: [{
xtype: 'combo',
displayField: "displayName",
fieldLabel: 'Some Label',
valueField: 'title',
displayField: 'title',
hidden : true,
queryMode: 'local',
value : 1,
autoSelect : true,
//dataindex:"MUTST",
store: {
fields: ["id", "displayName"],
data: [
{ "id": "1", "title": "Test1" },
{ "id": "2", "title": "Test2" },
{ "id": "3", "title": "Test3" }
]
},
listeners : {
select : function(combo , record , eOpts){
debugger;
var sg = this.up("MyGrid");
var col = sg.getColumns()[0]; // Getting Header column
var flit =sg.getColumns()[0].filter // Here I am getting object instead of constructor
//this.focus = sg.onComboFilterFocus(combo);
}
},
}]
},
I am creating widget type in column
MyColumn: function(headersXmlDoc) {
var me = this,
gridConfig = {};
gridConfig.columns = [];
Ext.each(headersXmlDoc.getElementsByTagName("HEADER"), function(header) {
var column = {
text: header.getAttribute("L"),
dataIndex: header.getAttribute("DATAINDEX"),
sortable: (header.getAttribute("ISSORTABLE").toLowerCase()=="true"),
widgetType: header.getAttribute("WIDGET"),
filterType: Ext.isEmpty(header.getAttribute("FILTER"))? undefined: header.getAttribute("FILTER"),
};
switch (header.getAttribute("WIDGET")) {
case 'textbox':
if(column.filterType){
if(column.filterType == 'TagData'){
column.filter = {
xtype: 'tagfield',
growMax : 10,
valueField: 'title',
displayField: 'title',
parentGrid : me,
dataIndex:header.getAttribute("DATAINDEX"),
queryMode: 'local',
multiSelect: true,
isFilterDataLoaded: false,
disabled: true,
listeners:{
focus: me.SomeMethod, //
}
};
}
}
break;
}
this.columns.push(column);
}, gridConfig);
return gridConfig.columns;
},
I want if I select in header combo, it will directly select in widget combo as well. Can anyone explain how to get this. Thanks in advance
So you basically need a combo box in your header, that changes record values - the fact that you have a widget column displaying a combo within the grid cells doesn't really matter here.
I think you were fairly close - but you were trying to define a "header" config and add the combo to its items - instead you just define items directly on the column:
columns: [{
text: 'Combo Test',
dataIndex: 'title',
items: [{
xtype: 'combobox',
width: '100%',
editable: false,
valueField: 'title',
displayField: 'title',
queryMode: 'local',
autoSelect: true,
store: {
data: [{
"id": "1",
"title": "Test1"
}, {
"id": "2",
"title": "Test2"
}, {
"id": "3",
"title": "Test3"
}]
},
listeners: {
select: function (combo, selectedRecord) {
//we could just get the value from the combo
var value = combo.getValue();
//or we could use the selectedRecord
//var value = selectedRecord.get('id');
//find the grid and get its store
var store = combo.up('grid').getStore();
//we are going to change many records, we dont want to fire off events for each one
store.beginUpdate();
store.each(function (rec) {
rec.set('title', value);
});
//finish "mass update" - this will now trigger any listeners for saving etc.
store.endUpdate();
//reset the combobox
combo.setValue('');
}
}
}],
},
The actual setting of values happens in the select listener as you were trying - the key is to loop through the records and call set on each one:
//find the grid and get its store
var store = combo.up('grid').getStore();
//we are going to change many records, we dont want to fire off events for each one
store.beginUpdate();
store.each(function (rec) {
rec.set('title', value);
});
//finish "mass update" - this will now trigger any listeners for saving etc.
store.endUpdate();
I have created a fiddle to show this working:
https://fiddle.sencha.com/#view/editor&fiddle/1r01
I've just started to learn about Mustache, but I don't understand how can I do this:
I have this JSON object :
var columnsDefinition = {
"columns": [
{
"header": 'First name',
"values": ['John', 'Jack', 'Abe', 'Adelle', 'Jim', 'Andrew', 'Matthew'],
"type": 'text'
},
{
"header": 'Last name',
"values": ['Carpenter', 'Reaper', 'Lincoln', 'Aidan', 'Raynor', 'Doe'],
"type": 'text'
},
{
"header": 'Profession',
"values": ['butcher', 'doctor', 'farmer', '', 'pilot', 'singer', ''],
"type": 'select'
},
{
"header": 'Employed',
"values": [true, false, true, true, false],
"type": 'checkbox'
}
],
"search": true
};
I want to create this :
This is what I've tried, but I don't know how to put values on each column, not on each row.
this.testDiv = $("#testDiv");
this.header = "{{#columns}}<th>{{header}}</th>{{/columns}}";
this.body = "{{#columns}}<tr>{{#values}}<td>{{.}}</td><{{/values}}/tr>{{/columns}}";
this.html = Mustache.to_html(this.header, this.columnsDefinition);
this.html2 = Mustache.to_html(this.body, this.columnsDefinition);
$("#testDiv table thead tr").append(this.html);
$("#testDiv table tbody").append(this.html2);
How can I create the table above? Thank you.
I don't believe this can be done out of the box.
If you can't modify the JSON object that you currently have, you're better off generating another JSON object that will pivot the data and feed that one to Mustache.
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:"".