For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!
Interested in getting your voice heard by members of the Developer Marketing team at Oracle? Check out this post for AppDev or this post for AI focus group information.
I started from checkbox tree mentioned here: Add Checkbox Selection to APEX Tree Region – HardLikeSoftware . Note you can download test app.
I changed Javascript code for Checkbox tree page (Execute on page Load). You can check result here: https://apex.oracle.com/pls/apex/f?p=104351:2
Maybe it's not exactly what you need but it's simmilar.
The latest version of treeView widget API is used. I guess you need APEX 18.1. for this code to work. API doc: https://docs.oracle.com/database/apex-18.1/AEXJS/treeView.html
Changed Code:
var tree$ = $("#mytree"), // change this to use whatever id you give the tree nodeAdapter = tree$.treeView("getNodeAdapter");
// Set a custom node renderer that adds a checkbox icon spannodeAdapter.renderNodeContent = function( node, out, options, state ) { out.markup("<span class='treeSelCheck'></span>"); // this is the checkbox - its not a real checkbox input // the rest of this code is essentially a copy of what is in widget.treeView.js function renderTreeNodeContent if ( this.getIcon ) { icon = this.getIcon( node ); if ( icon !== null ) { out.markup( "<span" ).attr( "class", options.iconType + " " + icon ).markup( "></span>" ); } } link = options.useLinks && this.getLink && this.getLink( node ); if ( link ) { elementName = "a"; } else { elementName = "span"; } out.markup( "<" + elementName + " tabIndex='-1' role='treeitem'" ).attr( "class",options.labelClass ) .optionalAttr( "href", link ) .attr( "aria-level", state.level ) .attr( "aria-selected", state.selected ? "true" : "false" ) .optionalAttr( "aria-disabled", state.disabled ? "true" : null ) .optionalAttr( "aria-expanded", state.hasChildren === false ? null : state.expanded ? "true" : "false" ) .markup( ">" ) .content( this.getLabel( node ) ) .markup( "</" + elementName + ">" ); //window.alert('nodeAdapter.renderNodeContent '+ this.getLabel( node ) +' '+ node.id);};
tree$.treeView("option","multiple", true) // make the tree support multiple selection .treeView("refresh") // refresh so that all the nodes are redrawn with custom renderer .on("click", ".treeSelCheck", function(event) { // make that "checkbox" span control the selection var nodeContent$ = $(event.target).closest(".a-TreeView-content"), isSelected = nodeContent$.hasClass("is-selected"), selection$ = tree$.treeView("getSelectedNodes"), node$ = tree$.treeView("getNodes", nodeContent$)[0]; function remove(arr, item) { var index = arr.indexOf(item); if (index > -1) { arr.splice(index, 1); } };
if ( isSelected ) { remove(selection$,node$); //naredi za vse otroke for (i = 0; node$.children && i < node$.children.length; i++) { remove(selection$, node$.children[i]); } } else { selection$.push(node$); //naredi za vse otroke for (i = 0; node$.children && i < node$.children.length; i++) { selection$.push(node$.children[i]) } } tree$.treeView("setSelectedNodes", selection$); $s("P2_SELECTED_NODES", selection$.map(function(n) {return n.id;}).join(":")); //window.alert('setSelectedNodes - onClick'); return false; // stop propagation and prevent default });
tree$.treeView("option", "selectionChange", function(e){ var nodes = $("#mytree").treeView("getSelection"); //$s("P2_SELECTED_NODES", nodes.map(function(n) {return n.id;}).join(":")); tree$.treeView("setSelectedNodes", $v("P2_SELECTED_NODES").split(":").map(function(i) { //window.alert('setSelectedNodes - selectionChange'); return { id: i }; })); //tree$.treeView("collapse", nodes); ////window.alert('selectionChange');});
// setSelectedNodes only works if the node has been rendered so do expand all// this is not ideal but much simpler than having to check each node and expand parents as neeeded, remove if not neededtree$.treeView("expandAll");tree$.treeView("setSelectedNodes", $v("P2_SELECTED_NODES").split(":").map(function(i) { //window.alert('setSelectedNodes'); return { id: i }; }));//window.alert('setSelectedNodes construktor');
Thanks you, MiroMas.
I will do what you have suggested even if my need is the opposite of what I should get with your script (I need to select a leaf and have automatically selected his ancestors).
Ciao
Cinzia
I have exactly the same question, how can you select all ancestors if you select a parent node?
I'm not JS or JQuery expert but you need to replace code:
if ( isSelected ) { remove(selection$,node$); //this is for each children, replace with while loop for (i = 0; node$.children && i < node$.children.length; i++) { remove(selection$, node$.children[i]); } } else { selection$.push(node$); //this is for each children, replace with while loop for (i = 0; node$.children && i < node$.children.length; i++) { selection$.push(node$.children[i]) }
WITH:
if ( isSelected ) { remove(selection$,node$); while node$.parent{ node$ = $node.parent; remove(selection$, node$); }} else { selection$.push(node$); while node$.parent{ node$ = $node.parent; selection$.push(node$);}
Something like that
HTH
Miro
Thanks you, Miro,
I have exactly the same question.
A few weeks ago I opened a threed about the same problem (Apex 18.1 tree with Checkboxes - select all ancestor ), but I had no answer .. I did some tests using your script and your suggestions but, at the moment, I could not get what I wanted. (selecting a tree leaf to have all his ancestors selected).
Also I am not an expert in JS and JQuery, but trying your code I verified that:
Looking at the treeView Widget documentation it seems that the node property is "_parent" and not parent.
Changing this property into your code ..
......
if ( isSelected ) {
remove(selection$,node$);
while (node$._parent) {
node$ = $node.\_parent; remove(selection$, node$);
}
else {
selection$.push(node$);
while (node$._parent){
node$ = $node.\_parent; selection$.push(node$);
.......
now seems that the parent node object exists, but the statement:
node$ = $node._parent
is not correct and after this assignement i get the following error in the console
ReferenceError: $node is not defined
We hope that some expert can help us
in any case, many thanks for your suggestions
saverio
I'm not JS or JQuery expert but it was just typewriting error ($node instead of node$). Correct code is:
node$ = node$._parent;
remove(selection$, node$);
Hope it works like expected: https://apex.oracle.com/pls/apex/f?p=104351:2
Thank you so much Miro now it works!Even I did not notice the trivial typewriting error Thanks againSaverio
Thanks for your help. Now it works.