Strontium_99
Strontium_99

Reputation: 1803

Style large numbers using jquery

I've got a large table containing numbers among other things. I'm trying to colour the large numbers based on decimal, hundreds, thousands and millions.

EG.

<tr>
   <td class="numColour">20,000,365.00 ISK</td>
   <td class="numColour">2,467,218,928.46 ISK</td>
   <td class="numColour">498,356.65 ISK</td>
</tr>

There are a load more numbers, but they are all in a TD class=numColour. What I'm after is something like this:

<tr>
   <td class="numColour"><span class="red">20</span>,<span class="blue">000</span>,<span class="green">365</span>.<span class="white">00</span> ISK</td>
   <td class="numColour"><span class="yellow">2</span>,<span class="red">467</span>,<span class="blue">218</span>,<span class="green">928</span>.<span class=white">46</span> ISK</td>
   <td class="numColour"><span class="blue">498</span>,<span class="green">356</span>.<span class="white">65</span> ISK</td>
</tr>

This is possibly a horrible way of doing it, but I started placing all the spans with this:

$('.numColour').each(function(){
    var tempVal = $(this).html();
    tempVal = tempVal.replace(' ISK', '</span> ISK').replace('.', '</span>.<span>').replace(/,/g, '</span>,<span>');
    tempVal = "<span>" + tempVal;
    $(this).html(tempVal);
});

Then thinking I could add the classes after. But I can't work out how to start from the decimal point and work backwards applying the relevant classes to the relevant values. IE.

Fractions = white hundreds = green thousands = blue millions = red hundreds of millions = yellow

Stumped. Would be most grateful of any help at all. Thanks.

Upvotes: 1

Views: 80

Answers (2)

Palpatim
Palpatim

Reputation: 9262

This isn't a really optimal solution, but here's some functions to get you started. DEMO

HTML

<table id="numbers">
  <tr>
    <td class="numColour">20,000,365.00 ISK</td>
  </tr>
  <tr>
    <td class="numColour">2,467,218,928.46 ISK</td>
  </tr>
  <tr>
    <td class="numColour">498,356.65 ISK</td>
  </tr>
</table>

CSS

body {
  background: #666;
  color: #999;
}

.numColour {
  font-family: monospace;
}

.fraction {
  color: #fff;
}

.int-group-1 {
  color: #00c800;
}

.int-group-2 {
  color: #0000c8;
}

.int-group-3 {
  color: #c80000;
}

.int-group-4 {
  color: #c8c800;
}

.int-group-5 {
  color: #00c8c8;
}

JavaScript

var SEPARATOR_DECIMAL_US_EN = '.';
var SEPARATOR_GROUP_US_EN = ',';

var normalizeNumberFromString = function(s, decimalSeparator) {
  var intParts;
  decimalSeparator = decimalSeparator || SEPARATOR_DECIMAL_US_EN;
  var normalized = s.trim().replace(/[^0-9.]/g, "");
  var parts = normalized.split(decimalSeparator);
  return {
    intPart: parts[0],
    fractionPart: parts[1]
  }
}

var separateIntIntoReversedGroups = function(i) {
  var parts = [];
  var part;
  i = parseInt(i, 10);

  while (i > 0) {
    part = i % 1000;
    parts.push(part);
    i = parseInt(i / 1000, 10);
  }
  return parts;
}

var padNum = function(n, pad, len) {
  var i = 0;
  var padLength;
  var s = '';

  n = '' + n;

  pad = '' + pad;
  pad = pad.charAt(0) || ' ';

  if (n.length >= len) {
    return '' + n;
  }

  padLength = len - n.length;
  for (i; i < padLength; ++i) {
    s = s + pad;
  }
  s = s + n;
  return s;
}

var formatStringFromSeparatedNumber = function(reversedIntGroups, fractionPart, groupSeparator, decimalSeparator) {
  var g, i, intGroups = [], numGroups = reversedIntGroups.length, s = '';

  groupSeparator = groupSeparator || SEPARATOR_GROUP_US_EN;
  decimalSeparator = decimalSeparator || SEPARATOR_DECIMAL_US_EN;

  for (i = reversedIntGroups.length - 1; i >= 0; i--) {
    g = '<span class="int-group-' + (i+1) + '">';
    if (i < reversedIntGroups.length - 1) {
      g += padNum(reversedIntGroups[i], 0, 3);
    } else {
      g += reversedIntGroups[i];
    }
    g += '</span>';
    intGroups.push(g);
  }
  s = intGroups.join(groupSeparator);
  s = s + decimalSeparator + '<span class="fraction">' + fractionPart + '</span>';
  return s;
};

var formatNumberString = function(s) {
  var parts, reversedIntGroups;
  parts = normalizeNumberFromString(s);
  reversedIntGroups = separateIntIntoReversedGroups(parts.intPart);
  return formatStringFromSeparatedNumber(reversedIntGroups, parts.fractionPart, ',', '.');
};

var replaceWithFormattedNumber = function(i, el) {
  var $el = $(el);
  var v = $el.html();
  v = formatNumberString(v);
  console.log('v::', v);
  $el.html(v);
};

$(document).ready(function() {
  $('.numColour').each(replaceWithFormattedNumber);
});

Upvotes: 0

j08691
j08691

Reputation: 207901

This worked for me:

var colors = ['hund', 'thou', 'mill', 'hmill'];
$('td.numColour').html(function () {
    var input = $(this).text();
    var num = input.split(' ');
    var dec = '<span class="frac">' + num[0].split('.')[1] + "</span>";
    var front = num[0].split('.')[0].split(',');
    for (var i = front.length - 1, j = 0; i >= 0; i--, j++) {
        front[i] = '<span class="' + colors[j] + '">' + front[i] + '</span>'
    }
    full = front.join(',') + '.' + dec + ' ' + num[1];
    return (full)
})

jsFiddle example

Upvotes: 2

Related Questions