Datatables sort images on title tag - datatables

I have a question about using a custom sorting option for datatables.
I have a table with only images in the last column. The images use the title tag, where I want to sort them on.
So, I use this code to set the sorting:
<script type="text/javascript">
jQuery.extend( jQuery.fn.dataTableExt.oSort, {
"title-string-pre": function ( a ) {
return a.match(/title="(.*?)"/)[1].toLowerCase();
},
"title-string-asc": function ( a, b ) {
return ((a < b) ? -1 : ((a > b) ? 1 : 0));
},
"title-string-desc": function ( a, b ) {
return ((a < b) ? 1 : ((a > b) ? -1 : 0));
}
} );
$(document).ready(function() {
$('#customertable').dataTable( {
"aoColumnDefs": [
{ "bSortable": false, "aTargets": [ 0,1 ] },
{ "sType": "title-string-asc", "aTargets": [ 4 ] }
],
"bPaginate": false,
"bLengthChange": false,
"bFilter": false,
"bInfo": false,
"bAutoWidth": false,
"bSortCellsTop": true
} );
} );
</script>
However, when I click on the header of column 4, it does not work and Chrome reports errors "Property 'title-string-asc-desc' of object # is not a function"
and
"Property 'title-string-asc-asc' of object # is not a function"
What am I doing wrong?

Found the answer, but don't understand it.
Changed
{ "sType": "title-string-asc", "aTargets": [ 4 ] }
to
{ "sType": "title-string", "aTargets": [ 4 ] }
Now it works. But why? "title-string" is defined nowhere. How can javascript link that string to the content of a title tag?

Related

vue-good-table custom sorting

I am using vue-good-table and have the following code so far:
<vue-good-table :columns="columns" :rows="rows"
styleClass="vgt-table condensed striped bordered"
:sort-options="sortOptions"
:search-options="searchOptions"
:select-options="selectOptions"
#on-selected-rows-change="selectionChanged">
</vue-good-table>
sortOptions: {
enabled: true,
initialSortBy: { field: "date", type: "desc" },
}
columns() {
return [
{
label: "Name",
field: "name",
},
{
label: "CreationDate",
field: "date",
type: "date",
formatFn: function (value) {
return value != null ? moment(value).format('YYYY-MM-DD') : null;
},
sortFn(x, y) {
x = moment(x);
y = moment(y);
return x.unix() < y.unix() ? -1 : x.unix() > y.unix() ? 1 : 0;
},
},
]
}
Sorting works fine so far, and there are three states: 'asc', 'desc' and 'none'.
However i would like to achieve the following:
When clicking the column header and the current sorting type is 'none' for any of the columns, i would like to have the data sorted as defined in the initialSortBy property in the sortOptions. So sorted by date in desc order.
I tried using the #on-sort-change event but don't really know how to proceed further as i am quite new to Vue.
onSortChange(params) {
console.log('on-sort-change:');
console.log(params[0].field)
console.log(params[0].type)
if (params[0].type == 'none') {
console.log("default sort")
//TODO sort data as defined in initial sort
}
}

datatables print customize cell color

