How can i check KendoTreeview has Children - javascript

How can i expand kendotreeView nodes with no children?, i need help checking if parent has child node if there is one or more child i want to keep it collapsed otherwise expanded.
I used the following Jquery code and works fine but it find by text value. i rather check all node with child li and expand if no child exist.
var treeview;
treeview = $("#treeview").data("kendoTreeView");
var nodeToExpand = treeview.findByText('abc.');
treeview.expand(nodeToExpand);
is there anyways to replace the code above to collapse or expand based on that?

You can iterate over all nodes, and if any do not have children nodes, expand them like this:
var treeView = $("#treeview").data("kendoTreeView");
var nodes = treeView.dataSource.view();
for (var i = 0; i < nodes.length; i++) {
if (!nodes[i].hasChildren) {
treeView.expand(nodes[i]);
}
}

Related

JavaScript How to create elements into each created element?

I'm trying to put a content div into each parent div, but this way it puts all the content divs to the first parent div, not each parent div. I've tried to do it in 2 for loops, tried forEach, but just can't figure it out.
for (let i = 0; i < 5; i++) {
const parent = document.createElement("div");
parent.classList.add("parent");
parent.setAttribute("id","parent");
document.getElementById("container").appendChild(parent);
const content = document.createElement("div");
content.classList.add("content");
document.getElementById("parnet").appendChild(content);
}
Ty for your answer
You're using id's to select your parents with. But you can't have multiple elements with the same id value. getElementById will also look for the first occurence of the id, so you will always get the first parent element.
Besides that, you already have a reference to the parent in your parent variable. No need to look it up again, just use the reference you already have.
const container = document.getElementById("container");
for (let i = 0; i < 5; i++) {
const content = document.createElement("div");
content.classList.add("content");
const parent = document.createElement("div");
parent.classList.add("parent");
parent.append(content);
container.append(parent);
}

why does my variable seem to be updating?

I'm currently learning JavaScript and as far as I know have not learned anything that could explain the following:
<div id="parent">
<div>One</div>
<div>Two</div>
</div>
<script>
function test(node) {
var divs = node.children;
console.log(divs);
var div = document.createElement("div");
node.appendChild(div);
console.log(divs);
}
test(document.querySelector("#parent"));
</script>
I want the variable divs to be an object containing the children divs of node that exist when that line of code is run. Which it is, however it seems to update when a child is added to the parent node. What explains this behaviour; am I creating a reference to the element, and if so how do I achieve what I want to?
In JavaScript, every object is passed by a reference instead of value. The .children property of a node is an object (HTMLCollection object to be specific). What that means is that 'divs' variable will not contain the children at the time it is run, it will refer to the children property. When children change and new nodes are added, accessing the divs variable will return the current state of children, so it will contain the new child as well. If you just want to just copy the reference to initial children, you can create another variable.
function test(node) {
var children = node.children;
var divs = [];
// copy every child to the divs array
for (var i = 0; i < children.length; i++) {
divs.push(children[i]);
}
var div = document.createElement("div");
node.appendChild(div);
// since divs is just an array copy of the initial children,
// when children change, the divs still only contains the initial nodes
console.log(divs);
// however, as we said before, children will still be a reference to
// current node's children, so
console.log(children); // outputs 3 divs
}
test(document.querySelector("#parent"));
divs holds a reference to the children property of the selected node. For this reason, if you change this children property, the content of divs also changes.
If you want to keep divs stable, create a shallow copy of the array-like object children:
function test(node) {
var divs = Array.prototype.slice.call(node.children);
console.log(divs);
var div = document.createElement("div");
node.appendChild(div);
console.log(divs);
}
You could create a new array
var divs = new Array(node.children.length);
for(var i = 0; i < node.children.length; i++){
divs[i] = node.children[i]
}
console.log(divs);
var div = document.createElement("div");
node.appendChild(div);
console.log(divs);
You can use querySelectorAll, it returns a static list not live. For more details you can check this link.
https://www.w3.org/TR/selectors-api/#queryselectorall
<div id="parent">
<div>One</div>
<div>Two</div>
</div>
<script>
function test(node) {
var divs = document.querySelectorAll('#'+node.id +' div');
console.log(divs);
var div = document.createElement("div");
node.appendChild(div);
console.log(divs);
}
test(document.querySelector("#parent",'#parent div'));
</script>

EasyUI treegrid collapseAll initially

I have used the below example to populate a hierarchical structure.
http://www.jeasyui.com/documentation/treegrid.php
When initially loaded, the tree is all expanded. IS there any setting which I am missing to load the tree initially all collapsed. I have tried "state: 'closed' in the data-options but it is not working.
If you used the "convert" filter, you can add the state property to your node
while(toDo.length){
var node = toDo.shift(); // the parent node
// get the children nodes
for(var i=0; i<rows.length; i++){
var row = rows[i];
if (row.parentId == node.id){
var child = {id:row.id,text:row.name, state:'closed'};
if (node.children){
node.children.push(child);
} else {
node.children = [child];
}
toDo.push(child);
}
}
}

Get childnode's children until there aren't any

I'm using DOMParser() to parse a HTML string, and am trying to get all the child nodes with a for loop. However I do not know how to get the child nodes' nodes, and their children, etc...
var str = "<div><p>paragraph<span>span</span></p></div>";
var doc = new DOMParser().parseFromString(str, 'text/html');
var childnodes = doc.body.childNodes;
for (var i = 0; i < childnodes.length; i++) {
console.log(childnodes[i]);
console.log(childnodes[i].childNodes);
console.log(childnodes[i].childNodes[i].childNodes);
}
This works as I'd like, it gives the div, p, text, and span, but how would I make this work with a for loop that gets all the grandchildren? Without jQuery?
Here's a fiddle with the above code.
You should use recursion for this:
function travelChildren(childnodes){
for (var i = 0; i < childnodes.length; i++) { // for each node in childnodes
console.log(childnodes[i]); // console log current node
travelChildren(childnodes[i].childNodes) // and travel its children
}
}
travelChildren(childnodes) // start recursion with the child nodes you want
For those who can use jQuery, you could do it in a while loop.
var $children = $(document.body).children();
while ($children.length) {
console.log($children.attr('class'));
$children = $children.children();
}
Or as #adeneo suggested, you can use contents():
$(document.body).find('*').contents();
Although, jQuery recommends to "Avoid the All Selector," either way it's likely going to be expensive code.

Trying to convert a jQuery plugin to pure javascript

I have a jQuery plugin that I want to convert into pure javascript, so that I can drop the dependency on jQuery. The part of the plugin i'm stuck on is this bit, which returns the DOM elements sorted by depth (eg. body's children, then grandchildren, then great-grand-children, etc etc)
var first = $('body'),
output = [];
while(first.length != 0) {
output = $.merge(output, first);
first = first.children();
}
basically I just need the pure javascript version of $('body') , $.merge and children() to help me on my way.
Any help would be much appreciated
Ok, I figured it out myself, it was pretty simple in the end.
// Every Element in the DOM.
var allElements = document.getElementsByTagName('*'),
// All the Element's children sorted by depth,
// ie. body, then body's children, grandchildren,
// so on and so forth.
sortedByDepth = [];
// for every element
for(var i = 0; i<allElements.length; ++i) {
// grab Its children
var allChildren = allElements[i].children;
// for every grabbed child
for(var j = 0; j<allChildren.length; ++j){
// Add it to the sortedByDepth array
sortedByDepth = sortedByDepth.concat(allChildren[j]);
}
}
console.log(sortedByDepth);

Categories

Resources