State Saving with individual column filtering - javascript

I am using individual column filtering in data table along with stateSave: true. To perform column filtering I am using column filter.js.
I am facing one issue If I filtered data in the column and reload the page it maintains state for table only but textbox becomes empty.
On page refresh, the state remains same for the table and for searching textbox too.
On page refresh, the textbox value should be shown, but instead of that, text box becomes empty.
Please, someone, let me know how can I maintain textbox value along with table state.
I am using this code
jQuery('#Gridtable').dataTable({
stateSave: true,
"aLengthMenu": [[10, 25, 50, 100, 500, -1], [10, 25, 50, 100, 500, "All"]],
"iDisplayLength": 10,
}).columnFilter({
sPlaceHolder: "head:after",
aoColumns: [
{ type: "text" },
{ type: "text" },
{ type: "text" },
]
});

"stateLoaded": function stateLoadedCallback(settings, state) {
state.columns.forEach(function (column, index) {
$('#' + settings.sTableId + '-head-filter-' + index).val(column.search.search);
});
}
Just put values from your state into the fields

If you use stateSave=true DataTables option you can load it this way (in footer in my case):
stateSave: true,
stateLoadParams: function(settings, data) {
for (i = 0; i < data.columns["length"]; i++) {
let col_search_val = data.columns[i].search.search;
if (col_search_val !== "") {
$("input", $("#your-id-of-table tfoot th")[i]).val(col_search_val);
}
}
}
Cheers!

Just in case someone stumbles across this post after two years... this should be the solution to the described issue.

Related

Javascript Datatable limit amount of characters shown in a cell

