Tablesorter sort numeric field with hyphen - javascript

I have a table that binds data in the format of YYYY-####. In some cases there may be values 2012-456 and 2012-1234. Be default, the 2012-1234 will sort 'before' the 2012-456. If I change the sort to 'numeric', then it throws off other years (ex: would sort in order 2012-456, 2013-555, 2012-1234). I'm guessing I'll have to prepend 0's to the digits after the hyphen if less than 4 digits, but I have not been able to get the sorter to work. I have tried .addParser but I'm not familiar with that and have not been successful. Are there any good articles for what I'm looking for or does anyone know a way to accomplish this?
Here is an image of example data that is sorting incorrectly and would need to sort in order of year (first 4 digits) then number after hyphen:
**Also, the date should have been in a better format obviously, but in this case I'm not able to adjust how that is entered.

After debugging further I was finally able to get .addParser() to work, and condensed the code as much as I could. I guess because I am new(ish) to javascript, I didn't realize that the .length was counting spaces and/or returns in my html.
$('.tablesorter').tablesorter({
widgets: ['zebra'],
headers: {
0: {
sorter: 'licenseYear'
}
}
})
$.tablesorter.addParser({
id: 'licenseYear',
is: function (s) {
return false;
},
format: function (s) {
//pad zeros for max length of digits after hyphen
var pad = "0000";
//replace hyphen with needed zeros to pad number
var n = s.replace(/-/, pad.substring(s.length - 5));
return n;
},
type: 'numeric'
});
*EDIT: Condensed code with help from this thread about padding left: convert '1' to '0001' in JavaScript

Related

Jquery leave only two numbers after decimal point

Been looking for this a while now, most questions include same answers which I have tried and it did not work for my case, hence why I am posting this. Now my script returns several numbers and I want to leave those numbers and 2 numbers after the decimal point, now the problem is that I have another script that adds commas to those numbers, so for example, I might get following numbers.
56,883.90,607,219,945
5,327.078,363,188,421
1688.7000000000003
2,739.272
Now I have tried several stuff, including Number(number).toFixed(2), etc. But it would cut off some parts, for example.
first number above would return > "56.00", While I need it to return 56,883.90
Would return > "5.00", While I need 5,327.07
would return what I am expecting "1688.70"
Would return "2.00" instead of 2,739.27
Now I understand where the issue is, it takes comma and turns number afterwards, is there way to specifically grab only 2 numbers after the DOT?
Thanks in advance
Use Regex:
'56,883.90,607,219,945'.replace(/(\..{2}).*/,'$1')
Which matches all of your expected results:
56,883.90,607,219,945 => 56,883.90
5,327.078,363,188,421 => 5,327.07
1688.7000000000003 => 1688.70 (it will not add comma)
2,739.272 => 2,739.27
function changeToNumber(str) {
return str.replace(/(\..{2}).*/, '$1');
}
var input = ['56,883.90,607,219,945',
'5,327.078,363,188,421',
'1688.7000000000003',
'2,739.272'
]
input.forEach(function(value) {
console.log(changeToNumber(value));
});
You have to remove the , from the number string to parse the full number. Use String#replace method to remove , from the string.
Number('5,327.078'.replace(/,/g, ''))
console.log(Number('5,327.078'.replace(/,/g, '')).toFixed(2));

Regex replace for commas in the thousands

