在制表符中如何将选定数据用于底行计算

In tabulator how to use selected data for bottom row calcs

我有一个相当简单的 table,目前正在使用底部计算器格式化程序:

export let myTable = new Tabulator("#my-table", {
  columns:[
      {title:"ID", field:"id", headerSort:false, visible:false, responsive:2},
      {formatter:"rowSelection", titleFormatter:"rowSelection", align:"center", bottomCalc:"sum", hozAlign:"center", headerSort:false, cellClick:function(e, cell){
        cell.getRow().toggleSelect();
      }},
      {title:"Name", field:"address", width:300, bottomCalc:"count"},
      {title:"My Data", field:"mydata", bottomCalc:avNoOutsiders},
      ],
});
export let avNoOutsiders = function(values, data, calcParams){
  // filter outliers
  let myArray = filterOutliers(values);
  // filter any null or falsy values
  let av = average(myArray);
  return av
}

代码不是特别重要,但我希望能够做的是允许用户取消 select 行以从该计算中排除该值。

问题是,我不明白如何访问这里的isSelected()函数,我认为只有row()我可以访问它。我可以访问 values(所有列值)但是那里没有 selection 数据,我可以访问 data - 整个 table,但是没有办法确定它是哪一行,或者它是否被 select 编辑。

我目前的思考方向是

  1. 使用 bottomCalcParams。我不明白我该怎么做。这个函数returns一个getRow() is not a function错误:
function cellIsSelected(cell){
  selected = cell.getRow().isSelected()
  return {isSelected:selected};
}

  1. 为每个底部计算编写单独的函数。这不起作用,因为我无法在 table 计算中调用 table - var selectedRows = table.getSelectedRows() 如果我尝试将其放入列计算函数中,则会导致循环错误。我可以在 table.
  2. 中引用 table

关于如何访问行 selection 数据以进行列计算的任何想法?

可能有一种更简单的方法,但实现该方法的一种方法是创建一个隐藏的占位符列,该列可以在第 selection/deselection 行更新为 true/false。然后,您可以在 bottomCalc 函数中使用此隐藏列的值来排除未选中的行。这是一个示例,其中选择一行将 re-trigger 计算底部并平均所有选择的年龄:

const dataSet1 = [
  { id: 1, name: 'Billy Bob', age: '21', gender: 'male' },
  { id: 2, name: 'Mary May', age: '5', gender: 'female' },
  { id: 3, name: 'Christine Lobowski', age: '42', gender: 'female' },
  { id: 4, name: 'Brendon Philips', age: '80', gender: 'male' },
]

const calcAvg = (values, data, calcParams) => {
  let selected = data.filter((row) => row.isSelected)

  values = selected.map((i) => i.age)

  let avg = values.reduce((a, b) => Number(a) + Number(b), 0) / values.length

  return avg ? avg : ''
}

const table = new Tabulator('#table', {
  data: dataSet1,
  columns: [
    {
      formatter: 'rowSelection',
      titleFormatter: 'rowSelection',
      cellClick: (e, cell) => {
        cell.getRow().toggleSelect()
      }
    },
    { title: 'Name', field: 'name' },
    { title: 'Age', field: 'age', bottomCalc: calcAvg },
    { title: 'Gender', field: 'gender' },
    { title: '', field: 'isSelected', visible: false }  // Selection placeholder column
  ]
})

const selection = (row) => {
  row.update({ isSelected: row.isSelected() })
  table.recalc()
}

table.on('rowSelected', selection)
table.on('rowDeselected', selection)
<html>

<head>
  <link href="https://unpkg.com/tabulator-tables@5.2.2/dist/css/tabulator.min.css" rel="stylesheet">
  <script type="text/javascript" src="https://unpkg.com/tabulator-tables@5.2.2/dist/js/tabulator.min.js"></script>
</head>

<body>
  <div id="table"></div>
</body>
<html>

@Tim 的回答让我完成了 95% 的工作。

请注意,他的某些回复不适用于 Tabulator v4.9:

const selection = (row) => {
  row.update({ isSelected: row.isSelected() })
  table.recalc()
}

table.on('rowSelected', selection)
table.on('rowDeselected', selection)

我认为解决这个问题可能比更新需要更长的时间,所以我跳槽并更新到 5.2.2,这没有预期的那么痛苦。我有多个列要计算,因此我不是 运行 每个列都有不同的函数,而是通过 bottomCalcParams 将字段名称传递给函数,因此:

const calcAvg = (values, data, calcParams) => {
  let selected = data.filter((row) => row.isSelected)
  // Add your calcParams here:
  values = selected.map((i) => i[calcParams.field]) 

  let avg = values.reduce((a, b) => Number(a) + Number(b), 0) / values.length

  return avg ? avg : ''
}

const table = new Tabulator('#table', {
  data: dataSet1,
  columns: [
    {
      formatter: 'rowSelection',
      titleFormatter: 'rowSelection',
      cellClick: (e, cell) => {
        cell.getRow().toggleSelect()
      }
    },
    { title: 'Name', field: 'name' },
    { title: 'Age', field: 'age', bottomCalc: calcAvg, bottomCalcParams:{field:"age"} },
    { title: 'Remaining Teeth', field: 'teeth', bottomCalc: calcAvg, bottomCalcParams:{field:"teeth"} },
    { title: 'Personality Quirks', field: 'quirks', bottomCalc: calcAvg, bottomCalcParams:{field:"quirks"} },
    { title: 'Gender', field: 'gender' },
    { title: '', field: 'isSelected', visible: false }  // Selection placeholder column
  ]
})