Render problem with function in array

Render problem with function in array

HexaHexa Posts: 10Questions: 1Answers: 0

Hello,

I am testing Editor and I have a problem with the render.
Line 83 of the code is not interpreted. Also, instead of having a comma separating the decimal part, it is a "." that appears and the "€" sign does not appear.
However, the render works correctly on the other lines.
It comes from "function () {return (this.Loyer / this.Superifice) .toFixed (2)}" but I can't do it any other way.

An idea ?

Thank you.

var dataSet = [
    {
        "DT_RowId": "row_1",
        "Étage": "RDC",
        "Type - numéro": " T1 - 01",
        "Superficie": "32.50",
        "Terrasse": "28.00",
        "Mezzanine": "",
        "Loyer": "875",
        "Prix au m²": function(){return(this.Loyer / this.Superficie).toFixed(2)}
    },
    {
        "DT_RowId": "row_2",
        "Étage": "RDC",
        "Type - numéro": " T1 - 02",
        "Superficie": "28.50",
        "Terrasse": "25.00",
        "Mezzanine": "",
        "Loyer": "795",
        "Prix au m²": function(){return(this.Loyer / this.Superficie).toFixed(2)}
    },
    {
        "DT_RowId": "row_3",
        "Étage": "RDC",
        "Type - numéro": " T1 - 03",
        "Superficie": "28.50",
        "Terrasse": "22.00",
        "Mezzanine": "",
        "Loyer": "775",
        "Prix au m²": function(){return(this.Loyer / this.Superficie).toFixed(2)}
    }
]

var editor; // use a global for the submit and return data rendering in the examples
        
