Search code examples
c#asp.net-mvcasp.net-coreasp.net-ajaxtabulator

API Tabulator - Summing Columns Values - dynamic total on cell value edit


I am developing a web app in C#, asp.net, JQuery, and Tabulator which is fed via a REST API

I am trying to achieve 2 things, my tabulator definition below, should provide a row sum total in the:

 AvailTotal field 

After an edit to each of the column values in any columns:

 availableBedsM, availableBedsF, availableBedsC

Could someone help please, I need a default sum in the AvailTotal Columns, and for ths to reflect any edit to the above fields dynamically when a value changes.

My Tabulator:

 // tabulator start
 var tabledata = new Tabulator("#example-table", {
     persistence:true, //enable table persistence
     reactiveData: true,
     height: (window.innerHeight - 10),
     ajaxURL: "api/bed_data_",
     groupBy:"siteCOSitrep",
     columns:[

     {title:"Ward Code", 
         field:"wardCode", 
         frozen:true,
         width:200
     },
         {//create column group
             title:"Available Beds",
                      columns:[
                      {title:"Male", 
                     field:"availableBedsM", 
                     align:"center", 
                     headerVertical:true,  
                     width:50, 
                     editor:"number",
                     validator:["integer", "min:0", "required", "max:99"],
                     topCalc:"sum", topCalcParams:{precision:0,},
                     cellEdited: function(cell) {
                     cell.AvailTotal = cell.getValue() + tabledata.availableBedsF + tabledata.availableBedsC;}
            },

                 {title:"Female", 
                     field:"availableBedsF", 
                     align:"center", 
                     headerVertical:true, 
                     width:50, 
                     editor:"number",
                     validator:["integer", "min:0", "required", "max:99"],
                     topCalc:"sum", topCalcParams:{precision:0,},
                     cellEdited: function(cell) {
                     cell.AvailTotal = cell.getValue() + tabledata.availableBedsM + tabledata.availableBedsC;}
            },
                 {title:"Cubicle", 
                     field:"availableBedsC", 
                     align:"center", 
                     headerVertical:true, 
                     width:50, 
                     editor:"number",
                     validator:["integer", "min:0", "required", "max:99"],
                     topCalc:"sum", topCalcParams:{precision:0,},
                     cellEdited: function(cell) {
                     cell.AvailTotal = cell.getValue() + tabledata.availableBedsM + tabledata.availableBedsC;}
                 },
                 {title:"Avail Total",  
                     field:"AvailTotal",
                     align:"center", 
                     headerVertical:true, 
                     width:50,
                     topCalc:"sum", topCalcParams:{precision:0,},
                    },
                 ],
         },

Solution

  • If you want to have a column based off of a calculation of the value of other columns then you need to look at using a Mutator

    if we assume you have a third column that you want to hold a value of the sum of the val1 and val2 columns then the definition would be something like this:

    var sumMutator= function(value, data, type, params, component){
        //value - original value of the cell
        //data - the data for the row
        //type - the type of mutation occurring  (data|edit)
        //params - the mutatorParams object from the column definition
        //component - when the "type" argument is "edit", this contains the cell component for the edited cell, otherwise it is the column component for the column
    
        return data.val1 + data.val2;
    }
    
    {title:"Sum Column", field:"sumcol", mutator:sumMutator}
    

    If you are manipulating the data, you should always use a mutator as it changes the data itself, which means that the column will sort correctly. if you use a formatter that is purely a visual effect and will mean you would be unable to sort or filter the column.

    If you want to the calculated column to update when the other columns are changed then i would suggest using the cellEdited callback to trigger an update on that column:

    function updateCalc(cel){
        cell.getRow().update({sumcol:false});
    }
    {title:"Val 1", field:"val1", cellEdited:updateCalc}
    

    it dosn't matter what value you give sumcol, changing it will trigger the mutator which will recalculate the value