Is there any way to have a show more
option/link in jsTree
?
I want to show only part of the children and have a link to expand to show all elements.
I tried a few google searches but could not find a solution. Any help/hint would be useful.
Let's say parent-1 has 10 child nodes and the Main Root has 5 parent nodes.
Main Parent
- Parent - 1
- child-1
- child-2
- child-3
show 7 more parent-1 elements //LINK
- Parent - 2
- child-1
- child-2
- Parent - 3
- child-1
- child-2
show 2 more Main Parent elements //LINK
I'm trying to achieve the following result
Is this possible? Are there any available plugins for this? Are there any alternatives for jsTree
that support this?
You could feasibly use classes/childElement count to work this. Depending on what you want to show, you could use ids/classes to leave the elements you want to stay visible or optionally show/hide. The same principle can be applied to both child elements (say list items in a list) and higher parent elements, so once you have the first function, it can easily be adapted.
I've included a list example here to give you the idea (it's in plain javascript and you could tweak it a bit..) Jquery would make the js shorter, but it's always good to know the vanilla i reckon..
var x = document.getElementById("show");
//var root = document.getElementsByTagName('body')[0];
var count = x.childElementCount;
var btn1 = document.getElementById("ulmore");
btn1.innerHTML = "+ Show all " + count + " li children";
document.getElementById("ulmore").addEventListener("click", showmore);
function showmore() {
//var d = document.getElementsByClassName("tg1").length;
//use d if you want to show "show d more children" instead of the full amount of children
var el = document.getElementsByTagName("li");
var i;
for (i = 0; i < el.length; i++) {
if (el[i].classList.contains("tg1")) {
//el[i].style.display = "block"; works
el[i].classList.toggle('more');
if (el[i].classList.contains("more")) {
btn1.innerText = "Hide children";
} else {
btn1.innerText = "+ Show all " + count + " li children";
}
}
}
}
body {
padding: 1em;
font-size: 10pt;
}
ul {
list-style: none;
width: 10em;
padding: 0px;
}
li {
text-align: left;
line-height: 1.5;
background: lightblue;
border: 1px solid #444;
margin: 1px 0px;
padding: 2px;
}
span {
display: inline-block;
}
div {
display: inline-block;
width: 100%;
float: left;
margin: 1em 2em 1em 0em;
}
.tg1 {
background: lightsteelblue;
display: none;
}
.more {
background: lightsteelblue;
display: block;
}
/*.tog2 {
display: none;
}
.grow {
background: yellow;
display: inline-block;
}*/
<body>
<div id="ulbit">
<h4>Demo List</h4>
<ul id="show">
<li>One</li>
<li>Two</li>
<li class="tg1">Three</li>
<li class="tg1">Four</li>
<li class="tg1">Five</li>
<li class="tg1">Six</li>
<li class="tg1">Seven</li>
<li class="tg1">Eight</li>
</ul>
<span id="ulmore"></span>
</div>
<!-- <div class="tog2">
Div 2 hello
</div>
<div class="tog2">
Div 3
</div>
<span id="divmore"></span>-->
</body>
Here's a fiddle link (with body 'parent' elements) included in code.
(Note: even a <br>
tag [when used between divs] will be regarded as a top-level element .. I'd think that count by tagName (or className) would be most useful if you want to count different types of 'parent' elements (as opposed to counting children of body). Examples of both (children of body and getElementsByTagName) are included in the fiddle)
Hope this helps
did you try to use "before_open.jstree" event to show the tree the way you need? see the example (I use part of the demo page from the jstree site):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>jstree basic demos</title>
<style>
html { margin:0; padding:0; font-size:62.5%; }
body { max-width:800px; min-width:300px; margin:0 auto; padding:20px 10px; font-size:14px; font-size:1.4em; }
h1 { font-size:1.8em; }
.demo { overflow:auto; border:1px solid silver; min-height:100px; }
</style>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.2.1/themes/default/style.min.css" />
</head>
<body>
<h1>Interaction and events demo</h1>
<button id="evts_button">select node with id 1</button> <em>either click the button or a node in the tree</em>
<div id="evts" class="demo"></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.2.1/jstree.min.js"></script>
<script>
// interaction and events
$('#evts_button').on("click", function () {
var instance = $('#evts').jstree(true);
instance.deselect_all();
instance.select_node('1');
});
$('#evts')
.on("changed.jstree", function (e, data) {
if(data.selected.length) {
alert('The selected node is: ' + data.instance.get_node(data.selected[0]).text);
}
})
.on("before_open.jstree", function (e, data,a,b,c,d) {
$('#' + data.node.id + ' ul li:nth-child(n + 2)').hide();
var str = '<li class="jstree-node jstree-leaf jstree-last" role="treeitem">press to show ' + $('#' + data.node.id + ' ul li:nth-child(n + 2)').length + ' more items</li>';
var li = $(str).on('click', function(a,b,c,d) {$(a.target).parent().find('li').show(); $(a.target).hide()});
$('#' + data.node.id + ' ul').append(li);
})
.jstree({
'core' : {
'multiple' : false,
'data' : [
{ "text" : "Root node", "children" : [
{ "text" : "Child node 1", "id" : 1 },
{ "text" : "Child node 2" }
]}
]
}
});
</script>
</body>
</html>
I hope this helped.
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