I have a Javascript function I'm using to loop through a bunch of inputs on a page and convert them to a thousands-compatible comma system. In short, regardless of what the user types into the field, they'll get a friendly thousands-separated number back.
Input: 5000
Return: 5,000
Here's how the function breaks down
function add_commas()
{
$('.field-group .field input[type=text]').each(function()
{
// format number
$(this).val(function(index, value) {
return value
.replace(/\D/g, "")
.replace(/\B(?=(\d{3})+(?!\d))/g, ",")
;
});
});
}
Everything's working right except for one thing. Here's another example of the data being passed in and what's returned:
Input: 9.5
Return: 95
Note the whole number.
I'm wondering if there's a way to ignore or leave off the decimal if it didn't have one, but keep it and treat it respectfully if there is one. Here's the input/output as I would hope for:
Input: 5000
Return: 5,000
Input: 9.5
Return: 9.5
Input: 1000.50
Return: 1,000.50
Hopefully this was clear, but please do let me know if you require more information about the issue at hand. Thank you!
Actually regular expressions are not appropriate for this problem, because not every culture uses commas as thousands separators and periods for the radix separator. You should be using toLocaleString. In node, for example:
> (52342.214).toLocaleString()
'52,342.214'
> (52342.214).toLocaleString('de-DE')
'52.342,214'
> (52342.214).toLocaleString('ar-EG')
'٥٢٬٣٤٢٫٢١٤'
> (5234289877.21).toLocaleString('en-US')
'5,234,289,877.21'
This way you don't have to write your own error-prone code and you can localize for different cultures. The work has already been done for you!
You also get the zeros part of your question for free too! Notice:
> (38209).toLocaleString()
'38,209'
> (38209.0000).toLocaleString()
'38,209'
Again, all for free!
Change the first replace because it is removing the dot in the string
.replace(/[^0-9\.]/g, "")

custom sort for an array of timezone offsets

I am attempting to sort an array of timezone offsets that looks like the following:
["+03:00", "-11:00", "+05:00", "-04:00"]
This is just a subset of the array. All of the offsets for GMT based timezones are included. The logical ordering would be distance from GMT starting with -11.00
So the final correct ordering would be:
["-11:00", "-04:00", "+03:00", "+05:00"]
I'd have to use Array.prototype.sort here, but I'm not entirely sure what the most effective custom sort function to use here would be. Would it involve breaking the string up into two parts? eg: -|+ and offset, eg: 11, 4, 3, 5 and then comparing those? Is there a way to do it with less processing?
sort function should be
function(a, b) {
return parseFloat(a.replace(':', '.')) - parseFloat(b.replace(':', '.'));
}
basically, change the : to a . and return the difference in the resulting parsed floats
You can also do the following:
function(a, b) {
return parseInt(a.replace(':', ''), 10) - parseInt(b.replace(':', ''), 10);
};
This would convert the strings to +/-HHMM which you can then parse as an integer and still be able to support the not insubstantial number of non whole hour timezones. Though I don't think there's that much performance to be gained
Assuming that the timezones always end in :00 you can simply parseInt them:
["+03:00", "-11:00", "+05:00", "-04:00"].sort(
( a, b ) => (a, 10) > parseInt(b, 10)
);
parseInt will read a string up until it finds characters that don't look like numbers. For example parseInt('1a') returns 1. Since the first part of '-11:00' is a valid number ('-11'), parseInt will correctly read it.

TableSorter doesn't recognize numbers

I have these two examples, which both use the same code but different sources of tablesorter. However one of them works as the other one doesn't.
$("table").tablesorter();
http://jsfiddle.net/lightheaded/x78cd/ (doesn't work)
http://jsfiddle.net/lightheaded/RYL54/ (works)
It should first sort by percent and then by users. However it doesn't recognize the second number to be a number. I have a similar situation on my site. What could be the issue? I'm using 2.14.4 min on my site as well.
Upgrade to a more recent version of table sorter. Recent version seems to parse out tokens from strings such as 99% coverage (12.08 million users) and 99% coverage (10.2 million users) and compare them one by one so strings that contain more than one number still sort out as expected (we have 10 compared with 12 in the above example).
OR: you can create a custom parser that normalizes the percentage and users; and use it:
$.tablesorter.addParser({
id: 'percentThenUsers',
is: function (s) {
return false;
},
format: function (s) {
// "99% coverage (12.08 million users)" gets converted to
// "1099 1012.08" which can then be sorted as text
var m = s.replace(/[^\d\.]/g, " ").replace(/ +/g, " ").split(" ");
return (+m[0] + 1000) + " " + (+m[1] + 1000);
},
type: 'text'
});
$(function () {
$("table").tablesorter({
debug: true,
headers: {
0: { sorter: 'percentThenUsers' }
}
});
});
Demo here
Tablesorter attempts to detect the content of table cells automatically. In this case it is finding text and not percentage or digit values.
The first demo is using the original tablesorter which doesn't use alphanumeric sorting, so it can only sort text blocks. Check out this updated demo where a row with this data is added:
<tr><td>10% coverage (1.0 million users)</td></tr>
The 10% is placed above 100% in ascending sorts - not what you would expect.
The second demo is using an updated version of tablesorter which does use alphanumeric sorting. It splits the text into blocks and is able to sort the content as you would expect. Here is an updated demo with the above row included.
If you "need" to use the original tablesorter, then use the parser provided by #SalmanA.