I'm tying to change the table cell color when printing a table.. The print cusomize fucntion is called and working correctly but the color doesn't change..
When I render the initial table I call rollCallback to set the cell color
rowCallback: function(row, data, index){
if(data.scores <= 1){
$(row).find('td:eq(2)').css('background-color', 'red');
}
if(data.scores > 1 && data.scores <=2 ){
$(row).find('td:eq(2)').css('background-color', 'yellow');
}
if(data.scores > 2){
$(row).find('td:eq(2)').css('background-color', 'green');
}
}
The in the print buttom. I use the same code to render the background color again
{
extend : 'print',
text : '<i class="fa fa-print fa-lg"></i>',
titleAttr : 'Print',
exportOptions : {
columns : [0,1,2,4]
},
customize: function(win,conf,table) {
table.rows().every(function(index,element) {
if(this.data().scores <= 1)
{
$(this).find('td:eq(2)').css('background-color', 'red');
}
if(this.data().scores > 1 && this.data().scores <=2 )
{
$(this).find('td:eq(2)').css('background-color', 'yellow');
}
if(this.data().scores > 2)
{
$(this).find('td:eq(2)').css('background-color', 'green');
}
});
}
}
The color does not change..
Im using
jquery-3.5.1
Datatables-1.10.21
buttons-1.6.3
Using #andrewjames answer I get a little better result.. The preview now has color.. but when ctrl-print is used from the browser I loose the style again.
Here is the approach mentioned in my other answer, but adapted for your specific circumstances.
In my test data I only have 3 columns, so I made one small change from your code - I changed this columns : [0,1,2,4] to this columns : [ 0, 1, 2 ].
Here is my starting table:
Here are some extra styles I added:
<style>
td.bg_red {
background-color: red;
}
td.bg_yellow {
background-color: yellow;
}
td.bg_green {
background-color: green;
}
</style>
I used the following embedded test data (instead of an ajax data source):
var dataSet = [
{ "name" : "Tiger Nixon",
"office": "London",
"scores" : 1 },
{ "name" : "Donna Snider",
"office": "New York",
"scores" : 2 },
{ "name" : "Airi Satou",
"office": "Tokyo",
"scores" : 3 }
];
Here is the DataTables definition:
<script type="text/javascript">
var dataSet = [
{ "name" : "Tiger Nixon",
"office": "London",
"scores" : 1 },
{ "name" : "Donna Snider",
"office": "New York",
"scores" : 2 },
{ "name" : "Airi Satou",
"office": "Tokyo",
"scores" : 3 }
];
$(document).ready(function() {
$('#example').DataTable({
dom: 'Bfrtip',
data: dataSet,
columns: [
{ title: "Name", data: "name" },
{ title: "Office", data: "office" },
{ title: "Score", data: "scores" }
],
rowCallback: function(row, data, index){
if(data.scores <= 1){
$(row).find('td:eq(2)').addClass("bg_red");
}
if(data.scores > 1 && data.scores <=2 ){
$(row).find('td:eq(2)').addClass("bg_yellow");
}
if(data.scores > 2){
$(row).find('td:eq(2)').addClass("bg_green");
}
},
buttons: [
{
extend: 'print',
//autoPrint: false, // useful for testing
exportOptions: {
//columns : [0,1,2,4],
columns : [ 0, 1, 2 ],
format: {
body: function ( inner, rowidx, colidx, node ) {
if (node.classList.contains('bg_red')) {
return '<span class="bg_red">' + inner + '</span>';
} else if (node.classList.contains('bg_yellow')) {
return '<span class="bg_yellow">' + inner + '</span>';
} else if (node.classList.contains('bg_green')) {
return '<span class="bg_green">' + inner + '</span>';
} else {
return inner;
}
}
}
},
customize: function ( win, butt, tbl ) {
$(win.document.body).find('span.bg_red').parent().css('background-color', 'red');
$(win.document.body).find('span.bg_yellow').parent().css('background-color', 'yellow');
$(win.document.body).find('span.bg_green').parent().css('background-color', 'green');
}
} ]
});
});
</script>
And here is the print-preview:
This uses the same technique as described in the other answer I mentioned in my comments, but adapted for your specific scenario. The reason it works is the same as described in that answer.
Update
You may need to adjust printer settings to see the colors on an actual print-out. For example, using Google Chrome:

How to only include a key if the value meets a certain criteria

I have this piece of Dataweave code
list_of_orders: {
order: payload map ((payload01 , indexOfPayload01) -> {
order_dtl:
"" when payload01[30] == "S"
otherwise
"" when payload01[30] == "C"
otherwise
[{
data: some_data
}],
order_hdr: {
data: some_data
}
})
}
This code will output the following data
"list_of_orders": {
"order": [
{
"order_dtl": [
{
"data": "some_data"
}
],
"order_hdr": {
"data": "some_data"
}
}
]
}
But it will only do this if payload01[30] != "S" or "C"
If payload01[30] is equal to "S" or "C" then it does this
"list_of_orders": {
"order": [
{
"order_dtl": "",
"order_hdr": {
"data": "some_data"
}
}
]
}
The reason I have done this is because I have been asked to only include the DETAIL line if the order_type is not "C" or "S".
The problem is that the actual key - order_dtl - is still present and I don't want anything there at all.
How do I make a KEY conditional?
Any help appreciated
Thanks
What you are looking is called conditional elements
list_of_orders: {
order: payload map ((payload01 , indexOfPayload01) -> {
(order_dtl:
[{
data: some_data
}]) when((payload01[30] != "S") and (payload01[30] != "C")),
order_hdr: {
data: some_data
}
})
}

Sort icon not changing in Datatable server side processing

