Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot toggle selection of grouped row to deselect its children #4759

Open
2 tasks done
mollykreis opened this issue Mar 17, 2023 · 7 comments · May be fixed by #4760
Open
2 tasks done

Cannot toggle selection of grouped row to deselect its children #4759

mollykreis opened this issue Mar 17, 2023 · 7 comments · May be fixed by #4760

Comments

@mollykreis
Copy link

Describe the bug

I have a table with grouping and selection enabled. I would like to achieve the following behavior:

  • Non-grouped rows are selectable; selection is toggled via a checkbox on the row
  • Grouped rows have selection checkboxes, but they don't have their own selection state
    • the checkbox is checked if all sub rows are checked
    • the checkbox is not checked is all subrows are unchecked
    • the checkbox is indeterminate if some sub rows are checked
    • interactively toggling the checkbox manually selects/deselects all sub rows

To get this behavior, I've configured my table as follows:

  • enableRowSelection: function that returns true for non-grouped rows and false for grouped rows
  • enableMultiRowSelection: true
  • enableSubRowSelection: true
  • state of the checkbox for grouped rows is updated programmatically using row.getIsAllSubRowsSelected() and row.getIsSomeSelected()
  • interaction with checkbox for rows (both grouped and non-grouped) calls row.toggleSelected(newCheckboxState)

Problem:
Interactively trying to uncheck a grouped row's checkbox does nothing when it should deselect all the rows beneath it. The problem is that the grouped row will always return false from row.getIsSelected(). Calling toggleSelection(false) on this grouped row, which should deselect all the sub rows, returns early because it detects that the row is already not selected so there is nothing to be done to deselect it.

Your minimal, reproducible example

https://codesandbox.io/p/sandbox/crimson-river-2ysx73

Steps to reproduce

In the code sandbox:

  1. Expand a group
  2. Click the selection checkbox for the expanded group to mark it as selected
  3. See that all the subrows were selected (correct)
  4. Click the selection checkbox for the expanded group again to mark it as not selected
  5. Notice that nothing happened. The group and subrows remained selected when the desired behavior was for the group and subrows to all become not selected.

Expected behavior

I expected to create a grouped row whose selection is based only on the selection of its subrows. Clicking the checkbox associated with that grouped row toggles the selection for all of its subrows.

How often does this bug happen?

Every time

Screenshots or Videos

No response

Platform

Not platform specific

react-table version

8.7.9

TypeScript version

No response

Additional context

As a note, I also went down an implementation path where I had enableRowSelection set to true for both grouped rows and non-grouped rows. However, this also did not lead to the behavior I wanted. The primary problem I encountered was that I didn't want a group's selection state to be part of TanStack's row selection state because the group's selection state is always determined programmatically by the state of its subrows.

Terms & Code of Conduct

  • I agree to follow this project's Code of Conduct
  • I understand that if my bug cannot be reliable reproduced in a debuggable environment, it will probably not be fixed and this issue may even be closed.
@KevinVandy
Copy link
Member

I see this issue reproduced in your sandbox, but I have yet to be able to reproduce this issue anywhere else. And actually, after modifying your sandbox a bit, I was able to solve the bug by just using the built-in row.getToggleSelectedHandler() method.

https://codesandbox.io/p/sandbox/priceless-swanson-cc7w0c?file=%2Fsrc%2Fmain.tsx

I'll need to look more into this to see if the change here is necessary.

@mollykreis
Copy link
Author

@KevinVandy Thanks for looking into this. The solution you mentioned of using row.getToggleSelectedHandler() on the grouped rows does not give me the behavior I am looking for. Specifically, I want the selection state of the grouped rows to be based purely on the state of its subrows using groupedRow.getIsAllSubRowsSelected() and groupedRow.getIsSomeSelected(). I do not want the grouped rows to maintain a selected/unselected state themselves because this will become stale in TanStack's rowSelection state as the selection state of subrows changes and as the table's data is updated.

In a sense, what I am looking for is a way to have a group selection checkbox that behaves exactly like a selection checkbox for the entire table:

  • The state of the checkbox is always calculated based on other rows in the table
  • There is no persisted selection state associated with the group row that could become stale
  • Toggling the value of the checkbox is an action taken at a specific instance in time that affects the current subrows, but isn't a state that affects any new rows that might be added if the table's data is updated
  • I can use the table's rowSelection state to trivially determine the set of selected data row IDs (does not include grouped rows) and the number of selected rows (again excluding grouped rows) without having to perform a look up for every selected row ID to determine whether it is a data row or a grouped row

I am open to alternative suggestions of how to achieve this behavior. For example, would you be more receptive to a more focused function on a row whose entire purpose is to toggle the selection of subrows? An approach like that would mirror the toggleAllRowsSelected() function on the table.

@VincEnterprise
Copy link

I'm fully with @mollykreis , also see this issue:

#4720

@VincEnterprise
Copy link

bump, any news on this?

@VincEnterprise
Copy link

bump

@csantos-nydig
Copy link

This seems to be the same issue I'm experiencing on #4879 and #4878 :/

@dimbslmh
Copy link

try the following:

<IndeterminateCheckbox
{...{
  checked: row.getIsAllSubRowsSelected(),
  indeterminate: row.getIsSomeSelected(),
  onChange: () =>
    row.subRows.forEach((subRow) =>
      subRow.toggleSelected(
        !row.getIsAllSubRowsSelected(),
      ),
    ),
}}
/>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants