【问题标题】:Tabulator formatter calculates percent of another column制表器格式化程序计算另一列的百分比
【发布时间】:2021-08-06 08:12:26
【问题描述】:

希望这对我来说足够简单,不会丢掉 Codepen 等。

我正在尝试在制表符中创建自定义格式化程序/修改器,但我很难获取另一列的总数。 bottomCalc 无法访问,我不明白如何访问另一列中的所有数据以循环运行它们。

ID Percent Amount
1 25 10
2 12.5 5
3 12.5 5
4 50 20
Total 100 40
{title:"%", field:"calc-pct", sorter:"number", formatter:function(cell){
    let amt = cell.getRow().getCell("amount");
    let amtCol = cell.getRow().getColumn("amount");
    // loop through amount to get total here
        amtTotal += amt
    pct = amt / amtTotal
    return pct;
}},

Tabulator 文档内容广泛且非常有用,但没有大量关于在格式化程序/修改器中使用 getData()、getRow() 内容的信息——其中很多似乎更适用于表格后的外部函数已建成。有用的东西,但不适用于我的情况。

编辑:

不幸的是,没有包括这个,但除了让这个工作,我需要能够编辑 Amount 列并获得实时更新百分比。我已经在下面发布了解决方案,希望其他正在寻找此解决方案的人可以得到一些帮助!

【问题讨论】:

    标签: javascript tabulator


    【解决方案1】:
    let amountColTotal = 0;
    cell.getTable().getData().forEach(row => { amountColTotal += row.amount; });
    

    这太简单了。

    你也可以使用getCalcResults()

    【讨论】:

    • 为这个 Michael 干杯,经过一些测试,我意识到很可能一个 mutator 更符合我的要求,因为我希望能够编辑和实时更新金额列,并让 pct 列实时更新。让我开始,如何循环遍历突变器中的表格数据(例如,在我的例子中的数量列)。我尝试了一堆组合(data.getTable();value.getTable()),据我了解,它们都在后台处理数据。
    • 问题是,据我所见,我可以访问行数据,但不能访问表的其余部分,或者 getCalcResults() 数据,因为它们尚未运行。
    • 更新了我的问题以反映我在寻找什么。
    【解决方案2】:

    因此,在迈克尔的帮助下,我设法完成了这项工作。我不得不通过控制台稍微分析一下表格数据,但设法让它与以下内容一起工作。我想 Tabulator 中可能有一些内置方法可以访问表中的所有行,但我无法用 getRow() 等来弄清楚。

    格式化程序:

    在表加载、pct 字段的初始填充时运行。

    let pctFormatter = function(cell){
        let amountColTotal = 0;
        cell.getTable().getData().forEach(row => { amountColTotal += parseFloat(row.amount); });
        console.log("Amount PCT col total: " + amountColTotal)
        let amount = cell.getRow().getCell("amount").getValue();
        console.log("Amount PCT: " + amount)
        return Math.round ( ( ( amount / amountColTotal ) * 100 ) * 10 ) / 10;
    }
    

    突变体:

    在数量编辑时运行,循环遍历表格数据并在calc_pct 列中的每个单元格上设置值,使用新的 pct 数字更新值。

    export let pctMutatorRun = function(cell) { 
        cell.getRow().getCell("calc_srm").setValue(true);
        let table = cell.getTable()
        table.rowManager.rows.forEach(row => {
            console.log(row.getCell("calc_pct").setValue(true));
        });
    
    

    桌子:

    {title:"%", field:"calc_pct", sorter:"number", formatter:pctFormatter},
    {title:"Amt (kg)", field:"amount", editor:"input", sorter:"number", bottomCalc:"sum", cellEdited:pctMutatorRun, bottomCalcParams:{precision:3}},
    

    【讨论】:

      【解决方案3】:

      这里是jsfiddle,以防万一您想包括过滤

      comment.log("leave me alone Stackoverflow.com");
      

      【讨论】:

      • 谢谢伙计!当我有时间时会比较这两种方法。制表器没有原生列过滤吗?
      • 不确定您所说的原生列过滤是什么意思?有可编程过滤器和 headerFilters。 headerFilters 是最容易进行演示的(如 jsfiddle),但它们通常非常简单(在此示例中,只是直接的“=”)。但您练习的要点是,并非数据中的每一行都被显示/用于计算,这会影响底部计算,从而影响您的百分比列。
      • Cheers Michael - 再看一眼,我想我假设您在那里放置的过滤器功能是非内置的,但它也只是为了更新表格列。谢谢老哥!
      【解决方案4】:

      您可以调用一个函数来计算表的dataLoaded 回调和您要编辑的列的cellEdited 回调上的百分比(在下面的示例中为updatePercent),以实现您要查找的内容:

      var updatePercent = async () => {
          await table.recalc();
        
        var sum = table.getCalcResults().bottom.amount;
        var data = table.getData('active');
        
        data.forEach(row => row.percent = (row.amount / sum) * 100);
        table.updateData(data);
      }
      
      var table = new Tabulator("#example-table", {
        height: '100%',
        layout: "fitColumns",
        dataLoaded: updatePercent,
        dataFiltered: updatePercent,
        columns: [{
            title: "Name",
            field: "name"
          },
          {
            title: "Percent",
            field: "percent",
            bottomCalc: "sum"
          },
          {
            title: "Amount",
            field: "amount",
            bottomCalc: "sum",
            editor: "input",
            headerFilter: true,
            cellEdited: updatePercent
          }
        ]
      });
      
      var tabledata = [{
          id: 1,
          name: "Oli Bob",
          amount: 10
        },
        {
          id: 2,
          name: "Mary May",
          amount: 5
        },
        {
          id: 3,
          name: "Christine Lobowski",
          amount: 5
        },
        {
          id: 4,
          name: "Brendon Philips",
          amount: 20
        }
      ];
      
      table.setData(tabledata);
      html,
      body {
        font-size: 12px;
      }
      
      .tabulator {
        font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji;
      }
      <html>
      
      <head>
        <link href="https://cdnjs.cloudflare.com/ajax/libs/tabulator/4.9.3/css/bootstrap/tabulator_bootstrap4.min.css" rel="stylesheet" />
        <script src="https://cdnjs.cloudflare.com/ajax/libs/tabulator/4.9.3/js/tabulator.min.js"></script>
      </head>
      
      <body>
        <div id="example-table"></div>
      </body>
      
      </html>

      JSFiddle:https://jsfiddle.net/9n0fwz4e/

      编辑:

      带头过滤:https://jsfiddle.net/ox09p8Lq/

      【讨论】:

      • 根据 Michael O'Keefe 的过滤建议更新了我的答案以包括过滤。谢谢迈克尔。
      猜你喜欢
      • 1970-01-01
      • 2020-01-25
      • 2022-06-23
      • 2021-09-13
      • 2019-11-20
      • 1970-01-01
      • 2021-05-10
      • 1970-01-01
      • 2019-01-26
      相关资源
      最近更新 更多