returning hyperlinks in the json for a jstree

816 views
Skip to first unread message

Cathryn Crane

unread,
Jan 23, 2015, 1:12:32 PM1/23/15
to jst...@googlegroups.com
I have a jstree that calls a webservice which returns a json string.  How do I add a value to each node, not just the text of the node and make that a clickable hyperlink?

Here's my code:

on the page:
<div id="jstree_demo_div"></div>



<script type="text/javascript">

 $
("#jstree_demo_div").on("select_node.jstree",
         
function (evt, data) {
             
var t = data.node.text;
         
}
       
);
 
});

$
(function () {
        $
(".textbox").click(function (e) {

           
var thisID = $(e.target).attr("ID");

           
var csID = thisID.substr(thisID.lastIndexOf("_") + 1);
            $
('#posDetailDiv').hide();

           
var line = $('#dlLine').val();

            showtree1
(csID, line);
         
});
   
});

   
function showtree1(thisID, line) {

        $
('#jstree_demo_div').jstree({
           
"core": {

               
"data": //data - jquery
                 
{
                      type
: "POST"
                     
, dataType: "json"
                     
, contentType: "application/json; charset=utf-8"

                     
, url: "DummyPage.aspx/populateTree"

                     
, data: JSON.stringify({ imgID: thisID, line: line })

                     
, success: function (node) {
                         
var ReturnString = node.d;
                          alert
(ReturnString);
                         
return { "id": node.id };
                     
}///success


                     
, error: function (msg) {

                          alert
("Error: " + msg.responseText);

                     
}///error
                 
}//data
           
}///core
   
,
           
"plugins": ["themes", "json_data", "search", "contextmenu", "types"]
       
});
   
}
</script>



the populateTree webmethod returns a string:

[
     
{ \"id\":1,\"text\":\"Customer Projects\",\"children\":
    [
        {\"id\":2,\"text\":\"Doors\"},
        {\"id\":3,\"text\":\"Lighting\"},
        {\"id\":4,\"text\":\"Carpet\"},
        {\"id\":5,\"text\":\"Electrical\"}
    ]}
]



How do I format the json to include a value for each node and the value being a hyperlink that opens in a new window?

Thanks!

"[from 


]

]},


Ivan Bozhanov

unread,
Jan 24, 2015, 5:19:45 AM1/24/15
to jst...@googlegroups.com
Read the docs on the JSON format expected by jstree - either on github (main repo page - which also has examples on jsfiddle) or on jstree.com
What you need is the a_attr object:
"id:"1", "text" : "...", "a_attr" : { "href" : "..." }

As for making it clickable - react to the changed event and redirect the user (or do anything else with the address - load it in an IFRAME, or get the content and add it to a DIV, it all depends on your code - but the changed event (or select_node event) is what you need).

Here is a similar topic (in case you want to reselect the node when navigation is complete): https://groups.google.com/forum/#!topic/jstree/Jk72DjaatSc

Best regards,
Ivan
...

cathry...@gmail.com

unread,
Jan 26, 2015, 2:30:38 PM1/26/15
to jst...@googlegroups.com
Thank you Ivan.
 
I finally got it working :-)
 
Now I'm trying to figure out how to hit the webservice more than once when the user clicks on a different text box.
 
It works great the first time but if I click on a different text box, it goes to the the json call but doesn't actually hit the webservice so it shows the same jstree each time.
 
Any ideas?  Do I need to reset something in order for the script to know it needs to refresh the result for the tree?

Thanks!
 
Cathryn

