JsTree: Show more options

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.