TanStack / table

πŸ€– Headless UI for building powerful tables & datagrids for TS/JS - React-Table, Vue-Table, Solid-Table, Svelte-Table
https://tanstack.com/table
MIT License
25.02k stars 3.07k forks source link

row selection not working for nested rows (`getSubRows`) #4878

Open csantos-nydig opened 1 year ago

csantos-nydig commented 1 year ago

Describe the bug

row-selection in the group rows are not correctly reacting to their sub-rows row-selection state

Your minimal, reproducible example

https://codesandbox.io/s/row-selection-sub-rows-kfgh2j

Steps to reproduce

  1. Go to https://codesandbox.io/s/row-selection-sub-rows-kfgh2j
  2. Expand the first group row
  3. Select the first sub-row
  4. βœ… Notice the parent row checkbox being "indeterminate" image
  5. Select the other 2 sub-rows in that same group
  6. πŸ›‘ Notice the parent row checkbox is "unchecked", when it should be "checked" image

Probably the same issue:

  1. Go to the same codesandbox: https://codesandbox.io/s/row-selection-sub-rows-kfgh2j
  2. Expand the first group row
  3. Select the checkbox from the column header
  4. βœ… Notice all rows (parent and children) are selected image
  5. Unselect the first sub-row of the expanded group
  6. πŸ›‘ Notice the parent row checkbox is stuck on "checked", when it should be "indeterminate" image

Expected behavior

As a user, I expected the parent row to react to the row-selection status of its children, regardless on how they are selected/unselected:

How often does this bug happen?

Every time

Screenshots or Videos

No response

Platform

Happens in codesandbox

react-table version

v8.9.1

TypeScript version

N/A - whatever codesandbox uses

Additional context

No response

Terms & Code of Conduct

VincEnterprise commented 1 year ago

Also see: https://github.com/TanStack/table/issues/4720

@tannerlinsley could you please take a look at this πŸ₯ΉπŸ™

I really want to use tabstack table for a project but this specific issue is preventing me from being able to use it.

This naive UI example here (cascade checking) has the behavior we are expecting:

https://www.naiveui.com/en-US/os-theme/components/tree#cascade.vue

VincEnterprise commented 1 year ago

bump

artem-zaiko-yara commented 1 year ago

I use this workaround until the bug is fixed (React):

useEffect(() => {
  const { rows } = table.getRowModel();
  rows.forEach((row) => {
    const allSuRowsSelected = row.subRows.length > 0 && row.subRows.every(({ getIsSelected }) => getIsSelected());
    if (allSuRowsSelected) {
      row.toggleSelected(true);
    }
  });
}, [rowSelection, table]);
R-Bower commented 8 months ago

Link to fix: https://github.com/TanStack/table/issues/3965#issuecomment-1912872932

Profesor08 commented 8 months ago

bump, issue is actual

Current workaround is to toggle manually

  useEffect(() => {
    const { rows } = table.getRowModel();

    rows.forEach((row) => {
      if (row.subRows.length > 0) {
        if (row.getIsAllSubRowsSelected() === true) {
          row.toggleSelected(true);
        } else if (row.getIsSomeSelected() === false) {
          row.toggleSelected(false);
        }
      }
    });
  }, [rowSelection, table]);
VACincoming commented 7 months ago

Any updates on this issue? I'm planning to update from v7 -> v8 because v7 has a bug with isSomeSelected prop for nested rows, but looks like updating does not make any sense because a v8 still has a problem with checkboxes for nested rows...

3965

pelletier197 commented 7 months ago

Just noticed the same issue :+1:

Macs89 commented 6 months ago

Yep, I've run into this issue too.

minhdtb-tanaakk commented 6 months ago

same issue here

cthomesmatt commented 6 months ago

bump, issue is actual

Current workaround is to toggle manually

  useEffect(() => {
    const { rows } = table.getRowModel();

    rows.forEach((row) => {
      if (row.subRows.length > 0) {
        if (row.getIsAllSubRowsSelected() === true) {
          row.toggleSelected(true);
        } else if (row.getIsSomeSelected() === false) {
          row.toggleSelected(false);
        }
      }
    });
  }, [rowSelection, table]);

This is a great fix since the issue is still occurring, thank you! I noticed that the table.getIsSomeRowsSelected() handler isn't counting grouped rows that are being selected, so to fix this I fixed up a function you can use to check if any are selected in the grouped or subrows, hope it helps someone like it did for me.

function getIsAnyRowsSelected(table: Table<any>) {
    const rows = table.getExpandedRowModel().rows;
    const { rowSelection } = table.getState();

    let isAnyRowsSelected = rows.some(row => {
      if (rowSelection[row.id]) return true;

      if (row.subRows.some(subRow => rowSelection[subRow.id])) return true;

      return false;
    });

    return isAnyRowsSelected;
  }
vladcos commented 5 months ago

same issue

mttigg commented 5 months ago

Following this issue.

xuyunan commented 4 months ago

same issue

etiennecoyacabelio commented 2 months ago

same issue