DataTables custom detection plug-in and sorting order - javascript

i'm trying to implement a function on Datatables that has to look up the table data, do a regex and then, if it returns true, then, when i click on the header to sort data, it will sort it by the last 5 digits, ignoring the letters that comes up in the beginning of the string.
i have the following code
$.fn.dataTable.ext.oSort['custom'] = function (settings, col) {
return this.api().column(col, {order: 'index'}).nodes().map(function (td, i) {
var string= $(td).html();
return $.trim(string.substr(string.length - 4));
});
}
$.fn.dataTable.ext.type.detect.push(
function (value) {
var test = (/PT\d/).test(value);
return test ? 'custom' : null;
}
);
this is for a custom data that has lots of trash in the beggining, like country code and stuff, but the data order is only by the last 5 digits.
i've been searching all over i'm having a hard time to understand and debug. Debuguing the detect works, if 1 put an alert, it gives-me true when it hits the colum with the values i want, but the custom sorting doesn't work, can anybody help?
hope i'm clear about it
thanks

actualy i solved it myself.
the problem was that DataTables needs to make the entire column return true, so, if the regex fails in any value in the same column it fails.
$.fn.dataTable.ext.type.detect.unshift(
function (d) {
var pt = (/^PT\d/).test(d);
var es= (/^ES\d/).test(d);
var en= (/^EN\d/).test(d);
if (pt || es|| en) {
return 'custom'
} else {
return false;
}
}
);
$.fn.dataTable.ext.type.order['custom-pre'] = function (string) {
return $.trim(string.substr(string.length - 4));
};
so this is my last code used and it works just fine.
i'm posting it so anybody with the same problem can have a clue to solve some future problem :)

Related

Tabulator: reformat cell on 'cellEdited' event

I am new at using Tabulator.js but I am willing to learn and use it deeply. I was indeed looking for a good tableGenerator library for a main project. So far, it seems to be pretty nice.
I am currently using a CND link for version 5.0.7.
Now here is my problem: I try to format cell with a background-color depending on the cell value (the cell name is status and the value can be either true or false). It works at the creation of the table. But it doesn't work if I change the cell value afterwards.
I created a method called statusFormatter:
statusFormatter: (cell) => {
if (cell.getValue() == true) {
cell.getElement().style.backgroundColor = "#A6A6DF";
}
return cell.getValue();
},
I call this method on the cellEdited event:
mainTable.on("cellEdited", function (cell) {
clientTabulator.statusFormatter(cell);
});
I suppose there is something wrong with the return in the method. But I don't know what to return when it is the style that I need.
Hope someone can help...
Change your statusFormatter function as
statusFormatter: function (cell, formatterParams, onRendered) {
let position = cell.getRow().getPosition();
// switch row even and odd color
let backgroundColor = cell.getValue() ? "#A6A6DF" : position % 2 ? "#efefef" : "#fff";
cell.getElement().style.backgroundColor = backgroundColor;
return cell.getValue();
}

Slice function in .csv

I have a .csv file that I am pulling into d3 and transforming to work for my assignment. I have one column that has the elements as percentages "xx.x%". I would like to remove the percentage sign, so that I am left with just "xx.x" for each element in that column. I know the slice() function needs to be used, and that I will be taking the values from 1 - length-2, but I'm not sure how to write the function. I'll include the other cleanup code so that you can get a feel for the file I'm working with. Thank you!!
function cleanup(raw_data) {
// remove unneeded columns
var data = [];
raw_data.forEach(function(obj){
if (obj["County"] == "Dutchess" && obj["Month"] == 12)
data.push(obj)
});
data.forEach(function(obj) {
delete obj["2012 Census Population"];
delete obj["Population 18+ Estimate"];
delete obj["OPO"];
delete obj["Location"];
delete obj["Month"];
delete obj["County"];
delete obj["Chart Month"];
});
data.sort(function (a,b) {
return a["Year"] > b["Year"];
});
return data;
}
Have you tried:
data.forEach(function(obj) {
obj["yourCol"] = obj["yourCol"].slice(0, -1);
});

TypeError: Cannot call method "split" of undefined

