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

[TreeView] Add checkbox support #6019

Closed
1 task done
cpdwyer opened this issue Sep 12, 2019 · 21 comments · Fixed by #11452
Closed
1 task done

[TreeView] Add checkbox support #6019

cpdwyer opened this issue Sep 12, 2019 · 21 comments · Fixed by #11452
Assignees
Labels
component: tree view TreeView, TreeItem. This is the name of the generic UI component, not the React module! new feature New feature or request

Comments

@cpdwyer
Copy link

cpdwyer commented Sep 12, 2019

Thanks for the Component, it works really well. Unfortunately I have come across on problem in the implementation which I can't seem to find a workaround for.

  • I have searched the issues of this repository and believe that this is not a duplicate.

Summary 💡

I am looking to use the TreeView / TreeItem components with a check box on each row. Ideally I would like a prop to suppress the event that expands and collapses the tree if the CheckBox is clicked. Or maybe a prop to enable a checkbox with a prop to set the value and a call back when clicked that also avoids the list toggle.

At the moment when a check box is toggled it also expands and collapses the tree when the node has children.

Thank You.

Examples 🌈

image

This is the current code...

const checkBoxClicked = (event, checked, id) => {
   setOrgStructureElement(checked, id, selected, orgStructure);
};

const createOrgStructureLevel = orgStructureElement => {
   const elements = [];

    orgStructureElement.forEach((v, k) => {
      const { id, children } = v;
      if (k.length !== 0) {
        const label = (
          <div style={{ display: 'flex', alignItems: 'center' }}>
            <Checkbox
              id={`checkbox-${k}`}
              className={classes.globalFilterCheckbox}
              checked={selected.has(id)}
              onChange={(event, checked) => checkBoxClicked(event, checked, id)}
              color="primary"
            />
            <Typography variant="caption">{k}</Typography>
          </div>
        );
        elements.push(
          children && children.length > 0 ? (
            <TreeItem key={id} nodeId={id} label={label}>
              {createOrgStructureLevel(children)}
            </TreeItem>
          ) : (
            <TreeItem key={id} nodeId={id} label={label} />
          ),
        );
      } else if (children) {
        elements.push(createOrgStructureLevel(children));
      }
    });
    return elements;
  };

  const handleExpanded = (nodeId, nodeExpanded) => {
    // cache expanded nodes
    if (nodeExpanded) {
      addOpenOrgStructurePanel(nodeId);
    } else {
      removeOpenOrgStructurePanel(nodeId);
    }
  };

  return (
    <TreeView
      defaultExpanded={openOrgStructurePanels}
      onNodeToggle={(nodeId, nodeExpanded) => handleExpanded(nodeId, nodeExpanded)}
      defaultCollapseIcon={<ExpandMoreIcon />}
      defaultExpandIcon={<ChevronRightIcon />}>
      {orgStructure.length !== 0 ? createOrgStructureLevel(orgStructure) : null}
    </TreeView>
  )
};

Motivation 🔦

see above

@oliviertassinari oliviertassinari added the new feature New feature or request label Sep 12, 2019
@mbrookes
Copy link
Member

@cdwyer-cognito does Event.stopPropogation in the checkbox click handler help?

@thclark
Copy link

thclark commented Sep 25, 2019

@mbrookes I can confirm no, Event.stopPropagation() doesn't help. Using the following handler:

  handleCheck(event) {
    // Prevent the checkbox-clicked event from firing the collapse/expand action on the tree
    // This makes no difference to behaviour
    event.stopPropagation()
    console.log('CHECKBOX CHANGED')
  }

@cdwyer-cognito did you fix this in the end?

@thclark
Copy link

thclark commented Sep 25, 2019

Ok. fixed.

After delving into the mui code, I realised the problem here. The Checkbox is handling the onChange event from its base input, not an onClick.

So capturing the onChange and stopping it from propagating won't do any good - the original onClick event bubbles up the DOM to the TreeItem where it's handled here. Sigh.

Anyhoo, simple fix is to give the checkbox an onClick handler as well as an onChange handler. This isn't documented in the checkbox api, but it ends up being given to the IconButton here

So here's a Checkbox which will work for this purpose:

