I have a column of checkboxes in my table that I want to have checked with parity in row.isSelected().
When using the VirtualDOM the rows in the buffer don't get checked/unchecked as part of a table.getRows() loop to un-check the box. The rows DO get unselected from the table POV via row.deselect().
The checkbox is added with a mutator to the first column:
checkboxMutator = function (value, data) {
return '<input type="checkbox" class="rowCheckBox" name="' + value + '">';
}
The select all logic:
$("#select-all").click(function () {
var rows = table.getRows(true);
rows.forEach(function(row){
row.select();
$("input[name='" + row.getData().index + "']:checkbox").prop('checked', true);
});
});
The rows that don't exist in the DOM at all yet can be checked by adding some logic into rowFormatter to check them on render the first time.
It might not be possible to fix, but I thought it was worth asking about.
Because Tabulator uses a vitrual DOM only the rows that are visible actually exists, rows are created and destroyed as you scroll.
Because of this it is not safe to try and manipulate any DOM elements inside the table from outside.
In your case you should be using a Custom Formatter that uses the isSelected function on the row component to determine if the checkbox should be selected when it is created.
//custom formatter
function checkboxFormatter(cell, formatterParams, onRendered){
//create input element
var input = document.createElement("input");
input.setAttribute("type", "checkbox");
//set checked state
input.checked = cell.getRow().isSelected();
return input;
}
//assign formatter in column definition
{title:"selected?", formatter:checkboxFormatter}
You should then be using the rowSelectionChanged option to redraw the row after selection has changed, which will then cause the formatter to run and update the checkbox.
rowSelectionChanged:function(data, rows){
//rows - array of row components for the selected rows in order of selection
//data - array of data objects for the selected rows in order of selection
//reformat all rows that have changed
rows.forEach(function(row){
row.reformat();
})
}
You can then select all rows in the table by calling the selectRow function on the table.
table.selectRow();
Related
I need to add and/or remove a class to all cells even when they are hidden by pagination. I am able to add a class, but only the cells on the active page are getting the class. I understand that is because it is only updating what is available in the DOM and the hidden rows are not active in the DOM at the time, I'm adding the class.
Is there a way that Tabulator handles this?
As you can see from below i'm getting the rows (not shown) and then looping over the rows and attempting to update the cell classList.
for (var i = 0; i < rows.length; i++) {
if (rows[i] != this){
var row = rows[i],
cell = row.getCell(col),
cellElement = cell.getElement();
cellElement.classList.add('disable-cell');
console.log(cell);
}
}
I have a custom function that hides/shows columns in my tabulator. The column I click on is supposed to hide and several other columns are shown. I have this function working correctly from onclick on an object in a custom cell formatter, but I would like to call it from clicking on the column header. It works except that I can't seem to get a handle of the column I clicked on from column header in order to hide the column.
I'm trying to get the column object and pass it to my function so I can hide that column while I show the others. I'm open to other ways to do this.
this works (cell formatter)
var showForecastCell = function(cell, formatterParams, onRendered){
...
span.onclick = function(){showForecast(cell.getColumn())};
return span
}
this doesn't work (column titleFormatter)
var showForecastHeader = function(t,e,o,i,n){
...
span.onclick = function(){showForecast(t.getColumn())};
return span
}
Is there any way to pass the column object from clicking on the column header? otherwise, if there is a simpler way to hide the column after clicking on the header, I am open to suggestions. I must admit that javascript isn't my strongest language and if I am overlooking something basic, please let me know.
You can check this JsFiddle it hides all other columns except the one you click
for Column call backs you can check documentation here and here
const hideAllButThis = function(e, column) {
const showField = column._column.field;
const columns = column._column.table.columnManager.columns;
for (let i = 0; i < columns.length; i++) {
if (columns[i].field !== showField) {
table.hideColumn("" + columns[i].field + "")
}
}
};
I feel I am missing something simple... The cheese example of how to use the rowFormatter is exactly how I want to implement something, except I'd like to add various additional columns...
I've noted the warning it is important to include only one column in your column definition array to ensure the table renders correctly, however it is exactly what I want to do.
So I tried adding another column to the table constructor which added a column heading but no data.
What an I missing? Surely this is a common use case?
Use the formatter option as apposed to the rowFormatter - which overwrites the entire rows contents.
Based on the printIcon and cheese examples in the Tabulator docs, construct a column formatter, but pass the row as apposed to the cell.
Then its just a matter of constructing the html table as per the cheese example, but return the table, don't append to the element.
My Test Example:
//Generate details
var details = function(row, formatterParams){ //plain text value
var element = row.getElement(),
data = row.getData(),
width = element.outerWidth(),
table;
//define a table layout structure and set width of row
table = $("<table style='width:" + (width - 18) + "px;'><tr></tr></table>");
//add image on left of row
$("tr", table).append("<td><img src='./img/teams/small-60x80/55015.png'></td>");
//add row data on right hand side
$("tr", table).append("<td><div><strong>Type:</strong> " + data.type + "</div><div><strong>Age:</strong> " + data.age + "</div><div><strong>Rind:</strong> " + data.rind + "</div><div><strong>Colour:</strong> " + data.color + "</div></td>");
//append newly formatted contents to the row
//element.append(table);
return table;
//return "<image src='./img/teams/small-60x80/55015.png'>";
};
//define Tabulator
$("#example-table").tabulator({
height:"600px",
layout:"fitColumns",
resizableColumns:false,
columns:[
{formatter:details},
{title:"Cheese", field:"type", sorter:"string"},
{title:"Something Else", field:"blah", sorter:"string"},
],
})
I´m iterating through the rows of my DataTable with the example I found here in documentation but I want to get the data of the second column, analyze that value and then set my processed value on that cell.
tablaProgDetalle.rows().every( function ( rowIdx, tableLoop, rowLoop ) {
// I suppose here goes the processing and the setting of the cells values.
});
SOLUTION
You can use row().data() inside the anonymous function to get and set row's data. Please note that variable this in inside the anonymous function refers to row being iterated.
var table = $('#example').DataTable();
table.rows().every( function ( rowIdx, tableLoop, rowLoop ) {
var data = this.data();
data[0] = '* ' + data[0];
this.data(data);
});
DEMO
See this jsFiddle for code and demonstration.
You can use rowID to do this; we can set rowID in rowCreated: callback of Datatable, or manually while inserting rows upon table creation. Here I am incrementing 3rd column value upon some event in my project.
//DOM only addition
var rowID = your rowID goes here;
var cols = Table.row(rowID).data();
var count = parseInt(cols[2]);
count = count + 1
cols[2] = count.toString();
Table.row(rowID).data(cols);
I have a datatable problem when I reject changes on the table. I've created an example below which demonstrates the problem:
DataTable table = new DataTable();
table.Columns.Add("Name", typeof(string));
table.Columns.Add("Last_Name", typeof(string));
table.Columns.Add("Male", typeof(Boolean));
foreach (DataColumn column in table.Columns)
{
if (column.ColumnName == "Name")
{
column.Unique = true;
}
}
DataRow row;
row = table.NewRow();
row["Name"] = String.Format("Steve");
row["Last_Name"] = String.Format("Smith");
row["Male"] = true;
table.Rows.Add(row);
table.AcceptChanges();
So at this stage I have a DataTable with a unique column constraint and 1 row in that table.
I now delete that row:
row.Delete();
This sets the rowstate to Deleted.
At this stage I realise that I've made a mistake and want to add the row again. So I create the new row again and add it to the DataTable:
row = table.NewRow();
row["Name"] = String.Format("Steve");
row["Last_Name"] = String.Format("Smith");
row["Male"] = true;
table.Rows.Add(row);
At this stage my DataTable contents are in the following state:
table.Rows[0].RowState is Deleted
table.Rows[1].RowState is Added
Now, I've changed my mind about the whole thing and want to get back to how I started so I call RejectChanges:
table.RejectChanges();
When I do this I receive the following error:
Column 'Name' is constrained to be unique. Value 'Steve' is already present.
I understand that there are 2 rows with the same values but I thought reject changes would have ingored this as the RowStates are different.
Any ideas how I can get round this?
In my live code I use this to move rows between to 2 grids (like allowing the user to selected what columns are visible)
I'm using C#4.0 in Visual Studio 2012
Thanks in advance