I am using Google Apps Script on Google SpreadSheets and I am trying to use split method on a member of my array and I get this error:
TypeError: Cannot call method "split" of undefined.
This is my code:
function myFunction(range) {
var Ocurrences=[];
range.forEach(function(row) {
var tokens=row.toString().split(' ');
var hour=tokens[4].split(':')[0];
Ocurrences.push(hour);
});
return Ocurrences;
}
The normal guess would be that tokens[4] is no defined, but I have already tried to read it's value and it IS defined and it IS a string.
I fixed the problem. It was because I was running my code as a google spreadsheets custom function and the range I was giving to it was the whole column (A1:A). But as there was some blank rows in the column which caused some undefined values reached the function without me noticing it.
One solution is to give the exact range of filled rows (A1:A229 in my case).
A better solution is to add a validation for token[4] right before the split call to make sure no undefined value will pass. This way the function will support an undefined range of cells.
Here is the code I used:
function myFunction(range) {
var Ocurrences=[];
range.forEach(function(row) {
var tokens=row.toString().split(' ');
if(tokens[4]){
var hour=tokens[4].split(':')[0];
Ocurrences.push(hour);
}
});
return Ocurrences;
}
There must be something going on in your particular environment. Your code, as-is, works for me:
console.log(myFunction(["first second third forth 8:25", "first second third forth 5:25"]));
function myFunction(range) {
var Ocurrences=[];
range.forEach(function(row) {
var tokens=row.toString().split(' ');
var hour=tokens[4].split(':')[0];
Ocurrences.push(hour);
});
return Ocurrences;
}
console.log(myFunction(["first second third forth 8:25", "first second third forth 5:25"]));
function myFunction(range) {
var Ocurrences=[];
range.forEach(function(row) {
var tokens=row.toString().split(' ');
var hour=tokens[4].split(':')[0];
Ocurrences.push(hour);
});
return Ocurrences;
}

Jquery Datatables render multiple functions

I am using the datatables plugin for jQuery however I am having issues with the render function:
I have a string that contains some html elements in a column, I do not want the html elements to render in the table so I use the function $.fn.dataTable.render.text()
I also only want this data to be a preview as the string can be incredibly long therefore I am using an ellipsis function $.fn.dataTable.render.ellipsis(40)
The ellipsis function is defined here:
// https://datatables.net/manual/data/renderers#Text-helper
$.fn.dataTable.render.ellipsis = function (cutoff) {
return function (data, type, row) {
if (type === 'display') {
var str = data.toString(); // cast numbers
return str.length < cutoff ?
str :
str.substr(0, cutoff - 1) + '…';
}
// Search, order and type can use the original data
return data;
};
};
Would it be possible to combine these functions in any way?
The closest solution to my problem is this found on the datatables forum.
This is exactly what I want to do however it does not work as d = renderArray[r](d, type, row, meta); is not a function.
Thanks in advance.
Edit:
The mRender function is passed the data for the whole row. So, you can access any property you want to access render multiple function using datatables
{
mData: "bar",
mRender: function(data, type, val) {
switch (type) {
case 'display':
return '' + data.bar + '';
break;
// optionally, add case statements for 'sort', 'filter', and 'type'
default:
return data.bar;
break;
}
}
}

How to Combine Multiple Return Functions (JavaScript)

I am learning JavaScript so that I can implement Google Tag Manager. I have a list of paths that I would like GTM to rewrite to something friendlier like so:
function() {
return document.location.pathname.indexOf('/l/138281/2016-06-07/dy383') > -1 ? 'Test Success' : undefined;
}
function() {
return document.location.pathname.indexOf('/l/138281/2016-04-03/55z63') > -1 ? 'SPP Contact Success' : undefined;
I'm just not sure how to combine these returns into one function (I currently have about 30 URLs to rewrite). I imagine I can use if/else, but advice would be quite lovely.
--edit--
URL Path Rewrite To
/test-638-jsj /test-success
/spp-zxcv-765 /spp-contact-success
/foo-asdf-123 /foo
/foo-bar-987 /foo-bar
The return function mentioned above does this beautifully for an individual link. I just want to be able to rewrite a series of URLs in one function (or however it makes sense to do this most specifically). Hopefully that helps clarify.
Thanks!
It is always a great idea to structure your code: separate abstract functionality from the specific problem.
What you are actually doing is scannins strings for occurences of keywords and returning specific values if such a keyword has been found.
Therefore, you need a function performing the above computation and a JavaScript datastructure holding your keywords and their values (= Object):
// Return patterns[key] if any key is found in string, else return string:
function match(string, patterns) {
for (key of Object.keys(patterns)) {
if (string.indexOf(key) > -1) return patterns[key];
}
return string;
}
var patterns = {
'/l/138281/2016-06-07/dy383': 'Test Success',
'/l/138281/2016-04-03/55z63': 'SPP Contact Success'
}
console.log(match('/l/138281/2016-06-07/dy383', patterns)); // "Test Success"
console.log(match('/doesnotexist', patterns)); // "/doesnotexist"
console.log(match(document.location.pathname, patterns));

Categories