Tabulator: How to update formatter on data reload?

Created on 10 Jul 2017  路  6Comments  路  Source: olifolkerd/tabulator

I have some code to format cells according to whether or not they match a certain string thisCohort. The value of this string changes every time I load new data, and my intent is is to update the formatter every time I load new data.

var format3 = d3.format(",.2f");

function createTable(tabledata, cohort){
  // $("#example-table").tabulator("clearData");

  // $("#migration-table").empty();

  var thisCohort = cohort;
  $("#migration-table").tabulator({
    columns:[
        {
            title:"Source Cohort",
            field:"source_level2_cohort",
            sorter:"string",
            width:150,
            formatter: function(cell, formatterParams){
              var value = cell.getValue();
              return value === thisCohort ? "<span style='font-weight:bold;'>" + value + "</span>" : value;
            }
        },
        {
            title:"Target Cohort",
            field:"target_level2_cohort",
            sorter:"string",
            width:150,
            formatter: function(cell, formatterParams){
              var value = cell.getValue();
              return value === thisCohort ? "<span style='font-weight:bold;'>" + value + "</span>" : value;
            }
        },
        {
            title:"Number of Customers",
            field:"cid_count",
            sorter:"number",
            width:150
        },
        {
            title:"Revenue Change($)",
            field:"revenue_difference",
            sorter:"number",
            width:150,
            // formatter:"money"
            formatter: function(cell, formatterParams){
              var value = cell.getValue(),
                  sign = value >= 0 ? "" : "-",
                  color = value >= 0 ? "black" : "red";
                  text = "<span style='color:"+color+";'>" +sign +"$"+format3(Math.abs(value))+ "</span>";
                  // text = "<font color="+color+">"+sign +"$"+format3(Math.abs(value))+"</font>";
              return "<div>"+text+"</div>";
            }
        }
        // {title:"Migration Type", field:"migration_category", sorter:"string", width:150}
        // {title:"Gender", field:"gender", sorter:"string", cellClick:function(e, cell){console.log("cell click")},},
    ]
  });

  $("#migration-table").tabulator("setData", tabledata);

  $("#migration-table").tabulator("setSort", "revenue_difference", "desc");
};

There is a user interaction which loads new data to the tabledata variable and calls the createTable() function.

When I do this, the data is correctly updated in the table, but for some reason my formatter function behaves as if it still has the original value of the thisCohort variable. So all the wrong cells are bolded. I can reload new data multiple times and it's always the original value that is bolded.

Am I implementing my formatters correctly or is there another way to set this up that will apply the new value of thisCohort every time I reload the data.

Question - Ask On Stack Overflow

All 6 comments

Hey,

there is no need to recreate the table each time you have new data, you can just call the setData function with the new data and the table will update.

This is probably what is causing your issues as tabulator will not allow itself to rebuilt unless you call destroy first to remove the old table (which would be a bit overkill in this scenario).

I would recommend that you declare the table and the thisCohort variable outside the scope of your table update function, then just update the thisCohort variable and call the tabulator setData function inside your update function.

let me know if that makes sense.

Cheers

Oli

Hey there,

Moving the table column definitions outside of my update loop solved the problem

Thanks for the help!

Karl

Similar, but different problem:

var format_options = function(cell, params){
    return (cell.getData().status == 'okay') ? "Okay" : "";
}

columns = [
    {title: "Options", field: 'movie_id', formatter: format_options},
    {title: "Date", field: "scene_date", formatter: format_date}
]

$.ajax ...
   row.update(data)

When I update a row with row.update(data), the row updates correctly with the new data, but the options-cell stays empty. Meanwhile, the date will get updated correctly, besides also having a formatter.
I checked and the format_date will be called, the format_options not.

Even when I set the movie_id to 0 before the row.update(data), the format_options won't be called again, though the rows value changed. Even when I call format_options() and put the result into cell.getElement().html(), nothing happens?

What am I doing wrong?
Am I correct in the conclusion that cells only get reformatted/redrawn when their data changes in the row.update? If so, would I be doing the force-update via row.update({movie_id: 0}), row.update(data) correctly?

Okay, the cell.getElement() needed other interfacing, disregard that, that was my jquery-mistake ;)

What remains is that format_options does not get called on row.update, but format_date does. I need to manually call format_options and replace the cell.getElement() after the row.update(). Why?

When you update a row, only cells where the data has changed are redrawn, any where the data is the same are not touched as it is more efficient.

...aaand sure, it does :/
It seems this was a result of an earlier mistake of having actually two columns with the field 'movie_id' with different titles, so I didn't notice. All the row.update() testing I did seemed to happen in that other column, which was hidden, ofc... :)

row.update({'movie_id': -1});
row.update(data);

Works like a charm and redrawing only the cells which are updated makes totally sense.

Sorry for bothering ;)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mindcreations picture mindcreations  路  3Comments

c3pos-brother picture c3pos-brother  路  3Comments

Manbec picture Manbec  路  3Comments

aballeras01 picture aballeras01  路  3Comments

andreivanea picture andreivanea  路  3Comments