This site is currently read-only as we are migrating to Oracle Forums for an improved community experience. You will not be able to initiate activity until January 31st, when you will be able to use this site as normal.

    Forum Stats

  • 3,890,899 Users
  • 2,269,649 Discussions
  • 7,916,821 Comments

Discussions

Looking for Tree Widget API samples (Apex 19.2)

John like many others
John like many others Member Posts: 116 Blue Ribbon
edited Oct 21, 2020 2:31PM in APEX Discussions

Hello

Before I put my questions I would like to make something clear to others not to pull out some hairs or wasting hours to find the cause:.

If you use a generated Apex tree (widget) and you want to access it by API you will get some confusing error messages and there is no help in the API itself telling you why. The way to access a generated tree is :

  1. On Tree region level add an ID in 'Static ID' (f.e.: HIERARCHYTREE)
  2. Access the Tree widget in Javascript by $('HIERARCHYTREE_tree')

The API documentation (I'm not allowed to link it here) is even misleading using the class identificator (dot notation) in the samples. So don't get confused about that.

Questions:

  • I would like to add and delete nodes in the generated tree. The API documentation does not provide ANY samples how to add or delete a node. I even searched here (spyglass on top) for "tree" but no result. So if you know any source on the Internet or a book providing examples I would be thankful..
  • I would like to react in the background if the user clicks on any treeview entry (node, child). The API doesn't support simple click events. How can I (simply) add a one-click event on any entry of the tree?
  • To add a node I guess I have to use the "addNode" option described in the API. It's already unclear how to get to those parameter: addNode(pParent, pIndex, pLabelopt, pContextopt, pCallback) -> f.e. HOW can I get the PARENT node into which I would like to add a child? There is function to get children but no function to get the parent of f.e. the selectedNode. pIndex: Why the heck do I have first to evaluate the amount of children of the node I would like to add another node(child) in order to get the amount of children and therefore add it at the end? As I'm using the default generated tree how can I pass the ID provided by that defaultNode?

I think with some simple code samples the questions of topic 3 will resolve themselves. So if you know any source where to find simple examples to add and/or delete nodes by API be would great.

Tagged:

Answers

  • John Snyders-Oracle
    John Snyders-Oracle Member Posts: 1,437 Employee

    Hi,

    What version of APEX? In later versions you reference the tree widget by giving the region a static id such as projects. Then:

    apex.region("projects").call("sometreemethodname"...)
    or
    apex.region("projects").widget()...
    

    It is true there are not a lot of examples. The Tree region is very simple mostly for viewing a tree and either selection or navigation. It is not intended to be editable. So using advanced features of the treeView widget from the Tree region is not easy.

    Adding and deleting nodes is possible but not easy and I don't have any handy examples. These kinds of questions have come up on this form before.

    Single clicking on nodes will change the selection. If you want to do something when the selection changes use the selectionChange event. Check out the activateNode event.

    I have blogged about the Tree region and/or treeView a few times

    This is about the treeView widget as used by the side navigation.

    The app you can download from this blog has some advanced examples using the Tree region but nothing as advanced as you are trying to do.

    The other info on my blog about the tree is a little out of date. For example the one about adding checkbox selection to the tree is out dated because now checkbox selection is built in to the widget.

    Regards,

    -John

  • John like many others
    John like many others Member Posts: 116 Blue Ribbon
    edited Oct 26, 2020 3:28PM

    Hi John

    Thank you for your answer. I'm relating to Apex 19.2...

    I tried your samples all with no luck (tree region has static ID: HIERARCHYTREE):

    apex.region("HIERARCHYTREE").call("refresh");

    --> widget.treeView.min.js?v=19.2.0.00.18:2 Uncaught TypeError: Cannot read property 'type' of undefined


    apex.region("HIERARCHYTREE").widget.refresh();

    --> widget.treeView.min.js?v=19.2.0.00.18:2 Uncaught TypeError: Cannot read property 'type' of undefined


    apex.region("HIERARCHYTREE").widget("refresh");

    --> widget.treeView.min.js?v=19.2.0.00.18:2 Uncaught TypeError: Cannot read property 'type' of undefined

    The only way I currently can access the tree is that way:

    var tree$ = $( "#HIERARCHYTREE_tree" ); // _tree seems to be the default the tree widget sets that

    tree$.treeView( "refresh" );

    With the sample from Stefan in the other forum entry I was able to add an entry by using addNode. I can't make it working to simple delete a node entry:

    var tree$ = $( "#HIERARCHYTREE_tree" );

    var selection = tree$.treeView( "getSelection" ); 

    tree$.treeView( "deleteNodes", selection );

    tree$.treeView( "refresh" );

    --> nothing happens (node(s) keep existing after refresh)


    I'm aware that the hierarchy widget is not able to sync with DB and therefore mainly for visual representation. So my idea is:

    Left side of mask: current view of treeview

    Right side of mask: Options (buttons/textfields) for the user to add a node/leaf or delete an existing one, etc.

    If the user wants to add an entry I will add that node with the addNode function and in the background I create an entry in the DB. So whenever the user reloads the page the view will represent the current state. Sure, it would be easier (to me) I create the related DB entry and reload the page (in order to see the updated tree). But then the user must re-open the whole tree to go on working the tree structure he just added one entry.

    I'm aware I have to call the refresh function to make the manually added node(s) visible. Sadly the refresh does also close the treeview which is not so nice from user perspective. So I have to find out now how to reopen the tree where the user has added the new node. Can't make the expand function to work yet. I assume that calling the refresh function destroys any pre-selection.

    All over not really demanding as I should be able to cover that with the existing function set.

    As I anyway have to react on users selection the selectionChange event is very handy, thanks, tested, works!

    Thanks for the other links. Going quickly through them I couldn't see anything that would be help right away but will read it more closely later on.

  • John Snyders-Oracle
    John Snyders-Oracle Member Posts: 1,437 Employee

    apex.region should work with trees in 19.2 release. I don't know why you are getting those errors.

    When reporting JavaScript errors from the console you should first put the page in debug mode and run it from the builder so that un-minified files are used. This way we can identify the actual source lines where the errors are raised. Also provide the full stack trace.

    If you look at SQL Workshop -> RESTful Services you will see that we have a tree region where things can be added and removed. Even with all our internal knowledge of how the treeView widget works we choose not to use JavaScript to add/remove/edit nodes. We wanted to stick closer to what is declarative for our own ease of future maintenance. We refresh the whole page. The one thing we do customize is that the current expanded nodes are remembered. This is reasonably easy to do and there are examples.

    Regards,

    -John

  • John like many others
    John like many others Member Posts: 116 Blue Ribbon
    edited Oct 27, 2020 10:55AM

    Remembering state tree would be awesome and solve me many hair pulling hours. How can I activate that option?

    Using the refresh function of the tree widget or reloading the page by location.reload(); does always show me the tree collapsed after.

    The problem is that adding a node (the official) way forces you to do a refresh in order to display it and that collapses the whole tree.

    Tnx, I'll try to find the demo you mentioned.

  • John Snyders-Oracle
    John Snyders-Oracle Member Posts: 1,437 Employee

    Here is how to save and restore the expansion state.

    1) Add the following to the tree region advanced JavaScript Initialization code attribute:

    function(options) {
        options.makeNodeAdapter = function(data, types, hasIdentity) {
            var a,
                // get the ids from session storage
                ids = apex.storage.getScopedSessionStorage( { usePageId: true, useAppId: true} ).getItem("treeExpansionState");
            if ( ids ) {
                ids = ids.split(":");
            }
            a = $.apex.treeView.makeDefaultNodeAdapter( data, types, hasIdentity, ids );
            return a;
        }
        return options;
    }
    

    2) Add a DA on Page Unload event called something like: save expansion state on page unload

    It should have one JavaScript action with this code:

    var ids = apex.region("empTree").call("getExpandedNodeIds").join(":");
    apex.storage.getScopedSessionStorage({usePageId: true, useAppId: true}).setItem("treeExpansionState", ids);
    

    Change empTree to your tree static id.

    That is all. Step 2 saves the expansion state when the page unloads. Step 1 restores the expansion state when the tree is initialized.

    The tree must have the PK set as the Node Column Value. The above was tested on versions 20.1 and 20.2. I used a tree on the EMP table and the EMPNO column is the node column value.

    Regards,

    -John