Excel to XML: Round decimals to the nearest hundredth and keep hyperlinks

I followed this guide to export an Excel Spreadsheet as an XML data file and then this guide to display the XML sheet as an HTML table on my website. It worked great. Now I "only" have to small issues remaining that I couldn't get solved.
(1) The output table contains numbers like 1.325667 but also lots of 0s. I would like the zeroes to be displayed as 0.00 and the numbers with many decimals to be displayed as 1.33. Basically, each number should be displayed with two decimals.
(2) The excel sheet contains hyperlinks to other pages on my website that I would like to keep when rendering the XML data file and then the HTML table. So far, that didn't work. Is this possible?
UPDATE I figured this part out. By breaking up the hyperlinks in just their character-strings, then adding new columns for these character strings, and then tweaking the source code to including
document.write("<tr><td><a href='");
document.write(x[i].getElementsByTagName("character-string")0].childNodes[0].nodeValue);
document.write(".php'>");
document.write(x[i].getElementsByTagName("name")[0].childNodes[0].nodeValue);
document.write("</a></td>");
I was able to include hyperlinks.
The Excel-Sheet is formatted with these two aspects already integrated, but the conversion to an XML file seems to be the problem.
Thank you so much for your help (again and again :-))
UPDATE I now also found a way to do the rounding in Excel, but I'm still stuck with integers and numbers with only one decimal. Basically, I now "only" need a way to show every number with two decimal points, applying to integers (e.g. 0 should 0.00) and numbers with one decimal (e.g. 1.5 should be 1.50). JohnnyReeves' answer seems to be on the right track but I couldn't get it to work. Any other ideas?
The Number Object has the method toFixed():
1.325667.toFixed(2) = 1.33.
Running inside the loop of the XML, select the URL and add it to the link:
document.write("< a href=" + x[i].getElementsByTagName(< your URL link>) + ">);
document.write("some text");
document.write("< /a>");
The Number.toFixed method will only work on floating point values (eg: 2.1), but not on integers (eg: 2, or 0). You will need to convert your number type to a string type so you can format it for display and get consistent results regardless of the input. A function like this should do the trick:
function formatNumber(value) {
var parts,
trailingDigits,
formattedRemainder;
// Coerce the supplied value to a String type.
value = String(value);
// Break the supplied number into two parts, before and after the dot
parts = value.split(".");
// If there was no dot, there will only be one "part" and we can just
// add the trailing zeros.
if (parts.length === 1) {
formattedRemainder = "00";
}
else {
trailingDigits = parts[1];
if (trailingDigits.length === 0) {
// A dot, but no digits. (eg: 2. -> 2.00)
formattedRemainder = "00";
}
else if (trailingDigits.length === 1) {
// Add an extra trailing zero (eg: 2.1 -> 2.10)
formattedRemainder = trailingDigits + "0";
}
else {
// Just take the last two trailing digits.
formattedRemainder = trailingDigits.substring(0, 2);
}
}
// Build the final formatted string for display.
return parts[0] + "." + formattedRemainder;
}

Categories

Resources