--
You received this message because you are subscribed to a topic in the Google Groups "jsTree" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/jstree/BbBe5Zwb7Yo/unsubscribe.
To unsubscribe from this group and all its topics, 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,
Jan 27, 2015, 2:44:34 AM1/27/15
to jst...@googlegroups.com
I will need a bit more context, do you mean you are using lazy loading and when opening a child you get the same root nodes you already have? If so - once again read the docs and take a look at the demos. The AJAX config inside core.data can have "data" and "url" as functions, so you can fetch each child from a different URL:
core : {
  data : {
    url : function (node) {
      return "/some/path/" + (node.id === "#" ? 0 : node.id);
    }

This config will first hit /some/path/0 for root nodes, if a root node has the ID of 1, when it is opened jstree will fetch the data from: /some/path/1, etc.

You can also only modify the data sent with the request like so:
core : {
  data : {
    url : "/some/path/",
    data : function (node) {
      return { id :  (node.id === "#" ? 0 : node.id) };
    }

This config will first hit /some/path/?id=0 for root nodes, if a root node has the ID of 1, when it is opened jstree will fetch the data from: /some/path/?id=1, etc. (you can of course use post too)

Best regards,
Ivan
To unsubscribe from this group and all its topics, send an email to jstree+unsubscribe@googlegroups.com.

cathry...@gmail.com

unread,
Jan 27, 2015, 12:50:42 PM1/27/15
to jst...@googlegroups.com
Thanks Ivan,
 
No, this is different than the lazy loading.  Lazy loading won't work for us b/c of the fact that our browser is too old and due to company policy we can't upgrade it b/c we have some apps that need to upgrade first.  Trust me, it's painful as a developer;-)
 
I load the tree all at once.  But they can click on different objects on the page and a different tree needs to load.  So the same webmethod needs to get called, just with a different value being passed.  It seems like because I've already populated the tree once, it thinks it doesn't have to hit the webmethod again even thought he values being passed is different.
 
I've looked through the documentation and I'll do it again since I'm getting more understanding but some of it is abstract to me so I'm struggling.  Hopefully, I'm making sense with the issue I'm having.

Thanks again for your help

Cat
 

$(

'#jstree_demo_div').jstree({

"core": {

"data": //data - jquery

{

type:

"POST"

, dataType:

"json"

, contentType:

"application/json; charset=utf-8"

, url:

"FlowCycleReport.aspx/populateTree"

, data: JSON.stringify({ imgID: thisID, line: line })

//, "data": function (node) {

// //return "{'id':'" + $(node).attr("id") + "'}";

// return node.d;

//}

, success:

function (node) {

var ReturnString = node.d;

// alert(ReturnString);

return { "id": node.id };

}

///success

 

, error:

function (msg) {

alert(

"Error: " + msg.responseText);

}

///error

}

//data

}

///core

,

"plugins": ["themes", "json_data", "search", "contextmenu", "types"]

});


To unsubscribe from this group and all its topics, send an email to jstree+un...@googlegroups.com.

cathry...@gmail.com

unread,
Jan 27, 2015, 4:00:21 PM1/27/15
to jst...@googlegroups.com
Hi Ivan --
 
I wanted to send an update:
 
I've actually got the refresh piece working with $('#jstree_demo_div').jstree("refresh"); so that's aweome.  But now, when it's hitting my webmethod the 2nd time, although the params from the jquery are correct, the webmethod still has the 1st params that were passed.  Am I missing anything? 
From the jquery it will be: 

, data: JSON.stringify({ imgID: 541, line: 278 })

but the webmethod will have the very 1st value when it was called. imgID will equal 527 or something other than what is passed.

[

WebMethod]

public static string populateTree(string imgID, string line)

{

DAL_Flow DL = new DAL_Flow();

string nodevalues = DL.JsonNav(imgID, line);

return nodevalues;

}


Ivan Bozhanov

unread,
Jan 27, 2015, 6:03:46 PM1/27/15
to jst...@googlegroups.com
data: JSON.stringify({ imgID: thisID, line: line })

This line of code means - stringify the above and set it as the data property - it will not be reevaluated ... ever. It is not a jstree thing, it is a JS thing :)

Try this:
data : function () { return
JSON.stringify({ imgID: thisID, line: line }); }

That way, when thisID or line change, and you call .refresh(), the new values will be passed to the server.

Best regards,
Ivan

cathry...@gmail.com

unread,
Jan 28, 2015, 2:21:04 AM1/28/15
to jst...@googlegroups.com
Hi Ivan

I thought that was going to totally be it:-(.  So, I know I must be missing one little thing. 
The on click event has the correct values.  When I step through in firebug, the values follow to the function call.  Then, when the refresh happens and it hits the call to the webmethod, it has the 1st value that was clicked again....

I know I've posted it before but wanted to make sure you have the latest to look at since I've been playing with it.

click method of the textbox.  These textboxes are created when the page loads to each has it's own ID.  This ID is what is passed as a value.


    $(function () {
        $(".textbox").click(function (e) {
        
            var thisID = $(this).attr("ID");


            var csID = thisID.substr(thisID.lastIndexOf("_") + 1);
            $('#posDetailDiv').hide();
           
           
            var line = $('#dlLine').val();
          
            // Reset the header:
            $('#PartHeaderDiv').empty();
            $('#PartHeaderDiv').append('Line Number: ' + line + ': Control Station ' + csID);
           
            showtree1(csID, line);

            $('#jstree_demo_div').jstree("refresh");

            $('#posDetailDiv').show();
        });
    });

The jstree call:

I've tried adding async: true and cache: false when trying different things.

    function showtree1(thisID, line) {

       
        $('#jstree_demo_div').jstree({
            "core": {

                "data": //data - jquery
                  {
                      type: "POST"
                      , dataType: "json"
                      , contentType: "application/json;charset=utf-8"
                      , url: "FlowCycleReport.aspx/populateTree"
                      , async: true

                      , data : function () { return JSON.stringify({ imgID: thisID, line: line }); }


                      , success: function (node) {
                          var ReturnString = node.d;
                          alert(thisID);
                          //alert(ReturnString);

                          return { "id": node.id };
                      }///success

                      , error: function (msg) {

                          alert("Error: " + msg.responseText);

                      }///error
                  }//data
            }///core
    ,
            "plugins": ["themes", "json_data", "search", "contextmenu", "types"]
    
    
            });
    }

Just in case it's my header files:
<script src="common/Scripts/json3.min.js"></script>
    <script src="common/Scripts/jquery-ui.min.js"></script>
    <script src="common/Scripts/jstree.min.js"></script>

Thanks again for your help...I just can't figure this one out...

Ivan Bozhanov

unread,
Jan 28, 2015, 9:05:14 AM1/28/15
to jst...@googlegroups.com
Why are you recreating the tree and then calling refresh? I am a bit lost - sorry. If you are using the data : function () approach you only need to create the tree once and make sure it has a reference to the line and thisID variables. If you are recreating the tree - then no need to call refresh.

Best regards,
Ivan


сряда, 28 януари 2015 г., 9:21:04 UTC+2, Cathryn Crane написа:
Hi Ivan

To unsubscribe from this group and all its topics, send an email to jstree+unsubscribe@googlegroups.com.

cathry...@gmail.com

unread,
Jan 28, 2015, 9:24:24 AM1/28/15
to jst...@googlegroups.com
I'm sorry - I'm probably not being real clear on the purpose...

So, I have a bunch of text boxes that are dynamically generated that hold different values. The tree provides different information based on what box is clicked.

So, for example, the whole page has a line number and based on that line number, a grid of boxes is generated.  Each box has its own value associated with the line number.  So, for example, line 10 might have 25 boxes with values 25-50 and line 1 might have 10 boxes with values 1 through 10.  (this is a real generic example but hopefully gives you the idea).

If box 1 is clicked, the .click event passes the line number value and the box value to a webmethod that calls a stored procedure in SQL. 

This returns a unique navigational menu that is mostly informational but does have some links to articles as you drill down. 

This whole tree navigation is different for each line number and box value.  So, I have to repopulated it each time.  It's not the same for the page.  It's actually at the object level of the page.

I hope this helps.  Maybe I'm going at this all wrong which I wouldn't be surprised.  This is my first crack at jquery.  It's looks great, but wouldn't surprise me if I'm trying to do something jstree isn't meant for.  But usually I get creative on things and I can figure it out.  For some reason, I'm just really stumped.  I understand what's happening but I can't find a solution b/c I don't know all the syntax and process flow of it.

To unsubscribe from this group and all its topics, send an email to jstree+un...@googlegroups.com.

Ivan Bozhanov

unread,
Jan 29, 2015, 3:34:26 AM1/29/15
to jst...@googlegroups.com
What you need to do is either .destroy() and create the tree again with the new data
Or set core.data.data to a function, make sure it uses the variables you set when clicking a textbox (meaning they are in the same scope) and call refresh.

From the looks of it - I believe recreating the tree (without the refresh call!) would be easier for you since you do not have much experience with jQuery / JS.

So - on click, call .destroy on the current tree instance (if it exists) and then create it again (the same thing you do above, but simply add the destroy call, and make sure you do not call refresh).

Let me know if you need something more.

Best regards,
Ivan


сряда, 28 януари 2015 г., 16:24:24 UTC+2, Cathryn Crane написа:
I'm sorry - I'm probably not being real clear on the purpose...

So, I have a bunch of text boxes that are dynamically generated that hold different values. The tree provides different information based on what box is clicked.

So, for example, the whole page has a line number and based on that line number, a grid of boxes is generated.  Each box has its own value associated with the line number.  So, for example, line 10 might have 25 boxes with values 25-50 and line 1 might have 10 boxes with values 1 through 10.  (this is a real generic example but hopefully gives you the idea).

If box 1 is clicked, the .click event passes the line number value and the box value to a webmethod that calls a stored procedure in SQL. 

This returns a unique navigational menu that is mostly informational but does have some links to articles as you drill down. 

This whole tree navigation is different for each line number and box value.  So, I have to repopulated it each time.  It's not the same for the page.  It's actually at the object level of the page.

I hope this helps.  Maybe I'm going at this all wrong which I wouldn't be surprised.  This is my first crack at jquery.  It's looks great, but wouldn't surprise me if I'm trying to do something jstree isn't meant for.  But usually I get creative on things and I can figure it out.  For some reason, I'm just really stumped.  I understand what's happening but I can't find a solution b/c I don't know all the syntax and process flow of it.

cathry...@gmail.com

unread,
Jan 29, 2015, 10:58:04 AM1/29/15
to jst...@googlegroups.com
Thank you so much.  I will let you know how it goes

To unsubscribe from this group and all its topics, send an email to jstree+un...@googlegroups.com.
Reply all
Reply to author
Forward
Message has been deleted
0 new messages