DataTables - set row colour - datatables

I am using DataTables and would like to set the background colour for each row depending on the input. I followed the directions in the forum:
https://datatables.net/forums/discussion/36595/change-the-row-color-based-on-column-data
[https://datatables.net/forums/discussion/62460/changing-row-color-at-rendering-time-based-on-column-values]
However, I can not get it to work.
My code is:
createdRow: function( row, data, dataIndex){
//console.log('data[3]: ' + data[3]);
if( data[3] == '4'){
$(row).css("background-color", "red");
}
},
The console.log displays "data[3] is undefined".
I have tried:
if( data[3] === '4')
The full context is:
//Show DataTable
moment.updateLocale(moment.locale(), { invalidDate: "" })
if ( $.fn.dataTable.isDataTable( '#ymTable' ) ) {
var ymTable = $('#ymTable').DataTable();
}
else {
var ymTable = $('#ymTable').DataTable( {
createdRow: function( row, data, dataIndex){
// console.log('data[3]: ' + data[3]);
if( data[3] == '4'){
$(row).css("background-color", "red");
}
},
info: false,
dom: 'Bfrtip',
order: [[ 3, 'asc' ], [ 1, 'asc' ], [ 2, 'asc' ]],
// buttons: ['copy', 'csv', 'excel', 'pdf', 'print'],
buttons: [
{
extend: 'copy',
exportOptions: {
columns: [ 1, 2, 3, 4, 5, 6 ]
}
},
{
extend: 'csv',
exportOptions: {
columns: [ 1, 2, 3, 4, 5, 6 ]
}
},
{
extend: 'excel',
exportOptions: {
columns: [ 1, 2, 3, 4, 5, 6 ]
}
},
{
extend: 'pdf',
exportOptions: {
columns: [ 1, 2, 3, 4, 5, 6 ]
}
},
{
extend: 'print',
exportOptions: {
columns: [ 1, 2, 3, 4, 5, 6 ]
}
},
],
columns: [
{data: 'cdId',
visible: false,
searchable: false},
{data: 'surname',
defaultContent: ""},
{data: 'firstname',
defaultContent: ""},
{data: 'age',
defaultContent: ""},
{data: 'gender',
defaultContent: ""},
{data: 'paradePatrol',
defaultContent: ""},
{data: 'role',
defaultContent: ""},
{data: null,
className: "center",
render: function(data,type,row) {
if(data.sayId == null || data.sayId == undefined){
return ("<input type='checkbox' id=" + data.cdId + " name='update' onchange='ymActivityPatrolFunction(this)' style='zoom: 2.0;'>")
}else{
return ("<input type='checkbox' id=" + data.cdId + " name='update' onchange='ymActivityPatrolFunction(" + data.cdId + ", " + this.checked + ")' style='zoom: 2.0;' checked>");
}
},
},
],
columnDefs: [
{targets: 7, orderable: false},
],
});
}

I found the answer to be, to replace:
data[3] == '4'
with:
data.age == '4'
As in:
createdRow: function( row, data, dataIndex){
if( data.age == '4'){
$(row).css("background-color", "red");
}
},

Related

Multiple filters / Filter inside filter - React Native

how can i do something like that in React-Native:
data = [
{id:1,title:'Action',games:[
{id:1,title:'Game1'},
{id:2,title:'Game2'},
{id:3,title:'Game3'},
]},
{id:2,title:'Horror',games:[
{id:1,title:'Game1'},
{id:2,title:'Game2'},
{id:3,title:'Game3'},
]},
]
Every time the query string is updated, look for the game within the category.
Returns only the categories that contain a game with the searched characters.
Thank you! :D
I don't know if I understand your question correctly. This is my solution.
If you query for "Game5" you will get whole object that contains query
const data = [
{
id: 1,
title: "Action",
games: [
{ id: 1, title: "Game1" },
{ id: 2, title: "Game2" },
{ id: 3, title: "Game3" },
],
},
{
id: 2,
title: "Horror",
games: [
{ id: 1, title: "Game4" },
{ id: 2, title: "Game5" },
{ id: 3, title: "Game6" },
],
},
];
const query = "Game5";
const result = data.find((category) =>
category.games.find((g) => g.title === query)
);
console.log(result);
You can use 'filter' instead of 'find' and result will be an array.
This is example of filter version. I add one more category so you can see how it filter
const data = [
{
id: 1,
title: "Action",
games: [
{ id: 1, title: "Game1" },
{ id: 2, title: "Game2" },
{ id: 3, title: "Game3" },
],
},
{
id: 2,
title: "Horror",
games: [
{ id: 1, title: "Game1" },
{ id: 2, title: "Game2" },
{ id: 3, title: "Game3" },
],
},
{
id: 3,
title: "Comedy",
games: [
{ id: 1, title: "Game5" },
{ id: 2, title: "Game6" },
{ id: 3, title: "Game7" },
],
},
];
const query = "Game2";
const result = data.filter((category) =>
category.games.find((g) => g.title === query)
);
console.log(result);
And you might want to look at life cycle componentDidUpdate if you write class component, but if you write function component you might want to use useEffect
This is official react hook explaination
EDIT: from your comment you might want something like this
const data = [
{
id: 1,
title: "Action",
games: [
{ id: 1, title: "Game1" },
{ id: 2, title: "Game2" },
{ id: 3, title: "Game3" },
],
},
{
id: 2,
title: "Horror",
games: [
{ id: 1, title: "Game1" },
{ id: 2, title: "Game2" },
{ id: 3, title: "Game3" },
],
},
{
id: 3,
title: "Comedy",
games: [
{ id: 1, title: "Game5" },
{ id: 2, title: "Game6" },
{ id: 3, title: "Game7" },
],
},
];
const query = "Game5";
let result = null;
data.forEach((category) => {
const game = category.games.filter((g) => g.title === query);
if (game.length) result = { ...category, games: game };
});
console.log(result);

Ant design vue different data in nested tables

I'm trying to make nested table, in documentation into the nested table they push one same data, how can i change it and push different data for every parent table row?
<script>
const columns = [
{ title: 'Status', dataIndex: 'Status', key: 'Status' },
{ title: 'Date', dataIndex: 'DateCreated', key: 'DateCreated' }
];
const innerColumns = [
{ title: 'Price', dataIndex: 'Price', key: 'Price' },
{ title: 'Status', dataIndex: 'Status', key: 'Status' },
];
const data = [
{
key: 0,
"Status": "u",
"DateCreated": "2019-10-11"
},
{
key: 1,
"Status": "u",
"DateCreated": "2019-09-20"
},
];
const innerData = [
[
{
key: 0,
"Price": 10623,
"Status": "u",
}
],
[
{
key: 0,
"Price": 15084,
"Status": "u",
},
{
key: 1,
"Price": 15084,
"Status": "u",
}
],
];
export default {
data() {
return {
data,
columns,
innerColumns,
innerData,
};
},
};
</script>
<template>
<div class="hello">
<a-table
:columns="columns"
:dataSource="data"
class="components-table-demo-nested">
<a-table
slot="expandedRowRender"
:columns="innerColumns"
:dataSource="innerData[1]"
:pagination="false"
>
</a-table>
</a-table>
</div>
</template>
Here my code
This worked for me
Template:
<a-table :data-source="data" :defaultExpandAllRows="true" v-on:expandedRowsChange="console.log">
<a-table-column title="First Col" data-index="firstCol" />
<template v-slot:expandedRowRender="record, index, indent, expanded">
<a-table :data-source="record.nestedData"
:pagination="false">
<a-table-column title="File Name" data-index="filename" />
</a-table>
</template>
</a-table>
Script:
Vue.component('demo', {
data: function() {
return {
data: [
{
firstCol: '1',
nestedData: [{filename: 'nested 11'}, {filename: 'nested 12'}]
},
{
firstCol: '2',
nestedData: [{filename: 'nested 22'}, {filename: 'nested 22'}]
}
]
}
}
});

Datatables show total

How could I show a total of a column on datatables? I tried with the datatables doc example but I don't understand how does it works.
I tried to adapt the datatables doc example with like this:
jQuery('#tableName').DataTable({
pagingType: 'full',
lengthMenu: [
[5, 10, 25, 50, -1],
[5, 10, 25, 50, 'All'],
],
searching: true,
ordering: true,
aaSorting: [],
paging: true,
select: false,
info: true,
responsive: true,
data: [
{ col1: "col1.1", col2: 20 },
{ col1: "col1.2", col2: 30 }
],
columns: [
{ data: 'col1', title: 'col1' },
{ data: 'col2', title: 'col2' }
],
dom: 'lBfrtip',
buttons: [{
extend: 'copy',
text: '<i class="far fa-copy"></i>',
title: lang.componentSection,
footer: true
}, {
extend: 'pdf',
text: '<i class="far fa-file-pdf"></i>',
title: lang.componentSection,
footer: true
}, {
extend: 'excel',
text: '<i class="far fa-file-excel"></i>',
title: lang.componentSection,
footer: true
}, {
extend: 'print',
text: '<i class="fas fa-print"></i>',
title: lang.componentSection,
footer: true
}],
footerCallback: function ( row, data, start, end, display ) {
var api = this.api(), data;
// Remove the formatting to get integer data for summation
var intVal = function ( i ) {
return typeof i === 'string' ?
i.replace(/[\$,]/g, '')*1 :
typeof i === 'number' ?
i : 0;
};
// Total over all pages
var total = api
.column( 1 )
.data()
.reduce( function (a, b) {
return intVal(a) + intVal(b);
}, 0 );
// Total over this page
var pageTotal = api
.column( 1, { page: 'current'} )
.data()
.reduce( function (a, b) {
return intVal(a) + intVal(b);
}, 0 );
// Update footer
$( api.column( 1 ).footer() ).html(
'$'+pageTotal +' ( $'+ total +' total)'
);
}
});
but I don't know how to show the results or if there's something bad. (I have no errors in console and this is a reduced example, in real datatable I get the data from ajax)
I have the total value, but I don't know how can be shown with this sintax (column defs)
I can show the total addinf the html tags with jQuery, but with this method total will not exported to pdf, excel, ...
here is the example code:
jQuery('#tableName').append('<tfoot>\
<tr>\
<th colspan="4" style="text-align:right">Total:' + pageTotal + '</th>\
<th></th>\
</tr>\
</tfoot>');
The only way to esport the footer is to have it painted before the datatable generation like in this simplified example:
jQuery('#' + tableName).html('<tfoot>\
<th></th>\
<th style="text-align:center; border:0.5px solid gray"></th>\
</tfoot>');
jQuery('#tableName').DataTable({
pagingType: 'full',
lengthMenu: [
[5, 10, 25, 50, -1],
[5, 10, 25, 50, 'All'],
],
searching: true,
ordering: true,
aaSorting: [],
paging: true,
select: false,
info: true,
responsive: true,
data: [
{ col1: "col1.1", col2: 20 },
{ col1: "col1.2", col2: 30 }
],
columns: [
{ data: 'col1', title: 'col1' },
{ data: 'col2', title: 'col2' }
],
dom: 'lBfrtip',
buttons: [{
extend: 'copy',
text: '<i class="far fa-copy"></i>',
title: lang.componentSection,
footer: true
}, {
extend: 'pdf',
text: '<i class="far fa-file-pdf"></i>',
title: lang.componentSection,
footer: true
}, {
extend: 'excel',
text: '<i class="far fa-file-excel"></i>',
title: lang.componentSection,
footer: true
}, {
extend: 'print',
text: '<i class="fas fa-print"></i>',
title: lang.componentSection,
footer: true
}],
footerCallback: function ( row, data, start, end, display ) {
var api = this.api(), data;
var intVal = function ( i ) {
return typeof i === 'string' ?
i.replace(/[\$,]/g, '.')*1 :
typeof i === 'number' ?
i : 0;
};
var total = api.column( 1 ).data()
.reduce( function (a, b) {
return intVal(a) + intVal(b);
}, 0 );
total = total.toString().replace(/[\$.]/g, ',');
jQuery(api.column( 1 ).footer()).html(total);
}
});
is important to put all of the <th></th>, because collspan doesn't exports correctly on datatables
the idea is to inject the footer with jQuery so you could destroy the table and regenerate again with the same footer (for example if you have to put that table with new columns or someting like that)
It doesn't works without api.column( 1 ).data() because if you put it with jQuery can't be exportable.

Add different values of tooltips with more than one series

I have a problem with adding different values in tooltips in my chart using React-Native.
We have 3 series of my graph. The first shows the bars and the others are lines.
When I click on the bar I load a tooltip with the value "this.y" which is what I need and it works.
But when I click the in lines I need to load other values into the tooltips.
But I can't load these values. Clicking doesn't open the tooltip.
//Bar data
this.state.barArray = [10.1, 22.5, 33.3, 4.5, 1.5, 26.3, 17, 18.20, 9.2, 0.9, 1, 2];
//Line 1 data
this.state.line1Array = [12.1, 21.5, 23.3, 14.5, 13.5, 16.3, 15, 18.12, 19.2, 10.9, 0, 2.5];
//Line 2 data
this.state.line2Array = [13.1, 18.5, 13.3, 24.5, 19.5, 23.3, 10.3, 16.40, 29.2, 5.9, 21.3, 0];
//X axis of chart
this.state.dias = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
//Here I load 2 arrays with the values. I want to display on each line
var toolTip = ['2h 30m','1h 30m','4h 30m','5h 30m','6h 30m','4h 30m','1h 30m','7h 30m','15h 30m','2h 13m','12h 30m','00h 30m'];
var toolTip2 = ['1h 30m','1h 30m','4h 30m','5h 30m','6h 30m','4h 30m','1h 30m','7h 30m','15h 30m','2h 13m','12h 30m','00h 30m'];
Graph configuration.
var conf={
chart: {
type: 'column',
},
yAxis: {
title: {
useHTML: true,
text: null,
},
},
navigation: {
buttonOptions: {
enabled: false
}
},
colors:
['#DA6AFF', 'rgb(71, 40, 213)', 'rgb(172, 143, 242)'], //Bar and lines colors
title: {
text: null
},
xAxis: {
categories: this.state.dias
},
credits: {
enabled: false
},
series: [{
type: 'column', //First serie with bar
name: 'Bar',
data: this.state.barArray,
marker: {
enabled: false,
},
tooltip: {
useHTML: true,
shared: false,
pointFormatter: function() {
return '<b>Value: ' + this.y + '</b>';
}
}
}, {
type: 'line', //Second serie with first line
name: 'Line 1',
data: this.state.line1Array,
marker: {
enabled: false,
},
tooltip: {
useHTML: true,
shared: false,
pointFormatter: function() {
Highcharts.each(toolTip[this.series.data.indexOf(this)], function(p) {
return '<b>' + p + '</b>';
});
}
}
}, {
type: 'line', //Second serie with second line
name: 'Line 2',
data: this.state.line2Array,
marker: {
enabled: false,
},
tooltip: {
useHTML: true,
shared: false,
pointFormatter: function() {
Highcharts.each(toolTip2[this.series.data.indexOf(this)], function(p) {
return '<b>' + p + '</b>';
});
}
}
}],
tooltip: {
headerFormat: '',
},
};
const options = {
global: {
useUTC: false
},
lang: {
decimalPoint: ',',
thousandsSep: '.'
}
};
I did this through the example of this link http://jsfiddle.net/o2zmLngr/5/, but I could not reproduce it in React-Native.
Can anyone help me to create individual tooltips for my chart line and loading information from other arrays?

How to map hierarchical Json to ItemFileWriteStore?

I have Json data that has children elements. I need to bind the store to an editable grid and have the edits populated to the store.
The data tree does get populated into the ItemFileWriteStore. The datagrid displays only the parent data and none of the children data.
SAMPLE.TXT
{
"items": [
{
"profileId": "1",
"profileName": "ABC",
"profileType": "EmailProfile",
"profilePreferences": [
{
"profilePreferenceId": "1",
"displayText": "Bob",
"address": "primary#some.com"
},
{
"profilePreferenceId": "2",
"displayText": "Sally",
"address": "secondary#some.com"
},
{
"profilePreferenceId": "3",
"displayText": "Joe",
"address": "alternate#some.com"
}
]
}
]
}
javascript
var sampleLayout = [
[
{ field: 'profileName', name: 'profileName', width: '100px' },
{ field: 'profilePreferences.displayText', name: 'displayText', width: '100px' },
{ field: 'profilePreferences.address', name: 'address', width: '100px' }
]];
function populateGrid() {
var url = "sample.txt"; //Will be replaced with endpoint URL
dojo.xhrGet({
handleAs: 'json',
url: url,
error: function (e) {
alert("Error: " + e.message);
},
load: showJsonData
});
}
function showJsonData(response, ioArgs) {
var profileStore = new dojo.data.ItemFileWriteStore({
data: {
items: response.items
}
});
var sampleGrid = dijit.byId("sampleGrid");
sampleGrid.store = profileStore;
sampleGrid.startup();
}
you need to be using dojox.grid.TreeGrid or 'fake' the JSON to present every even row with a blank profileName. Two samples follows, one for TreeGrid another on DataGrid - not tested in working environment though.
Given Hierachial JSON:
{
identifier: 'id' // a good custom to make an id pr item, note spaces and odd chars are invalid
items: [{
id: '1',
profileName: 'Admin',
profilePreferences: [
{ id: '1_1', displayText: 'John Doe', address: 'Big Apple' }
{ id: '1_2', displayText: 'Jane Doe', address: 'Hollywood' }
]
}, {
id: '2',
profileName: 'Visitor',
profilePreferences: [
{ id: '2_1', displayText: 'Foo', address: 'Texas' }
{ id: '2_2', displayText: 'Bar', address: 'Indiana' }
]
}]
}
TreeGrid Structure:
{
cells: [
[
{ field: "profileName", name: "profileName", width: "100px" },
{ field: "profilePreferences",
children: [
{ field: "displayText" name: "displayText", width: "100px" },
{ field: "address" name: "address", width: "100px" }
]
]
]
}
reference: dojo docs
Given flattened 'fake-children' JSON:
{
identifier: 'id' // a good custom to make an id pr item, note spaces and odd chars are invalid
items: [{
id: '1',
profileName: 'Admin', preferenceText: '', preferenceAddr: ''
}, {
id: '2',
profileName: '', preferenceText: 'John', preferenceAddr: 'NY'
}, {
id: '3',
profileName: 'Visitor', preferenceText: '', preferenceAddr: ''
}, {
id: '4', // Not with '.' dot seperator like so
profileName: '', preference.Text: 'Jane Doe', preference.Addr: 'Hollywood'
} ]
DataGrid structure:
[[
{'name': 'Profilename', 'field': 'profileName', 'width': '100px'},
{'name': 'User name', 'field': 'preferenceText', 'width': '100px'},
{'name': 'Address', 'field': 'preferenceAddr', 'width': '200px'}
]]
reference dojo docs