Javascript: Ordinal suffix for numbers with specific CSS class
My own suggestion, would be:
$(".ordinal").text(function (i, t) {
i++;
var str = i.toString().slice(-1),
ord = '';
switch (str) {
case '1':
ord = 'st';
break;
case '2':
ord = 'nd';
break;
case '3':
ord = 'rd';
break;
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case '0':
ord = 'th';
break;
}
return i + ord;
});
JS Fiddle demo.
This effectively takes the incremented number (i++
, in order to start from 1
not 0
), converts it to a string, then looks at the last number of that string. This should work for any number, since the ordinal is based purely on that last number.
You could also extend the Number
prototype to implement this functionality:
Number.prototype.ordinate = function(){
var num = this + 1,
last = num.toString().slice(-1),
ord = '';
switch (last) {
case '1':
ord = 'st';
break;
case '2':
ord = 'nd';
break;
case '3':
ord = 'rd';
break;
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case '0':
ord = 'th';
break;
}
return num.toString() + ord;
};
$(".ordinal").text(function (i, t) {
return i.ordinate();
});
JS Fiddle demo.
Edited to offer a slight alternative:
Number.prototype.ordinate = function(){
var num = this,
last = num.toString().slice(-1),
ord = '';
switch (last) {
case '1':
ord = 'st';
break;
case '2':
ord = 'nd';
break;
case '3':
ord = 'rd';
break;
default:
ord = 'th';
break;
}
return num.toString() + ord;
};
$(".ordinal").text(function (i,t) {
return t.replace(/(\d+)/g, function(a){
return parseInt(a, 10).ordinate();
});
});
JS Fiddle demo.
This essentially iterates over each .ordinal
element, replacing the numbers present with the (same) numbers with the ordinal suffix added to it.
Edited to address the problem, raised in the comments, below, that 11
, 12
and 13
were receiving the ordinal suffix of st
, nd
and rd
(respectively). This is now corrected to being th
in all cases:
Number.prototype.ordinate = function(){
var num = this,
numStr = num.toString(),
last = numStr.slice(-1),
len = numStr.length,
ord = '';
switch (last) {
case '1':
ord = numStr.slice(-2) === '11' ? 'th' : 'st';
break;
case '2':
ord = numStr.slice(-2) === '12' ? 'th' : 'nd';
break;
case '3':
ord = numStr.slice(-2) === '13' ? 'th' : 'rd';
break;
default:
ord = 'th';
break;
}
return num.toString() + ord;
};
JS Fiddle demo.
References:
slice()
.switch()
.text()
.toString()
.
I created two approaches one using Prototype, the other as a plugin :
Number.prototype.between = function(n,m){ return this > n && this < m }
Number.prototype.ORDINATE_INDEX = ["th","st","nd","rd"];
Number.prototype.toOrdinate = function(){
var
nthMod = (this % 10),
index = nthMod > 3 || this.between(10,20) ? 0 : nthMod
;
return this + this.ORDINATE_INDEX[index];
};
$(".ordinal").text(function (index, element) {
return parseInt(element).toOrdinate();
});
This is the one as a Jquery Plugin :
(function($){
var numberTool = new (function(){
var private = {};
private.ORDINATE_INDEX = ["th","st","nd","rd"];
private.parseOrdinary = function(number)
{
var
nthMod = (number % 10),
index = nthMod > 3 || private.between(number, 10,20) ? 0 : nthMod
;
return number + private.ORDINATE_INDEX[index];
}
private.between = function(number, n,m){
return number > n && number < m
}
this.isNumeric = function(number)
{
return !isNaN(parseFloat(number)) && isFinite(number);
}
this.toOrdinary = function(number)
{
return this.isNumeric(number) ? private.parseOrdinary(number) : number;
}
});
$.fn.toOrdinary = function(){
return this.each(function(){
$element = $(this);
$element.text(numberTool.toOrdinary($element.text()));
});
};
})(jQuery);
$(".ordinal").toOrdinary();
$(".ordinal").toOrdinary();
$(".ordinal").toOrdinary();
Tested on JSFIDDLE:
The prototype version example : http://jsfiddle.net/f8vQr/6/
The JQuery version example : http://jsfiddle.net/wCdKX/27/
function nth(n){
if(isNaN(n) || n%1) return n;
var s= n%100;
if(s>3 && s<21) return n+'th';
switch(s%10){
case 1: return n+'st';
case 2: return n+'nd';
case 3: return n+'rd';
default: return n+'th';
}
}
You can take care of the teens in their own line, other integers follow the last digit rules.