Select all children but not the parent?

4,343 views
Skip to first unread message

Roger Martin

unread,
May 28, 2014, 12:42:16 PM5/28/14
to jst...@googlegroups.com
We use jsTree in several places in Gallery Server Pro. In some cases we want all the children to be selectable, but not the parent, as seen here:


As best I can tell, there isn't a configuration option to allow this, so I hacked the source code to make it possible. But I wanted to double check and verify this can't be done via configuration.

Thanks,
Roger Martin
Gallery Server Pro

Ivan Bozhanov

unread,
May 29, 2014, 2:16:48 AM5/29/14
to jst...@googlegroups.com
Hi,

If you have activated the checkbox three_state option it will always update the parent as the children change - no way to disable that.
1) Maybe you do not need three-state - you can use checkboxes without three state and manually update parents when needed?
2) Apart from that - you can try disabling the parents, but that will still change their state, but they won't be "clickable" by the user, not sure if that will solve the problem.
3) Just a tip - if you need to modify you can either build your own checkbox plugin or abstract the changes to a mini plugin - that way you can update whenever a new version comes out

Best regards,
Ivan

Ivan Bozhanov

unread,
May 29, 2014, 2:17:29 AM5/29/14
to jst...@googlegroups.com
Oh, and you can also remove the checkbox by using pure CSS (if that needs to be removed).

Roger Martin

unread,
May 29, 2014, 11:03:26 AM5/29/14
to jst...@googlegroups.com
In this example I am setting three_state=true because I like the the behavior where children are auto-selected when the parent node is clicked.

I suppose I could write a custom plug-in. However, since this plug-in would be mostly copied code from the current checkbox plug-in, I am still left in the position of trying to merge code changes during upgrades (for example, to pick up any bug fixes you applied to the checkbox plug-in).

My wish would be for the checkbox plug-in to replace the three_state property with a new one named cascade_behavior, having one of these values: none, down, up, both

three_state=false maps to none. three_state=true maps to both. In my example in this thread I would set it to 'down' so that clicks cascade down but not up.

My two cents... Thanks for a fantastic product.

Roger




--
You received this message because you are subscribed to the Google Groups "jsTree" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jstree+un...@googlegroups.com.
To post to this group, send email to jst...@googlegroups.com.
Visit this group at http://groups.google.com/group/jstree.
For more options, visit https://groups.google.com/d/optout.

Ivan Bozhanov

unread,
May 29, 2014, 12:03:37 PM5/29/14
to jst...@googlegroups.com
I have had this feature request before, but then the discussion got stuck on "what happens when" so maybe you can give some insight.
So "none" and "both" are pretty much clear.

As for "down":
1) If a parent node is selected its children are selected - that is fine
2) If a parent is unchecked its children are deselected - right?
3) Now we get in the indeterminate states - what happens when for example a parent is checked (resulting in children (more than one) being checked), and then a single child is unchecked - does the parent get an indeterminate state?
4) In the above scenario - what happens if we uncheck all the children a parent has - does it uncheck?

The same questions can be adapted to the "up" scenario. I guess the root of the problem is realizing all possible states and ways to get there. I have had feature requests to skip the indeterminate state but keep the cascading - so if a parent has one child unchecked, it will be unchecked, if all are checked - it will get checked - so this is "both" in your case, but without the indeterminate state.
So basically we have as you specified - two axes - cascade up and cascade down and an optional indeterminate state, the question is how to make those configurable, without over complicating the configuration. We must also take into account that not all changes in selection come from user interaction ... so if a node is lazy-loaded and its children are all checked if the cascade up option is set we should check that node too.

Do you have more ideas or should I just try to implement this and see where we end up?

Best regards,
Ivan
To unsubscribe from this group and stop receiving emails from it, send an email to jstree+unsubscribe@googlegroups.com.

Roger Martin

unread,
May 29, 2014, 1:17:13 PM5/29/14
to jst...@googlegroups.com
I agree with your assessment and the devil is in the details to be sure. Before I discuss the indeterminate state, I should verify I understand its meaning, so can you confirm:

* A node is indeterminate only if at least one child is selected or at most n-1 are selected, where n is the number of child nodes. That is, if all children are selected (or none), the parent is never indeterminate.



To unsubscribe from this group and stop receiving emails from it, send an email to jstree+un...@googlegroups.com.

Ivan Bozhanov

unread,
May 30, 2014, 2:12:01 AM5/30/14
to jst...@googlegroups.com
Yes, exactly.

Roger Martin

unread,
May 30, 2014, 3:55:05 PM5/30/14
to jst...@googlegroups.com
OK, I spent about an hour thinking this through. The desire is this: Keep the cascading behavior but don't auto-select the parent node when all the children are selected.

Two ways to get there:

