I am new to JavaScript and Tabulator, I am stuck at this place, your help is appreciated.
I have loaded the data on the tabulator table and making few changes to it (add new column, deleting column etc.), these changes are reflected on the table but when I use table.getData() updated data is not reflected (old data is reflected). I need this to use some other places. Where am I going wrong?
Here is the sample code.
tabulatorTable = new Tabulator("#dfTable", {
selectable:true,
data:dataJson,
layout:"fitColumns", //fit columns to width of table
responsiveLayout:"hide", //hide columns that dont fit on the table
tooltips:true, //show tool tips on cells
addRowPos:"top", //when adding a new row, add it to the top of
//table
history:true, //allow undo and redo actions on the table
pagination:"local", //paginate the data
paginationSize:20,
movableColumns:true, //allow column order to be changed
resizableRows:true, //allow row order to be changed
columns:[
{title:"YearsExperience", field:"YearsExperience", editor:"number"},
{title:"Salary", field:"Salary", sorter:"number"}
]
});
tabulatorTable.addColumn({formatter:"rownum", title:"id"}); **// Adding new column to the table**
console.log(tabulatorTable.getData()); **// Does not reflect the newly added column**
Expected Json file to contain added column data (title - "id")
You can't modify data just by adding a column to the grid. Additionally, the column you added is a "rownum" formatter and is not bound to a field, so what key would it know to add? You will need to explicitly modify the data on the table.
See here: http://tabulator.info/docs/4.2/update
Solved it see snippet
tabulatorTable.addColumn({
formatter: "rownum",
field: "id",
title: "id"
});
const dataJson = [{
'YearsExperience': 2,
'Salary': 40000
},
{
'YearsExperience': 3,
'Salary': 50000
},
]
const tabulatorTable = new Tabulator("#dfTable", {
selectable: true,
data: dataJson,
layout: "fitColumns", //fit columns to width of table
responsiveLayout: "hide", //hide columns that dont fit on the table
tooltips: true, //show tool tips on cells
addRowPos: "top", //when adding a new row, add it to the top of
//table
history: true, //allow undo and redo actions on the table
pagination: "local", //paginate the data
paginationSize: 20,
movableColumns: true, //allow column order to be changed
resizableRows: true, //allow row order to be changed
columns: [{
title: "YearsExperience",
field: "YearsExperience",
editor: "number"
},
{
title: "Salary",
field: "Salary",
sorter: "number"
}
]
});
tabulatorTable.addColumn({
formatter: "rownum",
field: "id",
title: "id"
}); // Adding new column to the table**
console.log(tabulatorTable.getData()); // Does not reflect the newly added column**
<link href="https://cdnjs.cloudflare.com/ajax/libs/tabulator/4.2.7/css/tabulator.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/tabulator/4.2.7/js/tabulator.min.js"></script>
<div id="dfTable"></div>
Related
I got values in JSON and want to add several values in dataindex. How I can do this?
This works perfectly
columns: [
{
header: "Records",
dataIndex: time,
sortable: true,
},
];
But this example doesn't work
columns: [
{
header: "Records",
dataIndex: time + value + value1,
sortable: true,
},
];
Column property dataIndex should be a string that is the name of the field in the model definition, see documentation. To add different values from the model and display the result in a grid column, either use a calculated field and put the calculated field's name to dataIndex, or create a custom renderer function for the column and add the values there.
I have some rows I hide like that:
$("#"+rowid).hide();
My problem is that when the user clicks to sort a colmun, the hidden rows reappeared. There is a way to avoid this?
EDIT
I will try to explain a little bit more what I did with code example.
I start to create my grid with this params (and without datas).
var params = {
datatype: "local",
data: [],
caption: "Grid",
colNames:[ "Column A", "Column B" ],
colModel:[
{ name:"colA", key: true },
{ name:"colB" }
]
};
For some reasons, I reload next the grid with datas, like this:
$("#myGrid").jqGrid("clearGridData")
.jqGrid("setGridParam", { data: myDatas })
.trigger("reloadGrid");
And I have checkboxes with listeners, like this one:
$("#checkbox1").on("change", onCheckbox1Changed);
function onCheckbox1Changed() {
var rowid = ...;
var datas = $("#myGrid").jqGrid("getRowData");
for(var key in datas) {
if(datas[keys].colB === "" && $("#checkbox1").val() === true) {
$("#"+rowid).show();
} else if(datas[keys].colB === "" && $("#checkbox1").val() === false) {
$("#"+rowid).hide();
}
}
}
This code works like I want. Rows are hidden/shown depending on checkboxes. The problem is when I clik on a column to sort it, the hidden columns reappeared.
EDIT 2
I could force the grid to hide the rows after a sort. But I didn't find where I can find an event like "afterSort". There is "onSortCol" but it is called before the sort.
A solution will be to force that using "loadComplete". Like this:
var params = {
// ...
loadComplete: onLoadComplete
}
function onLoadComplete() {
onCheckbox1Changed();
}
I tried it and it works. But I am not very "fan" with this solution.
I find hiding some rows after displaying the page of data not the best choice. The main disadvantage is the number of rows which will be displayed. You can safe use $("#"+rowid).hide(); method inside of loadComplete only if you need to display one page of the data. Even in the case one can see some incorrect information. For example, one can use viewrecords: true option, which place the text like "View 1 - 10 of 12" on right part of the pager.
I personally would recommend you to filter the data. You need to add search: true option to the grid and specify postData.filters, which excludes some rows from displaying:
search: true,
postData: {
filters: {
groupOp: "AND",
rules: [
{ field: "colA", op: "ne", data: "rowid1" },
{ field: "colA", op: "ne", data: "rowid2" }
]
}
}
If you would upgrade from old jqGrid 4.6 to the current version (4.13.6) of free jqGrid, then you can use "ni" (NOT IN) operation:
search: true,
postData: {
filters: {
groupOp: "AND",
rules: [
{ op: "ni", field: "id", data: "rowid1,rowid2" }
]
}
}
In both cases jqGrid will first filter the local data based on the filter rules and then it will display the current page of data. As the result you will have the perfect results.
Sorting of such grid will not not change the filter.
Don't hide columns after the creation of the table, hide them directly when you create the grid using the option hidden, like this:
colNames: ['Id', ...],
colModel: [
{ key: true, hidden: true, name: 'Id', index: 'Id' },
....
]
If you want to hide columns on particular events after the creation of the grid, look at this article.
Hope it was you were looking for.
I wanted to set column align properties across all grids in my application based on the data.
Is there a way where I could align the columns to center if they are of type decimal/number
and otherwise align left for all other types.
I do not have column schema's I will need to determine it before the data is being rendered.
How about using attributes like :
$("#grid").kendoGrid({
columns: [ {
field: "someField",
title: "Some Name",
attributes: {
"class": "table-cell",
style: "text-align: center"
}
You can use the template field to determine the datatype and set a template for the column.
$("#grid").kendoGrid({
columns: [
{
title: "FieldName",
field: "Name",
template: '#=Getvalue(Name)#'
}
],
....
});
function Getvalue(value) {
if (//check datatype)
return "<span style='text-align: right'>"+ value+"</span>";
//or add a custom class
else
return value;
}
I've got a basic ExtJS gridpanel on which I can apply custom state on the fly. Using another control such as a combobox or another grid, my application applies the selected state on the grid. An example of this state:
{
"height": 384,
"columns": [{
"id": "h107"
},
{
"id": "h1",
"width": 30
},
{
"id": "unplannedtasks_ActualEndDate",
"hidden": true,
"width": 100
},
{
"id": "unplannedtasks_ActualNoResources",
"hidden": true,
"width": 100
},
{
"id": "unplannedtasks_ActualResponseDateTime",
"hidden": true
},
{
"id": "unplannedtasks_ActualTotalDurationInSeconds",
"width": 100
},
"filters": []
}
Here's the corresponding columns section of the grid declaration:
Ext.define('Ext.grid.Stateful', {
extend: 'Ext.grid.Panel',
stateEvents: ['columnmove', 'columnresize', 'sortchange', 'hiddenchange', 'groupchange', 'show', 'hide'],
// CODE OMMITTED FOR BREVITY
initComponent: function () {
Ext.apply(this, {
columns: [
filterAction,
new columns.tasks.ActualEndDate({ id: 'unplannedtasks_ActualEndDate', hidden: false }),
new columns.tasks.ActualNoResources({ id: 'unplannedtasks_ActualResponseDateTime', hidden: false },
new columns.tasks.ActualResponseDateTime({ id: 'unplannedtasks_ActualResponseDateTime', hidden: false },
new columns.tasks.ActualTotalDurationInSeconds({ id: 'unplannedtasks_ActualTotalDurationInSeconds', hidden: false }
]
});
}
})
An example of a column definition:
Ext.define("columns.tasks.ActualNoResources", {
extend: "Ext.grid.column.Column",
text: 'ActualNoResources',
dataIndex: 'ActualNoResources',
editor: {
allowBlank: false
}, filterable: true,
filter: {
type: 'string'
}
});
Everything goes as I expected except the column headers don't seem to refresh properly. If I open the columns panel in the grid, it is showing the correct amount of visible and hidden columns. Same story with the filters: if there's a filter in the state, it applies the correct value on the correct field. It's as though the column headers need to be refreshed in some way.
I tried to use grid.getView().refresh() but that doesn't work. Instead, if I resize the grid, it does refresh the hidden columns but not the columns that were initially hidden but now visible.
I think I am missing a simple line of code that belongs in the applyState method of the grid so I can command the grid to refresh the grid with the new state rather than the previous or initial state.
Any ideas on how to solve this?
As it turns out, the scenario that I pursue is not possible out of the box with ExtJS. What I'm asking can only be done during startup (without intervention of a developer's custom code) so I had to quit this approach and provide custom code. In the end, I had to rebuild the columns and then pass that collection to the reconfigure(store, columns) method of the grid.
I have a datatable which has ajax sourced data.
I have some function which validates the data in table cell by cell and changes cell color to red if validation failed. also having an column with no data initially and updates its data later. I set rowId as ip_address to identify that row based on ip.
Now i want to update the empty cell whose ip matches rowid in table.
I tried $("#devices_table td:nth-child(3)").text('hi');
which updates all rows for 3rd column, but i want to update only one row matching that rowId.
tbl1 = $('#devices_table').dataTable({
autoWidth: false,
scrollX: true,
scrollY: 400,
paging: false,
select:{ style: 'multi' },
info: false, // This will prevent showing message 'Showing 1 of N rows'
serverSide: true,
aoColumns: [ { title: "Result", data:'Result', defaultContent: '', name: 'Result'},
{ title: "IP Address",data: "IP_Address", name:'IP_Address'}, ],
fnRowCallback: function( nRow, aData, iDisplayIndex ) {
$('td', nRow).attr('nowrap','nowrap');
return nRow;
}, // This is for content wrap in column
ajax: "/get_device_table", // call for data
rowId: 'IP_Address',
this is my table defination.
tbl1.fnUpdate('abc' , $('tr#192.168.30.20'), 0 );
$("#devices_table").children().children()'192.168.30.20'].children[0].innerHTML = "Hi";
$('#devices_table tr:eq('+rowid+') td:eq(0)').text('ChangedText');
and these are few things which I tried but didnt work for me.
I am new to datatables and jquery, so this code can have stupid mistakes too.. please correct me if any. Thanks in advance.
Solved.
Issue was due to setting ip address as id
changed . in ip to - and added className to column and it worked.
and following code of line,
aoColumns: [
{ title:"Result", data:'Result', defaultContent:'',className:'result'},
{ title: "IP Address",data: "IP_Address", className:'IP_Address'}, ]
$('#192-168-32-24').find('td.result').html('hi')