Iterate over child nodes on a Telerik MVC TreeView - kendo-ui

I have a Telerik MVC Treeview that i am trying to get the child nodes for using JQuery. I'm using the "hasChildren" property to tell me if the node has any children and that's working fine. But I can't seem to figure out the node property that will let me iterate over the child nodes. "nodes[i].children.view()" gives me an empty array but it should be an array of the child nodes according to this Kendo doc.
var productTreeView = $("#treeviewProducts").data("kendoTreeView");
var nodes = productTreeView.dataSource.view();
for (var i = 0; i < nodes.length; i++) {
if (nodes[i].hasChildren) {
var childrenNodes = nodes[i].children.view();
for (var x = 0; x < childrenNodes.length; x++) {
...
}
}
}
UPDATE: The code above works fine if the node with children is expanded but does not work when the node with children is collapsed because LazyLoading for child nodes was enabled (thanks DontVoteMeDown). Either turn that off or expand all nodes before running the code (productTreeView.expand(".k-item");).

Related

AMCharts - Dynamically add children to tree map

I am thoroughly enjoying AMChart's many features but I couldn't find any way to dynamically add some children to a treemap.
I am trying to load additional children on "hit" for each element
for (var i = 0; i < this.maxDepthLevel; i++) {
const series = this.chart.seriesTemplates.create(i);
series.columns.template.events.on("hit", async function(ev) {
const data = ev.target.dataItem.dataContext;
children = await api.getChildrenOf(data.id);
ev.target.dataItem.treeMapDataItem.children.values.push(...children);
});
}
^ this doesn't work and when doing this and then zooming out, I get
I even tried changing the underlying data and then calling
this.chart.invalidateRawData();
but to no avail.
Does anyone have any experience with adding such dynamic children to a tree map?
I cannot simply load everything upfront, there are far too many possible layers of depth unfortunately and the request will be too large!
Rather than directly pushing child items to children values you need to do it like this :
for(var index=0; index < children.length; index++){
var newChildDataItem = new am4charts.TreeMapDataItem();
newChildDataItem.value = children[index].value;
newChildDataItem.name = children[index].name;
newChildDataItem.color = ev.target.dataItem.dataContext.color;
ev.target.dataItem.dataContext.children.insert(newChildDataItem);
}

Iterating through controls on a form

I am using C++ Builder. I want to locate several string grids that I have located on different tab sheets of a page control. I know how to iterate through the child controls of a specific control. In my case, each string grid is contained under a separate tab sheet control. My question is, is there a list of all controls in an app, without regards to the hierarchy of where they are contained?
There is such a list: Application->Components, consider code below
for (int i = 0; i < Application->ComponentCount; i++) {
for (int j = 0; j < Application->Components[i]->ComponentCount; j++) {
if (dynamic_cast<TStringGrid*>(Application->Components[i]->Components[j])){
//there is your TStringGrid* regardless of a place in application
}
}
}
You may as well iterate through your tab controls children if you are sure that your string grids are only there.

Copying rendered value instead of the data value

