jjimenezshaw / Leaflet.Control.Layers.Tree

a Tree Layers Control for Leaflet
https://jjimenezshaw.github.io/Leaflet.Control.Layers.Tree/examples/basic.html
BSD 3-Clause "New" or "Revised" License
148 stars 36 forks source link

Feature Request: Checkbox on non-leaf, to uncheck/check all descendants. #12

Closed MappingSteve closed 4 years ago

MappingSteve commented 5 years ago

When there are many leaf nodes, simply collapsing/expanding the tree helps manage them, but doesn't make it easier to turn on/off many nodes; AFAIK, they have to be checked/unchecked one at a time.

Would be great if each non-leaf also had a checkbox. This has 3 possible states: all children are checked => checked, all children are unchecked => unchecked, some children are checked => a symbol representing that (e.g. Microsoft's "square inside the checkbox").

Clicking on checked => unchecked, and unchecks all descendents.
Clicking on unchecked => checked, and checks all descendents.
Clicking on some-checked => checked, and checks all descendents. (I think - one could argue in favor of "=> unchecked")

The initial state should be based on the children. E.g., if they are all checked, then the group checkbox should also be checked. So that the next click on it performs "uncheck all".

A feature like this exists in https://github.com/ismyrnow/leaflet-groupedlayercontrol - options [ groupCheckboxes: true ] - but that control lacks the ability to collapse a tree branch. The option adds an input checkbox, with a click event, to every non-leaf node. It doesn't support the tri-state logic I describe above; just checked/unchecked (no "some-checked" display state). That's good enough - though it is ambiguous when you collapse a node which has some children checked: user doesn't know exactly what will happen when they click on checkbox of a collapsed node.

I would use this control, if it had this feature. I'd add the feature myself, but I don't know enough yet about leaflet internals, nor manipulating the DOM, to fully grasp the coding needed.


I see that the group node does have a checkbox, if it has a layer attached to it.
So I am wanting a different option, where group node has a checkbox, but no layer, that behaves as described above.


As a hack, I tried adding all the children to a LayerGroup, and making that LayerGroup the layer that is attached to the group node. This partially works:

Now I just need to figure out what edits would keep the children checked states in sync with the group node...

astridx commented 5 years ago

I would also like this option

jjimenezshaw commented 5 years ago

Thanks @MappingSteve for you suggestion. As you are realizing, it has not a simple solution. I have been thinking about that, and:

I am thinking on adding a callback that lets you manage it and easily change your state (checkbox of your choice) and activate or deactivate layers. It is not going to be just a boolean in the options... you will have to code a bit (don't worry, I'll add an example) I will link "soon" a PR here.

PS: GitHub does not notify me when you edit your comment.

astridx commented 5 years ago

Please check if my solution is ok.: https://github.com/jjimenezshaw/Leaflet.Control.Layers.Tree/pull/13

jjimenezshaw commented 5 years ago

Thanks @astridx . Unfortunately your PR #13 was too slow in the example you added (it does recreate the full tree for every single node). I looked for a faster solution in this PR: #14 It also lets you add it on any node(s) you want, and use the HTML you prefer. Still needs documentation and tests. You can start having a look to the tests.

jjimenezshaw commented 4 years ago

@MappingSteve @astridx I founded a better solution. Now you just have to add the option selectAllCheckbox: true to the nodes where you want that feature (probably on all with children). Look at the examples. I have already merged #14 into master. I will make a release soon.

astridx commented 4 years ago

Thank you very much @jjimenezshaw