I am creating a DataTable in Javascript, which has the following properties:
var dtable = $('.ssdatatable').DataTable({
"lengthMenu": [[10, 25, 50, 100, 500], [10, 25, 50, 100, 500]],
"bProcessing": true,
"sDom": "TBflrtip",
"bServerSide": true,
"sAjaxSource": ajSource,
"iDisplayLength": 25,
"bJqueryUI": false,
"bAutoWidth": false,
//"bAutoLength": false,
//"bLengthChange": false,
"recordsFiltered": 0,
"sPaginationType": "full_numbers",
"bPaginate": true,
"sServerMethod": "POST",
"responsive": true,
"fixedHeader": true,
"buttons": [
'copy', 'excel', 'pdf'
],
"aoColumns": [
//columns
]
});
One of the particular columns is a Description, which has a LOT of text in it. The width of columns is fixed, however because of that, the height of my rows are blowing out of proportions, making page x10 of its intended size.
My question is: is there anything I can add inside the properties to make it show only N characters, and by hitting limit it would be something like:
|text textte...|
| Show More|
(I tried commented out options, did do me any good)
Or would I need to use some method or modify css?
Had the same problem - only I wanted to show all the text when the table is exported and thus only limit the text, when displayed. So based on this blog https://datatables.net/blog/2016-02-26, I further developed the code in order to allow the whole text to be shown when the table is exported.
In order to do so, I altered the code so text > 50 char is not removed, but instead wrapped in a span which is then hidden from CSS.
The function code looks like this:
function(data, type, row) {
if (type === 'display' && data != null) {
data = data.replace(/<(?:.|\\n)*?>/gm, '');
if(data.length > 50) {
return '<span class=\"show-ellipsis\">' + data.substr(0, 50) + '</span><span class=\"no-show\">' + data.substr(50) + '</span>';
} else {
return data;
}
} else {
return data;
}
}
Then from the CSS file you can add:
span.no-show{
display: none;
}
span.show-ellipsis:after{
content: "...";
}
given data:
var mydt = [{ a: 1, b: 2, c: 3, d: 4 }, { a: 5, b: 6, c: 7, d: 8 }, { a: 10, b: 12, c: 13, d: 14 }];
$("#tbl2").DataTable({
columnDefs: [{ targets:[0] }],
data: mydt, columns: [{ data: "a" }, { data: "b" }, { data: "c" }, { data: "d" }],
createdRow: function (row, data, c, d) {
// so for each row, I am pulling out the 2nd td
// and adding a title attribute from the
// data object associated with the row.
$(row).children(":nth-child(2)").attr("title", data.b)
},
and the rest
here is a working one in jfiddle https://jsfiddle.net/bindrid/wbpn7z57/7/ note that this one has data in a different format but it works (on the first name column)
// DataTable created the createRow hook to allow the row html to be updated after it was created.
-- row is the current row being created
-- data is the data object associated with the row.
createdRow: function (row, data, c, d) {
$(row) gets the tr in a jQuery object
$(row).children() gets all of the td's in the row
(":nth-child(2)") gets the 2nd td in the row. Note, this is 1 based value,not 0 based.
.attr is the jquery command that adds the "title" attribute to the td.
the "title" is missed name but too late now.
data.b matches the data structured used to populate the table.
The actual structure of this data structure is dependent on your data source so you would actually have to check it.
Hope this helps :)
In the below example code block:
Whereas "Targets": 2 indicates column index, "data":"description" points out column name that wanted to be manipulated. When we look at the render function, description column is limited to 100 characters length.
var dtable = $('.ssdatatable').DataTable({
"lengthMenu": [[10, 25, 50, 100, 500], [10, 25, 50, 100, 500]],
"bProcessing": true,
"sDom": "TBflrtip",
"bServerSide": true,
"sAjaxSource": ajSource,
"iDisplayLength": 25,
"bJqueryUI": false,
.....
{
"targets": 2,
"data":"description",
render: function(data, type, row, meta) {
if (type === 'display') {
data = typeof data === 'string' && data.length > 100 ? data.substring(0, 100) + '...' : data;
}
return data;
}
},
});

Apply background-color to dxDataGrid control and export to Excel

I'm using DevExpress's dxDataGrid in a ASP.NET project for show some data stored on a SQL Server database.
The following code shows how I'm setting the dxDataGrid control for render the data:
// Variables.
var vlrMin = [];
var vlrMax = [];
var vlr_to_match = 0;
var colors = [];
var final_rst = "";
// Add values to variables:
vlrMin.push("9");
vlrMin.push("2");
vlrMin.push("9");
// Add values to variables:
vlrMax.push("13");
vlrMax.push("7");
vlrMax.push("4");
colors.push('#ff0000');
colors.push('#92D050');
colors.push('#5B9BD5');
// Start configuration.
$("#gridContainer").dxDataGrid({
dataSource: [{
"Dept": "Local services",
"Employee": "John Doe",
"TotalHours": "11"
}],
paging: {
pageSize: 10
},
export: {
allowExportSelectedData: true,
enabled: true,
fileName: 'Reporte 1',
texts: {
exportAll: 'Export all',
exportSelectedRows: 'Export selected row(s).',
exportTo: 'Export'
},
},
searchPanel: {
visible: true
},
filterRow: {
visible: true,
showOperationChooser: true
},
allowColumnReordering: true,
grouping: {
autoExpandAll: true
},
groupPanel: {
visible: true
},
pager: {
showPageSizeSelector: true,
allowedPageSizes: [5, 10, 20],
showInfo: true
},
columns: ['Dept',
'Employee', {
dataField: 'TotalHours',
allowFiltering: true,
allowSorting: true,
cellTemplate: function(container, options) {
/* Value to check if matches with the criteria. */
var vlr_to_match = options.value;
/* Loop elements. */
for (var mn = 0; mn < vlrMin.length; mn++) {
if (vlr_to_match >= vlrMin[mn] && vlr_to_match <= vlrMax[mn]) {
final_rst = colors[mn];
break;
}
}
/* Apply custom style to element. */
$('<span>').text(options.data.TotalHours)
.attr('style', 'background-color: ' + final_rst)
.appendTo(container);
}
}
]
});
This is the results in the dxDataGrid control:
But, when I open the generated file "using the DevExpress functionality" I'm not getting the same results as is shown in the screenshot (i.e; the cell has values, but no styles are applied).
According to the documentation, and after apply a color to an specific cell in the dxDataGrid control, when the exported Excel file is opened, the cell is not getting the same result as is shown in the dxDataGrid control.
My question is:
How can apply styles to a dxDataGrid cell and apply such results to the generated Excel file?
unfortunately, based on the quite recent (2016-09-20) reply from DX stuff in their support forum, there is no way in DevExtreme suit to export dxDataGrid to excel with formatting.
See yourself: https://www.devexpress.com/Support/Center/Question/Details/T429240
If you were using the DevEpress ASPxGridView control together with ASPxGridViewExporter you would be able to customize format in the exported Excel doc per cell or per row.

Disable Ordering Columns after initialization (init complete) in datatables

I would disable order possibility to user after datatables is draw.
I have a datatable, and I would order a data and remove possibility, for an user, to order data manually.
How can I do it?
I used below code:
table = $('#tbl-1').DataTable({
"info": false,
"searching": true,
"paging": false,
"iDisplayLength": 25,
"lengthMenu": [[10, 25, 50, -1], [10, 25, 50, "Tutti"]],
"language": {"url": "include/it_IT.txt"},
"order": [[1,"desc"]],
//"ordering": false,
//"orderFixed": {"pre": [ 1, "desc" ]},
"fnInitComplete": function(oSettings, json) {
//alert( 'DataTables has finished its initialisation.' );
this.fnFilter("<?php echo $_POST['search'];?>");
},
}).on('init.dt', function (e, settings, data) {
wrappa(); //after custom function
});
old post but still not handled by dt api. Removing the events won't work if wanting to temporarily disable sorting. Instead use jquery to add and later remove a class onto each th, and in this class specify "pointer-events: none".
Due to the fact that the API does not have a way to do this, I would suggest the following approach
Declare your table at first
var table = $('#myTable').DataTable();
Re-Initialize your dataTable with to disable ordering
//Destroy your table before
table.destroy();
$('#myTable').dataTable( {
"ordering": false
} );
reference:
https://datatables.net/reference/option/ordering

Linking two Handsontables

I'm trying to link two Handsontables so that the second table shows additional details for the current column in the first table. The number in the column header of the first table would be used to find the corresponding row in the second table.
Clicking on any cell in the first table should cause the corresponding row in the second table to be highlighted.
Clicking in the second table should highlight that row and move the cursor in the first table to the corresponding column.
Here's the HTML:
<div id="main" class="handsontable"></div>
<p>
<div id="index" class="handsontable"></div>
And here's the Javascript to display the tables:
$(document).ready(function () {
function getMainData() {
return [["2008", 10, 11, 12, 13], ["2009", 20, 11, 14, 13], ["2010", 30, 15, 12, 13]];
}
function getMainHeaders() {
return ["Year", 1, 2, 3, 4];
}
function getIndexData() {
return [[1, "Kia", "Korea"], [2, "Nissan", "Japan"], [3, "Toyota", "Japan"], [4, "Honda", "Japan"]];
}
function getIndexHeaders() {
return ["#", "Make", "Country"];
}
$("#main").handsontable({
data: getMainData(),
colHeaders: getMainHeaders(),
fillHandle: false,
readOnly: true
});
$("#index").handsontable({
data: getIndexData(),
colHeaders: getIndexHeaders(),
fillHandle: false,
readOnly: true
});
});
All I need is the code to link the tables! I've gone around in circles trying to make this work, but no joy.
I've got all of the above in a fiddle.
Thanks in advance for any help or suggestions.
I managed to do what you asked about (fiddle). I added this code after the initiation of the tables:
var sync = function(tab1, tab2) {
var syncSelection = function(row, col, rowEnd, colEnd) {
var sel1 = tab1.getSelected();
var sel2 = tab2.getSelected();
if (!sel2) {
tab2.selectCell(row, col, rowEnd, colEnd);
return;
}
for (var key in sel1) {
if (sel1[key] !== sel2[key]) {
tab2.selectCell(row, col, rowEnd, colEnd);
return;
}
}
};
// syncs while selecting (does not work for selecting one cell)
tab1.addHook('afterSelection', syncSelection);
// needed to sync selection of one cell
tab1.addHook('afterSelectionEnd', syncSelection);
};
var mainTable = $('#main').handsontable('getInstance');
var indexTable = $('#index').handsontable('getInstance');
sync(mainTable, indexTable);
sync(indexTable, mainTable);

DataTables add object data that is not a column to row?

I can't figure this one out, their API is very confusing.
I have a table that displays tabular data of geometric features, so I want to have the coordinates saved in the row data.
And I need a way to retrieve this coordinates, for example, when a user clicks on the row.
Example of what I'm trying to achieve :
const dt = $('table').DataTable({
columns : [
{data : "NAME"},
{data : "COLOR"}
]
})
dt.row.add({
COLOR : "Red",
NAME : "Point1",
//Invalid parameter error
geometry : {
type : "point",
coordinates : [1,1]
}
})
I think it wouldn't be ideal storing in a hidden column, because the coordinates can get quite large for polygon types.
I'm very new to DataTables and am very confused with the API, any suggestion on how to better organize/execute my concept is more than welcome.
Seems like what you have should work. I put together a little example for you:
http://live.datatables.net/rikofefu/1/edit
It adds a row with the extra geometry object. Select the row then click the Show selected data button. The console will display the full row and just the geometry object.
I'm using the Select extension to get the selected row.
HTML
<table>
<thead>
<tr>NAME</tr>
<tr>COLOR</tr>
<tr></tr>
</thead>
</table>
JS
const dt = $('table').DataTable({
columns: [
{data: null},
{data: null},
{data: null}
],
// This makes the row clickable, where you can get data later
"createdRow": function (row, data, dataIndex) {
var tds = $(row).find("td");
$.each(tds, function (key, value) {
$(value).attr("onclick", "see_the_data(this)");
}
},
// this hides the coordinate column from view
"columnDefs": [
{
"targets": 2,
"visible": false
}
]
});
dt.row.add({
COLOR: "Red",
NAME: "Point1",
//Invalid parameter error
geometry: {
type: "point",
coordinates: [1, 1]
}
});
function see_the_data(e) {
console.log("the data is ", e); // you can then go further as you need
}

Categories

Resources