When I use server side processing in datatable the sorting works but the sort icon does not change and stays in same direction. Below is the code snippet of my datatable configuration.
$('#dtSearchResult').DataTable({
"filter": false,
"pagingType": "simple_numbers",
"orderClasses": false,
"order": [[0, "asc"]],
"info": true,
"scrollY": "450px",
"scrollCollapse": true,
"bLengthChange": false,
"searching": true,
"bStateSave": false,
"bProcessing": true,
"bServerSide": true,
"sAjaxSource": VMCreateExtraction.AppSecurity.websiteNode() + "/api/Collection/SearchCustIndividual",
"fnServerData": function (sSource, aoData, fnCallback) {
aoData.push({ "name": "ccUid", "value": ccUid });
//Below i am getting the echo that i will be sending to Server side
var echo = null;
for (var i = 0; i < aoData.length; i++) {
switch (aoData[i].name) {
case 'sEcho':
echo = aoData[i].value;
break;
default:
break;
}
}
$.ajax({
"dataType": 'json',
"contentType": "application/json; charset=utf-8",
"type": "GET",
"url": sSource,
"data": aoData,
success: function (msg, a, b) {
$.unblockUI();
var mappedCusNames = $.map(msg.Table, function (Item) {
return new searchGridListObj(Item);
});
var data = {
"draw": echo,
"recordsTotal": msg.Table2[0].TOTAL_NUMBER_OF_RECORDS,
"recordsFiltered": msg.Table1[0].FILTERED_RECORDS,
"data": mappedCusNames
};
fnCallback(data);
$("#dtSearchResult").show();
ko.cleanNode($('#dtSearchResult')[0]);
ko.applyBindings(VMCreateExtraction, $('#dtSearchResult')[0]);
}
})
},
"aoColumns": [{
"mDataProp": "C_UID"
}, {
"mDataProp": "C_LAST_NAME"
}, {
"mDataProp": "C_FIRST_NAME"
}, {
"mDataProp": "C_USER_ID"
}, {
"mDataProp": "C_EMAIL"
}, {
"mDataProp": "C_COMPANY"
}],
"aoColumnDefs": [{ "defaultContent": "", "targets": "_all" },
//I create a link in 1 st column
]
});
There is some configuration that I am missing here. I read on datatable forums and the only issue highlighted by people was that draw should be same as what we send on server side.
For anyone looking for an answer to this. Sad but i had to write my own function as below:
function sortIconHandler(thArray, sortCol, sortDir) {
for (i = 0; i < thArray.length; i++) {
if (thArray[i].classList.contains('sorting_asc')) {
thArray[i].classList.remove('sorting_asc');
thArray[i].classList.add("sorting");
}
else if (thArray[i].classList.contains('sorting_desc')) {
thArray[i].classList.remove('sorting_desc');
thArray[i].classList.add("sorting");
}
if (i == sortCol) {
if (sortDir == 'asc') {
thArray[i].classList.remove('sorting');
thArray[i].classList.add("sorting_asc");
}
else {
thArray[i].classList.remove('sorting');
thArray[i].classList.add("sorting_desc");
}
}
}
}
tharrray-> The array of all row headers(You can just write a jquery selector for this).
sortCol->Column on which sort is clicked (Datatable param iSortCol_0)
sortDir -> Sorting direction (Datatable param sSortDir_0)
I know this is an old thread, but make sure you don't have an .off() somewhere associated with the tables capture group in jQuery. I had a click event that (for some reason) I attached an off function to.. Took me 3 days to find it.

dataTables make <tr> clickable to link

I have a dataTables table at http://communitychessclub.com/test.php
My problem is I need to make an entire table row clickable to a link based on a game#. The table lists games and user should click on a row and the actual game loads.
I am unable to understand the previous solutions to this problem. Can somebody please explain this in simple terms?
I previously did this at http://communitychessclub.com/games.php (but that version is too verbose and does disk writes with php echo)
with
echo "<tr onclick=\"location.href='basic.php?game=$game'\" >";
<script>$(document).ready(function() {
$('#cccr').dataTable( {
"ajax": "cccr.json",
"columnDefs": [
{
"targets": [ 0 ],
"visible": false,
}
],
"columns": [
{ "data": "game" },
{ "data": "date" },
{ "data": "event" },
{ "data": "eco" },
{ "data": "white_rating" },
{ "data": "white" },
{ "data": "black_rating" },
{ "data": "black" }
]
} );
} );</script>
"cccr.json" looks like this and is fine:
{
"data": [
{
"game": "5086",
"date": "09/02/2013",
"event": "135th NYS Ch.",
"eco": "B08",
"white": "Jones, Robert",
"white_rating": "2393",
"black": "Spade, Sam",
"black_rating": "2268"
},
...
You can do it this way:
Use fnRowCallback to add a game-id data-attribute to your datatable rows
...
{ "data": "black" }
],
"fnRowCallback": function (nRow, aData, iDisplayIndex, iDisplayIndexFull) {
//var id = aData[0];
var id = aData.game;
$(nRow).attr("data-game-id", id);
return nRow;
}
This will give each row in your table a game id attribute e.g:
<tr class="odd" data-game-id="5086">
Then create a javascript listener for the click event and redirect to the game page passing the game id taken from the tr data-attribute:
$('#cccr tbody').on('click', 'tr', function () {
var id = $(this).data("game-id");
window.location = 'basic.php?game=' + id;
}