1. Add an option that keeps the parent node in an indeterminate or unchecked state even when all children are selected. Not sure what to call it or where to put it but could be simpler and easier to implement than #2.

2. Replace three_state option with cascade_behavior option that can have one of these values: none, both, up, down. The 'none' setting is the same as three_state=false; 'both' is same as three_state = true.

I've spent quite a bit of time thinking through scenarios for 'up' and 'down' and am finding it difficult to get the desired behavior while preserving the ability for parents to shown an indeterminate state where necessary.

I've come to the conclusion I don't support this #2 approach unless it does away with indeterminate states altogether for 'down' and 'up', but it would be bad API design to do this since you need to keep the current behavior for the 'both' setting, which has indeterminate states.

PROPOSAL: What do you think about pursuing the #1 option?

Cheers,
Roger

Appendix: Below is the scenario matrix I was working on for the #2 option. Not sure how readable it is, but I'm including it in case you want to keep thinking about this option.

Scenario             setting    node behavior  child node behavior    parent node behavior
--------------------------------------------------------------------------------------------------------------------------
Node is checked  'down'       checked         All children checked    Nothing
Node is checked  'up'           checked              Nothing            Indeterminate or checked*

Node is unchecked 'down'   unchecked All children unchecked Indeterminate or unchecked*
Node is unchecked 'up'        unchecked           Nothing            Indeterminate or unchecked*

* The node will be indeterminate if at least one but not all children are selected. If all children are checked the parent node will be checked; if none are checked the parent node will be unchecked.


To unsubscribe from this group and stop receiving emails from it, send an email to jstree+un...@googlegroups.com.

Daniel Young

unread,
May 30, 2014, 4:43:54 PM5/30/14
to jst...@googlegroups.com
Hi,

I think the behaviour is similar to what I want to, below is an image to show what I would like. It also means not checking the parent when all children are checked but also if the parent was selected then unselecting children doesnt uncheck the parent.



Thanks

Dan
To unsubscribe from this group and stop receiving emails from it, send an email to jstree+un...@googlegroups.com.
To post to this group, send email to jst...@googlegroups.com.
Visit this group at http://groups.google.com/group/jstree.
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "jsTree" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jstree+un...@googlegroups.com.
To post to this group, send email to jst...@googlegroups.com.
Visit this group at http://groups.google.com/group/jstree.
For more options, visit https://groups.google.com/d/optout.

Daniel Young

unread,
May 30, 2014, 4:45:33 PM5/30/14
to jst...@googlegroups.com
Typo: "parent was checked then unchecking children doesnt uncheck the parent."

Dan

Roger Martin

unread,
May 30, 2014, 4:58:47 PM5/30/14
to jst...@googlegroups.com
Daniel - Your screenshots show some nodes with an indeterminate status. Is that what you want or would you prefer they be unchecked? In my case my preference is to turn off the indeterminate status but it's not a must-have.

Ivan Bozhanov

unread,
May 31, 2014, 2:36:53 AM5/31/14
to jst...@googlegroups.com
Thank you for the proposal, I will give it some thought. I will definitely do something in this direction, but I will see if we can keep the current settings, and add those on top without too much confusion (the idea is not to change the current settings and not to break backwards compatibility). I have not thought it through yet, but I just wanted to let you know I am reading and to thank you for giving such a detailed strategy.
I will probably have time to go over this tonight and let you know asap, so that we can continue the discussion (or if we are all OK - I can move on to implementing this).

Best regards,
Ivan
To unsubscribe from this group and stop receiving emails from it, send an email to jstree+unsubscribe@googlegroups.com.

Roger Martin

