CirclonGroup / angular-tree-component

A simple yet powerful tree component for Angular (>=2)
https://angular2-tree.readme.io/docs
MIT License
1.1k stars 492 forks source link

tri-state checkboxes #83

Closed Freest10 closed 7 years ago

Freest10 commented 8 years ago

Hello, are you planning "tri-state checkboxes"? I am very need in this in my project) tree_check

adamkleingit commented 8 years ago

Sometime in the future yes, but don't know when. It is completely possible to implement this yourself using angular2-tree-component BTW

popojargo commented 7 years ago

Simply add a checkbox in the template. Then, you need to add the selection logic.

Using the events, you can bind the onActivate and onDeactivate events to check and uncheck the checkboxes.

debslab commented 7 years ago

Please let us know if you are planning to add this out of the box. If not, can you please provide a sample template which includes html structure. Do I need to include the checkbox inside TreeNodeContent?

adamkleingit commented 7 years ago

Hi,

I don't have any schedule for this yet. I'm currently solving performance issues for large trees using virtual scroll and MobX.

MobX is a great way to do tri-state checkboxes, so I plan to use it for this feature as well.

You can override either the treeNodeTemplate or the treeNodeFullTemplate, please refer to the docs.

Thanks

debslab commented 7 years ago

Thank you. I am trying following template.

<Tree [nodes]="nodes"> <template #treeNodeTemplate let-node="node" let-index="index"> <input (click)="go(tree, node, $event)" type="checkbox" #Nodecheck> {{ node.data.name }}

Now in the function go, I need to get access to all child nodes checkbox so that I can check them. Please let me know how I can achieve it.

debslab commented 7 years ago

Hi..any update on my previous comment...it's an awesome component to use in my project..only one thing which is bugging me is not having checkbox support...if you provide some pointer to how we shall do it, it will be highly appreciated...

adamkleingit commented 7 years ago

Hi,

you can you node.getVisibleChildren() to access all children that are visible, or just node.children if you are not doing any filtering on the tree. Also - it's better to use (change) and not (click) on checkboxes, and you must also use [checked] to bind to the checked property of the checkbox.

All the best

--

On Thu, Feb 16, 2017 at 5:30 PM, debslab notifications@github.com wrote:

Hi..any update on my previous comment...it's an awesome component to use in my project..only one thing which is bugging me is not having checknox support...if you provide some pointer to how we shall do it, it will be highly appreciated...

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/500tech/angular2-tree-component/issues/83#issuecomment-280362938, or mute the thread https://github.com/notifications/unsubscribe-auth/AA2SSvzzZRDImJJZZu4Nrl-tle1PmyZsks5rdGumgaJpZM4KZwFd .

debslab commented 7 years ago

Thanks a lot. I have done the implementation as following. // html <Tree [nodes]="groups" #tree [options]="treeOptions" (onActivate)="selectNode($event)"> <template #treeNodeTemplate let-node="node" let-index="index"> <input (change)="go(tree, node, $event,nodeEdit)" type="checkbox" id="check-{{node.data.id}}"> {{ node.data.name }} // code executed if we click on any checkbox public updateChildNodesCheckBox(node,checked) { if (node) { var inputValue:HTMLInputElement = document.getElementById('check-' + node.id); if(inputValue) { inputValue.checked = checked; } for (let i = 0; i < node.children.length; i ++) { this.updateChildNodesCheckBox(node[i], checked); } }

}

But when I access child nodes, if the node is collapsed, I cannot get hold of the child nodes as they are not there in dom. A workaround is to check or uncheck those child checkbox when the node is expanded. Please let me know if I am missing something here.

debslab commented 7 years ago

Actually in onToggleExpanded also, I am not getting hold of child node as it's yet to be rendered. So I am not able to do the workaround I mentioned earlier. Please help

debslab commented 7 years ago

If I get an event after expand, that will suffice as that time child nodes will be available to me

adamkleingit commented 7 years ago

Hey,

you shouldn't update DOM elements directly. Angular provides data-binding for that. You should update a checked property on the nodes themselves and bind to it using [checked] property. something like:

<input ... [checked]="node.data.checked">

updateChildNodesCheckBox(node) {
  node.checked = true;
  if (node.children) {
    node.children.forEach((child) => updateChildNodesCheckBox(child));
  }
}
debslab commented 7 years ago

Thank you very much. Finally I am able to implement this. For setting child nodes checkbox, I followed your approach. But for parent nodes I needed to access DOM elements directly. I needed to set the checkbox of parent to indeterminate state which, I guess, is not possible without accessing DOM element. Using checked property of angular, I can select or unselect a checkbox, but unable to set indeterminate state.

debslab commented 7 years ago

Logic I have written to set parent node checkbox-

public updateParentNodesCheckBox(node) {
    if (node && node.level > 0 && node.children) {
        let allChildChecked = true;
        let noChildChecked = true;
        for (let child of node.children) {
            if (!child.data.checked) {
                allChildChecked = false;
            } else if (child.data.checked) {
                noChildChecked = false;
            }
        }
        let inputValue: HTMLInputElement = <HTMLInputElement> document.getElementById('check-' + node.id);
        if (allChildChecked) {
            node.data.checked = true;
            inputValue.indeterminate = false;
        } else if (noChildChecked) {
            node.data.checked = false;
            inputValue.indeterminate = false;
        } else {
            node.data.checked = true;
            inputValue.indeterminate = true;
        }
        this.updateParentNodesCheckBox(node.parent);
    }

}
adamkleingit commented 7 years ago

Hey, You should be able to use [indeterminate] as well in the template. Angular allows to bind to all properties of DOMNodes.

debslab commented 7 years ago

thank you. I updated my code.

touqeershafi commented 7 years ago

do we have any official documentation on this feature ?

debslab commented 7 years ago

here you go - https://angular2-tree.readme.io/docs/tri-state-checkboxes

kmuseligadoo commented 4 years ago

Hello, i am using the same code but the indeterminate is not working on save Any help?