Add double click event on child node in angular-tree-widget - angularjs

I am new to angular-tree-widget.js. We need to implement double click event once we click on any tree child node. All I found only two events are supported.
$scope.$on('selection-changed', function (e, node) {
//node - selected node in tree
$scope.selectedNode = node;
});
$scope.$on('expanded-state-changed', function (e, node) {
// node - the node on which the expanded state changed
// to see the current state check the expanded property
//console.log(node.expanded);
$scope.exapndedNode = node;
});
How do I add double click event on a node here? Please help me. Thanks in advance.

You can add ng-dblclick, as #Manikandan suggested, in the following way:
HTML
<body ng-controller="TreeController" ng-dblclick="dblclick($event)">
<tree nodes='treeFamily'></tree>
</body>
JavaScript
controller('TreeController', ['$scope', function ($scope) {
$scope.dblclick = function(evt) {
angular.element(evt.target).toggleClass('red')
}
...
}])
Live Demo
https://plnkr.co/edit/nWfiDA82WDpgRGnLqJUs?p=preview
As you can see, the idea is to subscribe to event on parent element of the tree and distinguish between tree items using evt.target, which is passed to event handler using angular's $event

Related

how to collapse all function on for each angular UI tree

For Angular ui-tree, i want to add expland all or collapse all.
I tried the following code and it works.
$scope.collapseAll = function () {
$scope.$broadcast('angular-ui-tree:collapse-all');
};
$scope.expandAll = function () {
$scope.$broadcast('angular-ui-tree:expand-all');
};
...
The question is,my page have multiple ui tree, i only want to trigger expandAll function for separate. now i trigger this expandAll function. ALL ui -tree will be affected.
Is there any solution to set each one as seperate?
How to call collapseAll function on Angular UI tree?
If you check at the Source of angular ui tree , the 'angular-ui-tree:collapse-all' event toggles a scope value . Other problem being each of the directives in angular-ui-tree inherits the scope of the parent than having a isolated scope . So changing the when you broadcast an event it is actually changing the same scope value .
You should either find a way for each tree's to have a separate scope or think of using some other tree's like v-accordion .
we should broadcast angular-ui-tree:collapse-all for specified tree scope.
It's work for me.you can use it without any hesitation at all.
function collapseAll() {
var treeScope = _getRootNodesScope('myTreeId');
if (treeScope) {
treeScope.$broadcast('angular-ui-tree:collapse-all');
}
}
function expandAll() {
var treeScope = _getRootNodesScope('userTreeroot');
if (treeScope) {
treeScope.$broadcast('angular-ui-tree:expand-all');
}
}
function _getRootNodesScope(myTreeId) {
var treeElement = angular.element(document.getElementById(myTreeId));
if (treeElement) {
var treeScope = (typeof treeElement.scope === 'function') ?
treeElement.scope() : undefined;
return treeScope;
}
return undefined;
};

angular-ui-tree: dropped location + catch dropped event in directive

I'm using angular-ui-tree for building a tree of items in my app.
I'm using its drag & drop feature and I need to know when & where (on what element) the dropping occurs.
For example, I drag item1, and drop it on a panel. I want the panel to display the item name. (each item has a name property). the panel is just a simple div with text inside.
I saw in the documentations that I can access the "dropped" event in my controller. But I don't understand how to change the panel content according to the dragged & dropped item.
As in documentations $callbacks (type: Object)
$callbacks is a very important property for angular-ui-tree. When some
special events trigger, the functions in $callbacks are called. The
callbacks can be passed through the directive.
you define the events in a treeOptions collection
myAppModule.controller('MyController', function($scope) {
// here you define the events in a treeOptions collection
$scope.treeOptions = {
accept: function(sourceNodeScope, destNodesScope, destIndex) {
return true;
},
dropped: function(e) {
console.log (e.source.nodeScope.$modelValue);
}
};
});
then in your tree div add callbacks="treeOptions" which you defined above in the controller
<div ui-tree callbacks="treeOptions">
<ol ui-tree-nodes ng-model="nodes">
<li ng-repeat="node in nodes" ui-tree-node>{{node.title}}</li>
</ol>
</div>
then you can access the old parent from here
e.source.nodeScope.$parentNodeScope.$modelValue
and you can access the new parent from here
e.dest.nodesScope.$parent.$modelValue
Hey guys i just found it !
$scope.treeOptions = {
dropped: function (event) {
//To catch the event after dragged
//Value of model which is moving
event.source.nodeScope.$modelValue;
//Source Parent from where we are moving model
event.source.nodeScope.$parentNodeScope.$modelValue;
//Destination Parent to where we are moving model
//Edit: Use "nodesScope" instead of "nodeScope" for dest object
event.dest.nodesScope.$nodeScope.$modelValue;
}};
Hope it works for you too:)
You access the "dropped" item like this.
$scope.elOptions = {
dropped: function(e) {
console.log (e.source.nodeScope.$modelValue);
}
};
Addional information which might be useful can be found on this issue of the project : https://github.com/angular-ui-tree/angular-ui-tree/issues/272
For example in my case, I was dragging from one tree to another one, and in this case, the dropped function must be overriden in the SOURCE tree options (and not the DESTINATION one like I initially thought).
The discussion in the related issue helped me a lot to find this out.

Primefaces tree checkbox single selection