<Checkbox
    id={`checkbox-${yourId}`}
    checked={isChecked}
    onChange={(e, checked) => (console.log('you checked it!', checked)}
    onClick={e => (e.stopPropagation())}
    {...props}
/>

@cpdwyer
Copy link
Author

cpdwyer commented Oct 5, 2019

So sorry, I've not looked at this thread for a while. That looks a good solution, I'll give it a go and let you know. Thank you

@cpdwyer
Copy link
Author

cpdwyer commented Oct 5, 2019

Great, that works perfectly. I had tried to stop the propergation on the onChange, I understand why that didn't work now. Thank you again.

@ReactWithRajesh
Copy link

can you shair current code of checkbox treeview

@dnquang1996vn
Copy link

@RjSingh1529 my solution in typescript
https://codesandbox.io/s/typescript-data-driven-treeview-dhkx2?file=/src/App.tsx

@eps1lon
Copy link
Member

eps1lon commented Jul 31, 2020

We probably need to have a dedicated TreeItemCheckbox anyway to get the a11y story right. Then we also have better control over event propagation quirks.

@arbabi2010
Copy link

arbabi2010 commented Nov 10, 2020

@thclark please share your complete code with us . if it is possible.

@datchanhkun
Copy link

@RjSingh1529 my solution in typescript
https://codesandbox.io/s/typescript-data-driven-treeview-dhkx2?file=/src/App.tsx

I don't understand the getChildByID code. Can you re-explain how you checked the child when the parent is checked.

@hamsishe
Copy link

Added auto selection for parent when children are selected. And the same for deselection.
Improved a bit search for selected node.
@dnquang1996vn Thank you for your example!
https://codesandbox.io/s/edeyu

@SawkaDev
Copy link

SawkaDev commented Aug 19, 2022

Added auto selection for parent when children are selected. And the same for deselection. Improved a bit search for selected node. @dnquang1996vn Thank you for your example! https://codesandbox.io/s/edeyu

@hamsishe great work! Any tips on how I could extend this to where the children could be a group of radio buttons (in addition to have checkboxes in the same parent)

Ideally I am needing something that can extend to this

Parent 1
  Child 1.1 CheckBox
  Child 1.2 CheckBox
  Child 1.3 CheckBox
   1.3.1 Radio Option 1
   1.3.1 Radio Option 2
   1.3.1 Radio Option 3
   1.3.2 Checkbox
  Child 1.4 CheckBox

Only one option in 1.3.1 should be allowed to be selected for radio boxes, checkboxs you can select N amount.

@pursonc
Copy link

pursonc commented Sep 3, 2022

Great sample.

@oliviertassinari oliviertassinari transferred this issue from mui/material-ui Sep 3, 2022
@oliviertassinari oliviertassinari added component: tree view TreeView, TreeItem. This is the name of the generic UI component, not the React module! plan: Pro Impact at least one Pro user labels Sep 3, 2022
@Shivraj97
Copy link

Added auto selection for parent when children are selected. And the same for deselection. Improved a bit search for selected node. @dnquang1996vn Thank you for your example! https://codesandbox.io/s/edeyu

Hi @hamsishe Can you please tell me what to do when I don't have a root parent node? I mean the structure of data is an array of objects and not an object. I don't want the Parent label to render

@Kavan72

This comment was marked as off-topic.

@oliviertassinari oliviertassinari removed the plan: Pro Impact at least one Pro user label Jul 15, 2023
@MrPoint1400

This comment was marked as off-topic.

1 similar comment
@srgg

This comment was marked as off-topic.

@zhangjianrencai
Copy link

Added auto selection for parent when children are selected. And the same for deselection. Improved a bit search for selected node. @dnquang1996vn Thank you for your example! https://codesandbox.io/s/edeyu

@hamsishe Do you know how to resolve this issue when the data's length === 200, the error will happen
image

@flaviendelangle flaviendelangle self-assigned this Mar 1, 2024
@truongnt27
Copy link

@Shivraj97 Just use data.map(item => renderTree(item))

Copy link

⚠️ This issue has been closed. If you have a similar problem but not exactly the same, please open a new issue.
Now, if you have additional information related to this issue or things that could help future readers, feel free to leave a comment.

@cpdwyer: How did we do? Your experience with our support team matters to us. If you have a moment, please share your thoughts in this short Support Satisfaction survey.

@oliviertassinari
Copy link
Member

See #12883 for the continuation of this issue, to get to the right checkbox selection behavior.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: tree view TreeView, TreeItem. This is the name of the generic UI component, not the React module! new feature New feature or request
Projects
None yet