jQuery datatable - format column as string when exporting to Excel - datatables

I have a jQuery datatable where first column is barcode labels and they are 24 characters long. They could be all numeric characters or mix of alpha and numeric. My problem is when exporting to Excel and all labels look numeric.
It exports fine when label is 1234ABCD5678901234567890 or 001234567890001234567890 but labels such as 123004590218842001720584 are displayed as 123004590218842000000000 and when clicking on that cell it shows as 1.23004590218842E+23, and right justified as if number.
I tried forcing it to use column A as string using
$('row c[r^="A"]', sheet).attr('s', '50'); //"A" is Label column
Didn't work; all it did was replace 123004590218842000000000 with 1.23004590218842E+23.
This is my Excel customization section:
buttons: [
{
extend: "collection",
text: "Export",
buttons: [
{
extend: 'excel',
orientation: 'landscape',
pageSize: 'LEGAL',
customize: function (xlsx) {
var sheet = xlsx.xl.worksheets['sheet1.xml'];
var sheet2 = xlsx.xl['styles.xml'];
// use font size 10
var tagName = sheet2.getElementsByTagName('sz');
for (i = 0; i < tagName.length; i++) {
tagName[i].setAttribute("val", "10")
}
$('c[r=A1] t', sheet).text('Label Outcomes');
$('row:first c', sheet).attr('s', '2').attr('s', '32'); // first row is bold
// This didn't help, it just made the header of this column non-bold
$('row c[r^="A"]', sheet).attr('s', '50'); //"A" is Label column
$(sheet.body)
.css('font-size', '10pt');
$(sheet.body).find('table')
.addClass('compact')
.css('font-size', 'inherit');
},
exportOptions: {
columns: [0, 1, 2, 3, 4, 5, 6, 7, 8, 10]
},
},

I posted to datatable forum and got a response that solved my issue.
It boils down to adding a zero-width non-joiner character (\u200c) character to the columns. It preserves sorting (date, ...).
buttons: [
{
extend: "collection",
text: "Export",
buttons: [
{
extend: 'excelHtml5',
orientation: 'landscape',
title: 'My Excel Title',
//messageTop: 'List Success Transactions',
//messageBottom: 'The information in this table is copyright',
customizeData: function (data) {
for (var i = 0; i < data.body.length; i++) {
for (var j = 0; j < data.body[i].length; j++) {
data.body[i][j] = '\u200C' + data.body[i][j];
}
}
},
customize: function (xlsx) {
...
}
},
...
Link to solution is here
There is also a SOF post related to this issue that includes above solution here

Related

how to export visible columns of my datatable

I have a datatable export option pdf excel but I have some hidden columns I don't want to see them in the export
this is my code
//Buttons examples
var table = $('#datatable-buttons').DataTable({
lengthChange: false,
buttons: ['copy', 'excel', 'pdf'],
retrieve: true
});
table.buttons().container()
.appendTo('#datatable-buttons_wrapper .col-md-6:eq(0)');
// Key Tables
$('#key-table').DataTable({
keys: true
});
I tried to add option
Visible
but didn't work please help
The simplest way is to use exportOptions with the columns option.
You can provide an array of column index numbers for this - for example:
var colsToExport = [1, 2, 3]; // the first column has an index of 0
var table = $('#example').DataTable( {
dom: 'Brftip',
buttons: [
{
extend: 'pdf',
text: 'To PDF',
exportOptions: {
columns: colsToExport
}
},
{
extend: 'excel',
text: 'To Excel',
exportOptions: {
columns: colsToExport
}
}
]
} );
If you need something more sophisticated than a simple array list, then there are various alternatives to defining an array - see column-selector for full details.
A full list of export options, in addition to columns, can be found here.

datatables rowcallback and colvis and statesave

I am using datatables with statesave, colvis button to select the visibility of columns and rowcallback to put some colors on my data.
Here is my code:
activitiesTable = $('#activitiesTable').DataTable({
scrollX: true,
serverSide: true,
processing: true,
stateSave: true,
...
buttons: [
{
extend: "colvis",
className: "btn-sm",
columns: [ 1, 3, 4, 6, 7, 8, 9, 10, 12, 14, 16,18,20,22,24,26,28,30,32 ]
},
...
rowCallback: function(row, data, index){
if(data.jan_com<= 0){
$(row).find('td:eq(4)').addClass('zero');
}
else if(data.jan_otl> 0){
$(row).find('td:eq(4)').addClass('otl');
}
else {
$(row).find('td:eq(4)').addClass('forecast');
}
if(data.feb_com<= 0){
$(row).find('td:eq(5)').addClass('zero');
}
else if(data.feb_otl> 0){
$(row).find('td:eq(5)').addClass('otl');
}
else {
$(row).find('td:eq(5)').addClass('forecast');
}
...
So as you can see, I change the color of my data with class zero, forecast or otl.
The problem is that because it changes the columns that appear, the next time I reload, the colors are applied to the wrong column because column 4 is not anymore the column jan_com.
Is there a way to find the td corresponding to the column jan_com instead of asking td:eq(4)?
Thanks.

Order DataTables by invisible data column using columns.orderData

For my question I have prepared a simple test case at JS Bin.
In a word game I am trying to display the 20 longest words played by a player.
I deliver the data from PostgreSQL to DataTables jQuery plugin in JSON format. It is already sorted by word length and by the date when words were played.
This order is stored as numeric value (1, 2, 3, ...) in the row property of each JSON object:
var dataSet = [
{"row":4,"gid":1,"created":"25.02.2017 14:07","finished":null,"player1":2,"player2":1,"score1":30,"score2":52,"female1":0,"female2":0,"given1":"Abcde3","given2":"Ghijk4","photo1":null,"photo2":null,"place1":null,"place2":null,"word":"ZZ","score":11},
{"row":2,"gid":1,"created":"25.02.2017 14:07","finished":null,"player1":2,"player2":1,"score1":30,"score2":52,"female1":0,"female2":0,"given1":"Abcde3","given2":"Ghijk4","photo1":null,"photo2":null,"place1":null,"place2":null,"word":"BBBBB","score":6},
{"row":3,"gid":1,"created":"25.02.2017 14:07","finished":null,"player1":2,"player2":1,"score1":30,"score2":52,"female1":0,"female2":0,"given1":"Abcde3","given2":"Ghijk4","photo1":null,"photo2":null,"place1":null,"place2":null,"word":"ABC","score":7},
{"row":1,"gid":1,"created":"25.02.2017 14:07","finished":null,"player1":2,"player2":1,"score1":30,"score2":52,"female1":0,"female2":0,"given1":"Abcde3","given2":"Ghijk4","photo1":null,"photo2":null,"place1":null,"place2":null,"word":"XYZXYZXYZ","score":6}
];
Here is my JavaScript code, where I try to sort the column word (column 2) by the invisible column row (column 0):
function renderGid(data, type, row, meta) {
return (type === 'display' ? '<IMG SRC="https://datatables.net/examples/resources/details_open.png"> #' + data : data);
}
function renderGame(data) {
return 'Details for game #' + data.gid;
}
jQuery(document).ready(function($) {
var longestTable = $('#longest').DataTable({
data: dataSet,
order: [[2, 'desc']],
columns: [
{ data: 'row', orderable: false, visible: false },
{ data: 'gid', orderable: false, visible: true, className: 'details-control', render: renderGid },
{ data: 'word', orderable: true, visible: true, orderData: 0 /* order by invisible column 0 */ },
{ data: 'score', orderable: false, visible: true }
]
});
$('#longest tbody').on('click', 'td.details-control', function () {
var img = $(this).find('img');
var tr = $(this).closest('tr');
var row = longestTable.row(tr);
if (row.child.isShown()) {
row.child.hide();
img.attr('src', 'https://datatables.net/examples/resources/details_open.png');
} else {
row.child( renderGame(row.data()) ).show();
img.attr('src', 'https://datatables.net/examples/resources/details_close.png');
}
});
});
However this does not work - the displayed words order is ZZ, BBBB, ABC, XYZXYZXYZ (seemingly unsorted) - while it should be XYZXYZXYZ, BBBB, ABC, ZZ (sorted by row descending):
Why does not sorting work even though I have specified columns.orderData: 0?
And why can't I change ordering by clicking the greyed out arrows (shown by the red arrow in the above screenshot)?
Ok, this seems to be an old bug in dataTables jQuery plugin: the integer argument is not accepted.
I have to change it to an array with the single value:
{ data: 'word', orderable: true, visible: true, orderData: [0] },
and then it works:

Is it possible to add animations to dgrid rows?

We currently have a dgrid with a single column and rows like this:
Recently I added some code so that we can delete rows with the little X button that appears above the row when we hover them.
The handler calls this to delete the row:
this.grid.store.remove(rowId);
When we delete a row, since it's instantaneous and each row contains similar text, it's not always obvious to the user that something just happened.
I was wondering if it would be possible add some sort of dojo or css animation to the row deletion, like the deleted row fading or sliding out. This would make the row deletion more obvious.
Thanks
I have created a jsfiddle for animating(wipeOut) a selected row.
require({
packages: [
{
name: 'dgrid',
location: '//cdn.rawgit.com/SitePen/dgrid/v0.3.16'
},
{
name: 'xstyle',
location: '//cdn.rawgit.com/kriszyp/xstyle/v0.2.1'
},
{
name: 'put-selector',
location: '//cdn.rawgit.com/kriszyp/put-selector/v0.3.5'
}
]
}, [
'dojo/_base/declare',
'dgrid/OnDemandGrid',
'dgrid/Selection',
'dojo/store/Memory',
"dojo/fx",
'dojo/domReady!'
], function(declare, Grid, Selection, Memory,fx) {
var data = [
{ id: 1, name: 'Peter', age:24 },
{ id: 2, name: 'Paul', age: 30 },
{ id: 3, name: 'Mary', age:46 }
];
var store = new Memory({ data: data });
var options = {
columns: [
/*{ field: 'id', label: 'ID' },*/
{ field: 'name', label: 'Name' },
{ field: 'age', label: 'Age' }
],
store: store
};
var CustomGrid = declare([ Grid, Selection ]);
var grid = new CustomGrid(options, 'gridcontainer');
grid.on('dgrid-select', function (event) {
// Report the item from the selected row to the console.
console.log('Row selected: ', event.rows[0].data);
//WipeOut animation for selected row.
fx.wipeOut({ node: event.rows[0].element }).play();
});
});

Display the time picker value in the textfield using sencha touch 2

Ext.define("Datetimepicker.view.Main", {
extend: 'Ext.form.Panel',
requires: [
'Ext.TitleBar',
'Ext.field.DatePicker',
'Ext.Spacer',
'Ext.Picker'
],
config: {
fullscreen:'true',
title:'DatatimePicker',
items: [
{
xtype:'fieldset',
items:[
{
xtype:'datepickerfield',
label:'Birthday',
picker:{
yearFrom:1980,
yearTo:2015
},
name:'birthday',
value:new Date()
},
{
xtype:'textfield',
label:'Time',
value:''
//In this textfield i want to display the time picker value
}
}
]
},
{
items:[
{
xtype:'spacer'
},
{
text: 'setValue',
handler: function() {
var datePickerField = Ext.ComponentQuery.query('datepickerfield')[0];
var randomNumber = function(from, to) {
return Math.floor(Math.random() * (to - from + 1) + from);
};
datePickerField.setValue({
month: randomNumber(0, 11),
day : randomNumber(0, 28),
year : randomNumber(1980, 2015)
});
}
},
{ xtype:'spacer'}
]
}
]
}
});
By using above code I'm getting the value of datepicker which successfully display in the first textfield.In the same way I want to display that value of datepicker in another textfield.
Can anyone help me to do this ...thanks in advance
You can do it by setting the value of the textfield every time your picker's value has been changed so here is a solution:
items: [
{
xtype: 'datepickerfield',
label: 'Birthday',
name: 'birthday',
value: new Date(),
listeners: {
change: function(picker, value) {
// This function use to prepend 0 to the month which less than October
function minTwoDigits(n) {
return (n < 10 ? '0' : '') + n;
}
var date = value.getDate(), // Get date's value
month = value.getMonth(); // Get month's value
month += 1; // Increase the number of month by 1 since the index started with 0
var formatMonth = minTwoDigits(month),
year = value.getFullYear(), // Get year's value
formatDate = formatMonth.concat("/",date,"/",year); // Concatenate string
Ext.ComponentQuery.query('#textfield')[0].setValue(formatDate); // Set the value of the textfield with itemID equal to textfield
}
}
},
{
xtype:'textfield',
label:'time',
itemId: 'textfield',
value:''
}
]
If you don't understand anything, feel free to ask. Hope it helps :)