I'm need primefaces tree in "checkbox" selection mode, but only one and only one node can be selected at a time. By default, primefaces tree selects all descendants when a node is selected and that is actually what I want to change.
Can anybody help me figure it out, please?
I finally found a way to realize this by looking at the Javascript source code of the tree. You can e.g. create a singleton that caches the previously selected node. By using the "onNodeClick" attribute of the tree you can call a Javascript function that unselects the previous node before the widget internally sets the new selected node (and potentially posts the new selection when using ajax events).
Update:
I modified the Facelet and the Javascript to search the tree for a preselected node on initialization. Be aware that the preselected node has to be visible to make it work correctly. See this answer for details about expanding the parent nodes.
Bean:
#Named
#ViewScoped
public class BackingBean implements Serializable {
private TreeNode rootTreeNode;
// IMPORTANT: Use array!
private TreeNode[] selected;
public TreeNode getRootTreeNode() {
if (rootTreeNode == null) {
rootTreeNode = new DefaultTreeNode("Root", null);
// init child tree nodes
}
return rootTreeNode;
}
public TreeNode[] getSelected() {
return selected;
}
public void setSelected(TreeNode[] selected) {
this.selected = selected;
}
}
Facelet:
<p:tree id="tree"
onNodeClick="TREE_SELECTION.updateSelection(node, event)"
propagateSelectionDown="false" propagateSelectionUp="false"
selection="#{backingBean.selected}" selectionMode="checkbox"
value="#{backingBean.rootTreeNode}"
var="data"
widgetVar="treeWidget">
<p:treeNode>
<h:outputText value="#{dataWrapper.label}" />
</p:treeNode>
</p:tree>
Javascript:
<script type="text/javascript">
// singleton for tree selection
var TREE_SELECTION = {
init: function (treeWidgetVar) {
this.treeWidget = PF(treeWidgetVar);
this.selectedNode = this.treeWidget.jq.find('.ui-treenode-selected');
},
treeWidget: null,
selectedNode: null,
updateSelection: function (node, event) {
// get the checkbox state of the clicked node
var checkbox = node.find('> .ui-treenode-content > .ui-chkbox'),
checked = checkbox.find('> .ui-chkbox-box > .ui-chkbox-icon').hasClass('ui-icon-check');
if (checked) {
// checkbox is going to be unchecked
this.selectedNode = null;
return;
}
// check for previously selected node
if (this.selectedNode !== null) {
// get the checkbox of the previously selected node
checkbox = this.selectedNode.find('> .ui-treenode-content > .ui-chkbox');
// update tree
this.treeWidget.uncheck(checkbox);
this.treeWidget.removeFromSelection(this.treeWidget.getRowKey(this.selectedNode));
}
// cache selected node
this.selectedNode = node;
}
};
// initialize singleton when document is loaded
$(function () {
TREE_SELECTION.init('treeWidget');
});
</script>

can not travel int Extjs treestore

I have treestore, i want to traverse the each node. I found no each function in the treestore. But the store have the each function. I also tried the treestore.data. but not success.
pls help me .tks!
Ext.data.TreeStore has no each method, since it deals with Ext.data.Tree. However, Ext.data.NodeInterface has eachChild method, you can use this method to traverse the tree.
function traverse(node) {
// do something with node
node.eachChild(function(child) {
traverse(child); // handle the child recursively
});
}
traverse(yourTreeStore.getRootNode()); // start tree traversal with root node
Use Ext.each as bellow:
Ext.each(tree.getRootNode().childNodes, function (node) {
console.log(node.data.text);
});
Why can't you use Ext.Array.each for your requirement....
Refer below sample example.
Ext.Array.each(records, function(record, index, records) {
if(!(record.get('name')==='')){
}
});

Expand node not calling callback

I am testing my ExtJs App with Jasmine. So there are no views involved.
I want to expand several nodes, but first my root node. But even expanding that node fails.
I create my TreeStore, then:
Code:
// oStore is my treestore, everything OK
// Here, I also tried calling oStore.load(); see below
var oNode = oStore.getNodeById( 'root' );
// oNode.isExpanded() says false
// oNode.hasChildNodes() says false
oNode.expand(false, function(oChildren) {
// it never gets here
console.log( "hello?");
});
My listener for load gets called, but the listener for beforeexpand does not get called.
If I call oStore.load() at the beginning after store creation, then when the on load listener gets called it says, oNode.childNodes.length has 3 children...
So why is expand()'s callback not called? How can I get that node to expand?
Why are the children of the node already loaded when calling oStore.load()? After that expand() is also not fired.
EDIT:
Starting my root node with expanded: true makes my store collapse correctly on collapse(), but after it expand() does nothing.
oNode.collapse(false, function() {
console.log( "collapse()" ); // works, but expand() afterwards does not
});
Found the solution. I need to wait for the store to get loaded. Is is a Jasmine issue:
runs( function() {
oStore.on( 'load', function() {
bStoreLoaded = true;
});
});
waitsFor( function() {
return bStoreLoaded;
}, " store to be loaded", 5000 );
runs( function() {
oNode.expand(false, function( aoChildren ) {
aoChildrenRoot = aoChildren;
bRootExpanded = true;
});
});
There is some convoluted logic in the source to tell the node whether or not it needs to expand or be expandable. Take a look at the code below that I ended up resorting to when I tried to manipulate the tree programmatically:
if (!parentNode.isExpanded() && !parentNode.isLeaf()) {
parentNode.expand(false, function () {// deal with open or closed paths
console.log('expanded parent to pick up new item');
});
} else {
parentNode.callStore('suspendAutoSync');
if (parentNode.isLeaf()) { // Parts that are leafs
parentNode.set("leaf", false); //must be set to work properly
parentNode.appendChild(newPart);
parentNode.expand(); //expand to show newly created child
} else {
parentNode.insertChild(0, newPart);
}
parentNode.callStore('resumeAutoSync');
}

Resources