$(document).ready(function() {
    editor = new $.fn.dataTable.Editor( {
        data: dataSet,
        table: "#loyers",
        fields: [   {
                label: "Superficie :",
                name: "Superficie"
            }, {
                label: "Terrasse :",
                name: "Terrasse"
            }, {
                label: "Mezzanine :",
                name: "Mezzanine",
            }, {
                label: "Loyer :",
                name: "Loyer",
            },  
        ]
    } );
    $('#loyers').on( 'click', 'tbody td', function (e) {
        var index = $(this).index();
 
        if ( index === 2 || index === 3 || index === 4) {
            editor.bubble( this, {
                message: 'Entrez un nombre décimal séparé par un point.',
                submit: 'allIfChanged'
            } );
        }
        else if ( index === 5 ) {
            editor.bubble( this ), {
                submit: 'allIfChanged'
            }
        }
    } );
    $('#loyers').DataTable( {
        dom: '"Brt"',
        data: dataSet,
        searching: false,
        paging: false,
        info: false,
        columns: [
            { data: "Étage" },
            { data: "Type - numéro" },
            { data: "Superficie",render: $.fn.dataTable.render.number(' ', ',', 2, '', ' m²') },
            { data: "Terrasse",render: $.fn.dataTable.render.number(' ', ',', 2, '', ' m²')},
            { data: "Mezzanine",render: $.fn.dataTable.render.number(' ', ',', 2, '', ' m²')},
        { data: "Loyer",render: $.fn.dataTable.render.number(' ', ',', 0, '', ' €')},
        { data: "Prix au m²",render: $.fn.dataTable.render.number(' ', ',', 2, '', ' €')},
        ],

Replies

  • colincolin Posts: 15,118Questions: 1Answers: 2,583

    You can't have functions in the data, so you would need to move your equation into the columns.render function, like this,

    Colin

  • HexaHexa Posts: 10Questions: 1Answers: 0

    Thank you for your reply but with your solution, average footerCallback doesn't work in the last column :

    An idea ?

    // footerCallback
                    "footerCallback": function(row, data, start, end, display) {
                        var api = this.api(), data;
    
    
                        // Remove the comma for calcuations
                        var intVal = function ( i ) {
                            return typeof i === 'string' ?
                                    i.replace(/,/g,'')*1 :
                                    typeof i === 'number' ?
                                            i : 0;
                        };
    
                        var columnData = api.column(0).data();
    
                        //Average
                        api.columns('.avg', {
                            page: 'current'
                        }).every(function() {
    
                            var numerator = this
                                    .data()
                                    .reduce( function(a, b) {
                                        return (intVal(a) + intVal(b));
                                    }, 0);
    
                            var denominator = this.data().length;
    
                            avg = numerator / denominator;
                            // Replace dot by comma
                            avg = avg.toFixed(2).toString().replace (/\./g, ',');
                            $(this.footer()).html("" + avg + " €");
    
                        }); //end Average
    
  • kthorngrenkthorngren Posts: 20,147Questions: 26Answers: 4,736

    average footerCallback doesn't work in the last column :smile:

    What happens. Please provide a test case showing the issue so we can help debug.
    https://datatables.net/manual/tech-notes/10#How-to-provide-a-test-case

    Kevin

  • HexaHexa Posts: 10Questions: 1Answers: 0

    live.datatables.net/dekusidi/1/edit

    At the bottom of the last column, the average no longer works and stay at 0,00€. Thanks a lot for your help.

  • kthorngrenkthorngren Posts: 20,147Questions: 26Answers: 4,736

    Thanks for the test case. To get the rendered data you will need to use cells().render() as discussed in this thread. For example:
    http://live.datatables.net/habejejo/1/edit

    I had to add a function, removeSymbol(), to remove the " €" form the rendered data.

    Kevin

  • HexaHexa Posts: 10Questions: 1Answers: 0

    Sorry but I don't understand. I need the 7th column average to appear in the 7th column footer.
    In your example, there is a number and I big number and I don't understand what he's coming to do there.

  • kthorngrenkthorngren Posts: 20,147Questions: 26Answers: 4,736

    Looks like you have api.columns('.avg', { for this column which I din't notice before. Make the changes to this code to use cells().render() and to call removeSymbol() instead of intVal(). Basically what I have in the 7th column cdoe I added at the end of initComplete.

    Kevin

  • arcanisgkarcanisgk Posts: 41Questions: 12Answers: 0

    other way is eval the data and execute function trough the array .... before send it to datatable.

  • HexaHexa Posts: 10Questions: 1Answers: 0

    I'm a beginner and I can't seem to get the right result. I tried to modify the code as you indicated but I am afraid of being mistaken. Could you correct this one please?

    live.datatables.net/comaloma/1/edit

  • kthorngrenkthorngren Posts: 20,147Questions: 26Answers: 4,736

    Here is the updated example:
    http://live.datatables.net/qugavoso/1/edit

    See the inline comments I added to the api.columns('.avg').every(function() { section
    of code. You had .data() which is not correct.

    'm a beginner and I can't seem to get the right result.

    I also added a console.log statement for debugging which you can remove. Sometime you either need to use console.log statements or the browser's debugging tools with breakpoints to find out how the code is behaving.

    I added another function called convertCommaToDecimal() which replaces the , in the number with . so that the numbers are summed correctly.

    Kevin

  • HexaHexa Posts: 10Questions: 1Answers: 0

    Thank you very much for your responsiveness and your help.

    There seems to be a problem. I tried to change a number in the "loyer" column. If I put 9000 all is ok but if I put 90000 the average in the footer is wrong ;-(
    How can a mistake happen?

  • kthorngrenkthorngren Posts: 20,147Questions: 26Answers: 4,736

    What is incorrect? Can you update the example to show the problem? Did you use console.log statements to see if you can isolate the problem?

    Kevin

  • HexaHexa Posts: 10Questions: 1Answers: 0

    Impossible since the modification with editor is not saved.
    By default the average of the 7th column is € 24.98.
    If I modify a number in the 6th column by changing it to 90000, the result of the row in 7th column is good but the average of the column is not.

    For example, I change the 750 in the first line of the 6th column to 90000. The first box in the 7th column updates well in 2769.23. But the average of the 7th column should be around 200 and it is only 23.58. Why is that ?

  • kthorngrenkthorngren Posts: 20,147Questions: 26Answers: 4,736

    Impossible since the modification with editor is not saved.

    If you are talking about live.datatables.net the changes should be saved. The URL may change or you may need to clone a copy a message pops up indicating that you need to make a clone.

    I made a bad assumption about your data in this code:

                        // Remove symbol from rendered data
                        var removeSymbol = function (i) {
               
                            return typeof i === 'string' ?
                                    convertCommaToDecimal( i.split(' ')[0] ) :
                                    typeof i === 'number' ?
                                            i : 0;
                        }
    

    I was trying to make it generic to handle any symbol by using split(" "). Looks like the best thing to do is to reverse what you are using in the render function, something like this:
    intVal($.fn.dataTable.render.number('', '', 2, '', '').display(i)) :

    http://live.datatables.net/qugavoso/3/edit

    Kevin

  • HexaHexa Posts: 10Questions: 1Answers: 0

    Now it works for 90,000 but if you change 90,000 to 25 it will no longer work! The average is no longer good, it stands at more than 2000 when it should be less than 30 ;-(

  • kthorngrenkthorngren Posts: 20,147Questions: 26Answers: 4,736

    I changed your render function to this:

                       render: function( data, type, row, meta) {
                          var val = (row.Loyer / row.Superficie).toFixed(2)
                          if ( type === 'display') {
                            return $.fn.dataTable.render.number(' ', ',', 2, '', ' €').display(val)
                          }
                          return val;
                       }
    

    It uses Orthogonal Data to display the data with the €' but leave the underlying data without the added symbol. This allowed removing the other functions I added and just use the intVal() to make sure the data is a number.

    http://live.datatables.net/qugavoso/5/edit

    Kevin

  • HexaHexa Posts: 10Questions: 1Answers: 0

    It's perfect !
    A huge thank you :-)

This discussion has been closed.