unread,
Jun 2, 2014, 10:35:34 AM6/2/14
to jst...@googlegroups.com
Thanks, Ivan. As long as I can reach my goal (keep the cascading behavior but don't auto-select the parent node when all the children are selected), I am happy to defer to your judgment as to the best way to implement it.

Cheers,
Roger

Ivan Bozhanov

unread,
Jun 4, 2014, 4:04:17 AM6/4/14
to jst...@googlegroups.com
Please have a look at the latest commit. I added the checkbox.cascade option.
Keep in mind if three_state is set to true, this option is ignored (three_state : true automatically sets cascade to 'up+down+undetermined')
cascade should be a string, if it contains "up" selection will cascade up, if it contains "down" selection will cascade down, if it contains "undetermined" there will be "square" checkbox icons for partial selection.
The cascade option defaults to an empty string, so basically backwards compatibility is not broken (if you do not mess with the cascade option and only use three_state everything will be as before).

I guess in your case you should use:
                    checkbox : {
                        three_state : false,
                        cascade : 'down'
                    },

I guess some options do not make much sense (like "down+undetermined"), I could limit "undetermined" only if "up" is set, but I have not given that much thought yet.

Tell me what you think.

Best regards,
Ivan

Roger Martin

unread,
Jun 6, 2014, 4:25:21 PM6/6/14
to jst...@googlegroups.com
In my brief testing it works beautifully. Nicely done!

And thank you.

To everyone else: If you use jsTree and are able to financially support Ivan, please do so. We all benefit when Ivan can focus on jsTree instead of having to work a "real" job. Open source only works when the folks doing it can keep their bills paid. We've sent him $100 as our small contribution. 

Roger

Derek Simkowiak

unread,
Feb 26, 2017, 6:05:53 PM2/26/17
to jsTree
Hi! I came across this (old) thread in a Google Search. I hope it's okay to re-open the discussion. 

> The desire is this: Keep the cascading behavior but don't auto-select the parent node when all the children are selected.

This is still my desire, as well. I am trying to get this behavior with the latest version 3.3.3.  I am using:

 'checkbox' : {
   
'three_state' : true,
 
},

Everything works as desired, except that selecting all siblings in a tree auto-selects their parent node.

I am using this in a filemanager application. Two use-case examples:

1. I want the user to be able to select and move all files in /Temp/, without also being forced to move the (parent) /Temp/ directory itself.
2. Given a tree like this:

/SomeDir/
   
+-- File1
   
+-- File2
   
+-- Child1/
        +-- File3
        +-- File4

I want the user to be able to select and all the files (File1,File2,File3,File4) without being forced to also select the directories SomeDir/ and Child1/

But I want this without losing other behaviors that "cascade up". Deselecting any child node, no matter how deep, should still de-select all it's ancestors up to the root (the way it does now). "If any of my descendants are unselected, then I am unselected."

Currently, if the user has a selected hierarchy, then user can click a descendant node (deselecting its ancestors), and then just click that node again, and get back to where they started (because that 2nd click will cascade up and re-select all parents). I want to specifically break this two-click symmetry. If my user deselects any child (or deeper-level) descendant, the user will need to manually re-select each of node's ancestors up to the topmost node -- or, more easily, just re-select the topmost node again (thus selecting all descendants again). This allows the user to easily say, "Give me all this stuff, except for these one or two exceptions" -- and also not be forced into selecting the parents.

I am going to dig into the code now, to examine the checkbox plugin and maybe write a new plugin that works the way I want.

But if there is more general interest, I could also code this as a new option to the existing plugin and submit a Pull Request. Maybe something like forceParentSelect: false.


Thanks,
Derek Simkowiak

Derek Simkowiak

unread,
Feb 26, 2017, 6:33:23 PM2/26/17
to jsTree
It did not take long to find. I found the section of code to modify and got it to work.

I played with it for a while, and I think the way it acts now (described in my post below) is very intuitive. I propose making this a new config option, and maybe even making this the default behavior. Then users who depend on the parent auto-select can re-enable it on their next upgrade by adding a single config option.

The code was near line 5072, in a block labelled "apply up" for the event  'select_node.jstree' and 'check_node.jstree'. Just commenting it out worked for me:

/* I propose making this configurable with an option, so parent selection is not forced:

        // apply up
        if(s.indexOf('up') !== -1) {
            while(par && par.id !== $.jstree.root) {
                c = 0;
                for(i = 0, j = par.children.length; i < j; i++) {
                    c += m[par.children[i]].state[ t ? 'selected' : 'checked' ];
                }
                if(c === j) {
                    par.state[ t ? 'selected' : 'checked' ] = true;
                    sel[par.id] = true;
                    //this._data[ t ? 'core' : 'checkbox' ].selected.push(par.id);
                    tmp = this.get_node(par, true);
                    if(tmp && tmp.length) {
                        tmp.attr('aria-selected', true).children('.jstree-anchor').addClass(t ? 'jstree-clicked' : 'jstree-checked');
                    }
                }
                else {
                    break;
                }
                par = this.get_node(par.parent);
            }
        }
*/


Derek Simkowiak

unread,
Feb 26, 2017, 7:22:39 PM2/26/17
to jsTree
One more minor issue came up with the checkbox plugin: I am using it with 

'checkbox' : {
 
'visible' : false,
}

This gives me the nice cascading behavior (with my edit, below) but without showing the checkboxes.

Unfortunately, this forces click-to-multiple-select, instead of the default CTRL-key or SHIFT-key to multi-select. (The GUI in my application prefers single-select, because it previews the file for the user.)

I was able to make the plugin act like the default behavior by commenting out a line near line 5475:

 if(this.settings.checkbox.tie_selection && (this.settings.checkbox.whole_node || $(e.target).hasClass('jstree-checkbox'))) {
   
// dereks
   
//e.ctrlKey = true;
 
}


I think it would be great if that was also a configuration option for the plugin. (Just because I want cascading behavior does not mean I want click-to-multiple-select.)

Thanks!
Reply all
Reply to author
Forward
0 new messages