I use Handsontable and in one column, the data type is an integer that is an index of a vector of strings v. So, instead of showing the integer index i, I have to show v[i]. I do so by declaring a custom renderer in handsontable:
var annotationTableSettings = {
data: componentAnnotation,
columns: [
{renderer: annotationId2StringRenderer},
...
However, when I copy the value of the cell (Ctrl+c in windows/linux or cmd+c in mac), the integer is copied instead of the rendered value. Does anyone know how to copy the rendered value (I would like to keep the integer data type and the custom renderer).
An example can be seen here: http://leoisl.gitlab.io/DBGWAS_support/full_dataset_visualization_0_4_6/components/comp_2.html
Just copy the first cell of the first line of the first table (in the north panel) - the cell with value "(Phe)CML" and you will copy the value 3, instead of "(Phe)CML" itself.
Thanks in advance!
you can use the beforeCopy hook.
var annotationTableSettings = {
data: componentAnnotation,
beforeCopy: data => {
for (let i = 0; i < data.length; i++) {
for (let j = 0; j < data[i].length; j++) {
if (!isNaN(data[i][j])) {
data[i][j] = v[data[i][j]]
}
}
}
}
columns: [
{renderer: annotationId2StringRenderer},
...

Determining whether a node in a collapsible tree is hidden

I'm working on a GUI that displays a list of elements.
All the elements are in a one dimensional iterable array, so displaying them would normally look something like this:
foreach (Element e: elements) {
display.Display(e);
}
I now need a way to organize the elements in a tree structure like in this example:
In my system, there is no distinction between "folder" elements and "file" elements, but I can access an element's 'depth' and 'isExpanded' values.
How can I determine whether an element should be displayed based on data taken from iterating through previous elements?
I think I've figured it out, but there may be some cases that mess it up:
bool prevIsCollapsed = false;
int collapsedPropertyDepth = 0;
// iterate through each property of this component
for (Property p : properties)
{
int depth = property.depth;
if (prevIsCollapsed && depth > collapsedPropertyDepth)
{
// dont display this property
continue;
}
if (!property.isExpanded)
{
prevIsCollapsed = true;
collapsedPropertyDepth = depth;
}
else
{
prevIsCollapsed = false;
}
}

Dom4j detach node, Jython

I am using Dom4j to detach a node, like below:
<div name="divName">
Some Text Here
<span>Some Text Here</span>
</div>
I am selecting the div node by name and then using the detach method to remove it:
xpathValue = "//*[contains(#name, 'divName')]"
xpath = dom.createXPath(xpathValue)
if xpath != None:
nodes = xpath.selectNodes(dom)
if len(nodes) > 0:
for node in nodes:
node.detach()
This seems to remove the div fine, I noticed that it also removes elements and text within that div also. What I am looking to achive is removing the div without removing the elements and text inside the div, resulting in this:
Some Text Here
<span>Some Text Here</span>
Is it possible to achive this with dom4j? If not any suggestions on how to go about this?
Cheers
Eef
Update:
#alamar
I have achived what I wanted by taking your code and editing it a little and this is what I have come up with:
xpathValue = "//*[contains(#name, 'divName')]"
xpath = dom.createXPath(xpathValue)
if xpath != None:
nodes = xpath.selectNodes(dom)
if len(nodes) > 0:
for node in nodes:
parent = node.getParent()
nodeContents = node.content()
if len(nodeContents) > 0:
for subNode in nodeContents:
parent.add(subNode.clone().detach())
node.detach()
This seems to work, but adds the nodes to the end of the parent node in the below situation:
<div name="parent">
<div name="divName">
Some Text Here
<span>Some Text Here</span>
</div>
<div name="keep"></div>
</div>
The result is this:
<div name="parent">
<div name="keep"></div>
Some Text Here
<span>Some Text Here</span>
</div>
I am trying to figure out how to get the contents of the removed node to stay in its original position, before thed div named "keep", instead of being added after the div with the name "keep". I have tried a few thing but can not seem achive this, could anyone help?
Eef
If you want to keep the order of elements, you should really ask parent for its content().
In that content (which is a List backed by parent element) collection, you should find your div and replace it with that div's content().
I don't remember idiomatic way to do that in python, frankly.
probably
if xpath != None:
nodes = xpath.selectNodes(dom)
if len(nodes) > 0:
for node in nodes:
parent = node.getParent()
index = parent.indexOf(node)
siblings = parent.content()
nodeContents = node.content()
if len(nodeContents) > 0:
for subNode in nodeContents:
siblings.add(subNode.clone().detach(), index++)
node.detach()
Try:
if xpath != None:
nodes = xpath.selectNodes(dom)
if len(nodes) > 0:
for div in nodes:
parent = div.getParent()
div.detach()
for(child in node.content())
child.detach()
parent.add(child)
I believe it would do the trick.
I.e. after detaching every div, you should reattach every div's child into div's parent.
i had a similar problem and solved it with the following function (works fine for me)
What is it doing: it will simply remove that parent tag and includes every element and node inside the element to the parent at that position.
private void _replaceTagByContent(Element element) {
Element parent = element.getParent();
List elements = parent.elements();
int insertPosition = elements.indexOf(element);
// add them all to the parent again
for (int i = 0, size = elements.size(); i < size; i++) {
Node node = (Node) elements.get(i);
if (i == insertPosition) {
// if we are here, then this has to be an element, since
// wo do only replace elements ...
for (int j = element.nodeCount() - 1; j >= 0; j--) {
Node theNode = element.node(j);
theNode.detach();
elements.add(i, theNode);
}
// finally remove this node
elements.remove(node);
}
}
}
enjoy cnsntrk

Resources