I have the following code to display jstree control with ajax data.
action method for data in Home controller
[HttpGet]
public JsonResult GetNodeData()
{
var tvdata = new List<NodeDataStructure>();
tvdata.Add(new NodeDataStructure { id = "student1", parent = "#", text = "Single root node", value = "10", @class = "parentNode" });
tvdata.Add(new NodeDataStructure { id = "student2", parent = "#", text = "Root Node with children", value = "10", @class = "parentNode" });
tvdata.Add(new NodeDataStructure { id = "student3", parent = "student2", text = "Query1", value = "answerQ1", @class = "cn1" });
tvdata.Add(new NodeDataStructure { id = "student4", parent = "student2", text = "Query2", value = "answerQ2", @class = "cn1" });
return Json(tvdata, JsonRequestBehavior.AllowGet);
}
ViewModel
public class NodeDataStructure
{
public String id { get; set; }
public string @class { get; set; }
public string parent { get; set; }
public string text { get; set; }
public string value { get; set; }
}
Index.cshtml
<div id="Div_jstree"></div>
@section Scripts{
<script src="Scripts/jstree.min.js"></script>
<script>
$(document).ready(function () {
$.ajax({
url: 'Home/GetNodeData',
method: 'get',
dataType: 'json',
success: function (data) {
$(data).each(function (index, item) {
console.log("here");
});
$('#Div_jstree').jstree({
'core': {
'data': data
}
});
$(document).on('click', '.cn1', function () {
console.log('im here');
});
},
error: function (x,y,z) { }
});
});
</script>
}
I have put the click event in the success part of ajax but the click does not work, whats the problem here and how should I fix it?
Here is the generated html but since jstree is dynamic I don't see any use of this.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title>Index</title>
<link href="/Content/site.css" rel="stylesheet"/>
<link href="/Content/themes/base/all.css" rel="stylesheet"/>
<script src="/Scripts/modernizr-2.6.2.js"></script>
</head>
<body>
<link rel="stylesheet" href="Content/themes/default/style.min.css" />
<br><br><br><br>
<div id="Div_jstree"></div>
<script src="/Scripts/jquery-2.2.0.js"></script>
<script src="/Scripts/jquery-ui-1.11.4.js"></script>
<script src="/Scripts/jquery.unobtrusive-ajax.js"></script>
<script src="/Scripts/jquery.validate.js"></script>
<script src="/Scripts/jquery.validate.unobtrusive.js"></script>
<script src="Scripts/jstree.min.js"></script>
<script>
$(document).ready(function () {
$.ajax({
url: 'Home/GetNodeData',
method: 'get',
dataType: 'json',
success: function (data) {
$(data).each(function (index, item) {
console.log("here");
});
$('#Div_jstree').jstree({
'core': {
'data': data
}
});
$(document).on('select_node.jstree', '.cn1', function () {
console.log('im here');
});
},
error: function (x, y, z) { console.log('error'); }
});
});
</script>
<!-- Visual Studio Browser Link -->
<script type="application/json" id="__browserLink_initializationData">
{"appName":"Chrome","requestId":"2cf16620b2de4718bed3c368cbe7f86b"}
</script>
<script type="text/javascript" src="http://localhost:48985/eae5ba43081c4bce98f0d05ef8143589/browserLink" async="async"></script>
<!-- End Browser Link -->
</body>
</html>
here is the generated DOM for (#Div_jstree)
<div id="Div_jstree" class="jstree jstree-1 jstree-default" role="tree" aria-multiselectable="true" tabindex="0" aria-activedescendant="student4" aria-busy="false">
<ul class="jstree-container-ul jstree-children" role="group">
<li role="treeitem" aria-selected="false" aria-level="1" aria-labelledby="student1_anchor" id="student1" class="jstree-node jstree-leaf"><i class="jstree-icon jstree-ocl" role="presentation"></i><a class="jstree-anchor" href="#" tabindex="-1" id="student1_anchor"><i class="jstree-icon jstree-themeicon" role="presentation"></i>Single root node</a></li>
<li role="treeitem" aria-selected="false" aria-level="1" aria-labelledby="student2_anchor" aria-expanded="true" id="student2" class="jstree-node jstree-last jstree-open">
<i class="jstree-icon jstree-ocl" role="presentation"></i><a class="jstree-anchor" href="#" tabindex="-1" id="student2_anchor"><i class="jstree-icon jstree-themeicon" role="presentation"></i>Root Node with children</a>
<ul role="group" class="jstree-children" style="">
<li role="treeitem" aria-selected="false" aria-level="2" aria-labelledby="student3_anchor" id="student3" class="jstree-node jstree-leaf"><i class="jstree-icon jstree-ocl" role="presentation"></i><a class="jstree-anchor" href="#" tabindex="-1" id="student3_anchor"><i class="jstree-icon jstree-themeicon" role="presentation"></i>Query1</a></li>
<li role="treeitem" aria-selected="true" aria-level="2" aria-labelledby="student4_anchor" id="student4" class="jstree-node jstree-leaf jstree-last"><i class="jstree-icon jstree-ocl" role="presentation"></i><a class="jstree-anchor jstree-clicked" href="#" tabindex="-1" id="student4_anchor"><i class="jstree-icon jstree-themeicon" role="presentation"></i>Query2</a></li>
</ul>
</li>
</ul>
</div>
you know that <div id="Div_jstree"></div> is your container
and if you are certain that after obtaining ajax results, calling
$('#Div_jstree').jstree({'core': {'data': data}});
will definitely trigger a change in the DOM structure of your container.
What you can do is that, after calling jstree, perform a
$('#Div_jstree').find('li').each(function(){
//apply a click listerner on each leaf <li> element that is found
//in #Div_jstree
if( $(this).find('ul').length <=0 ){
$(this).click(function(){
// your click handling logic
});
}
});
To put it all together, it should look similar to this.
node 1, 3 and 4 should have listeners applied to them.
$(document).ready(function(){
var changesIntroducedToContainerAfterAjax = '<ul class="jstree-container-ul jstree-children" role="group"> <li role="treeitem" aria-selected="false" aria-level="1" aria-labelledby="student1_anchor" id="student1" class="jstree-node jstree-leaf"><i class="jstree-icon jstree-ocl" role="presentation"></i><a class="jstree-anchor" href="#" tabindex="-1" id="student1_anchor"><i class="jstree-icon jstree-themeicon" role="presentation"></i>Single root node</a></li> <li role="treeitem" aria-selected="false" aria-level="1" aria-labelledby="student2_anchor" aria-expanded="true" id="student2" class="jstree-node jstree-last jstree-open"> <i class="jstree-icon jstree-ocl" role="presentation"></i><a class="jstree-anchor" href="#" tabindex="-1" id="student2_anchor"><i class="jstree-icon jstree-themeicon" role="presentation"></i>Root Node with children</a> <ul role="group" class="jstree-children" style=""> <li role="treeitem" aria-selected="false" aria-level="2" aria-labelledby="student3_anchor" id="student3" class="jstree-node jstree-leaf"><i class="jstree-icon jstree-ocl" role="presentation"></i><a class="jstree-anchor" href="#" tabindex="-1" id="student3_anchor"><i class="jstree-icon jstree-themeicon" role="presentation"></i>Query1</a></li> <li role="treeitem" aria-selected="true" aria-level="2" aria-labelledby="student4_anchor" id="student4" class="jstree-node jstree-leaf jstree-last"><i class="jstree-icon jstree-ocl" role="presentation"></i><a class="jstree-anchor jstree-clicked" href="#" tabindex="-1" id="student4_anchor"><i class="jstree-icon jstree-themeicon" role="presentation"></i>Query2</a></li> </ul> </li> </ul>';
//simulate Ajax call
$('#Div_jstree').html(changesIntroducedToContainerAfterAjax);
//apply listeners to leaf nodes
$('#Div_jstree').find('li').each(function(){
if( $(this).find('.jstree-node').length <=0 ){
console.log( $(this).prop('id') );
$(this).click(function(){
alert( $(this).prop('id') + " clicked" );
});
}
});
});
See it working on CodePen: http://codepen.io/anon/pen/vLzxpj
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With