Error rendering negative numbers represented as strings

Error rendering negative numbers represented as strings

Alex FiennsAlex Fienns Posts: 2Questions: 1Answers: 0


I've been using the dataTable.render.number function to format values that are supplied as <td>12.3445678%</td> which works fine until you get a negative value such as <td>-12.345678%</td> which is correctly formatted but is missing the "-" character at the beginning. is a proof of concept. As you can see all the outputs are as expected apart from the Negative String column which doesn't have a - value which is present in the Number column. What is interesting is that ordering the table by the String column does give us the correct response.

If we look at the source code for the number function:-

            number: function ( thousands, decimal, precision, prefix, postfix ) {
                    return {
                            display: function ( d ) {
                                    if ( typeof d !== 'number' && typeof d !== 'string' ) {
                                            return d;

                                    var negative = d < 0 ? '-' : '';
                                    var flo = parseFloat( d );

                                    // If NaN then there isn't much formatting that we can do - just
                                    // return immediately, escaping any HTML (this was supposed to
                                    // be a number after all)
                                    if ( isNaN( flo ) ) {
                                            return __htmlEscapeEntities( d );

                                    flo = flo.toFixed( precision );
                                    d = Math.abs( flo );

                                    var intPart = parseInt( d, 10 );
                                    var floatPart = precision ?
                                            decimal+(d - intPart).toFixed( precision ).substring( 2 ):

                                    return negative + (prefix||'') +
                                                    /\B(?=(\d{3})+(?!\d))/g, thousands
                                            ) +
                                            floatPart +

then I believe that the problem is that when the negative prefix is calculated that d is still a String and therefore can't be <0. If this was moved down to after the isNan check and checked against flo rather than d then the functionality should be correct.



  • allanallan Posts: 61,669Questions: 1Answers: 10,096 Site admin

    Hi Alex,

    Thanks for this - the problem you are encountering here is that the number formatter expects its inputs to be completely unformatted - i.e. not % or anything else. The idea is that the formatter would add them as required.

    So an updated version of your example reflecting that would be: .

    If it isn't possible to change your input value to just a plain number, that it would need a custom renderer to be used, to first strip the symbols and then do whatever formatting is needed (you can use the built in formatter directly calling $.fn.dataTable.render.number(...).display(value);).


  • Alex FiennsAlex Fienns Posts: 2Questions: 1Answers: 0

    I fully understand that the string "should" be parseable as a number. However the fact that everything else apart from the negative marker worked when the string had a trailing "%" made me think that it "should" work and I felt it was odd that it mostly worked.

    The % symbol is added by my backend to ensure that the cell gets marked correctly when using the excel exporter and formatted as a percentage cell in the generated excel file.

  • pybcgpybcg Posts: 41Questions: 10Answers: 0


    I noticed if a number is -.05 and you round it to zero decimal places, it shows as "-0" instead of just "0". Is there a fix for this? Please view link above

  • allanallan Posts: 61,669Questions: 1Answers: 10,096 Site admin

    @pybcg - Thanks! That's a good one. I've fixed it here and it will be in the nightly soon.


This discussion has been closed.