How to update treepanel's root name without reloading the root again? - extjs

I am working with ExtJS 4.2 and have two tree panels. I am also using treeviewdragdrop to be able to drag some nodes from left tree to right.
Now let me explain the problem I am having.
You can see that AMAZONE is the Service Alias and as soon you change something in that textfield, there is a listener on blur to update right tree's root text. Since its AMAZON now, the root is also AMAZON. Then you can drag items from left to right like i have in the picture (Yhoo, dbTask).
This is when I get into trouble. When I go back and change the SERVICE ALIAS, it changes the name but nodes disappear since I have to reload the root node again in order to see the updated root text. Is there a way to maybe update the view, that actually updates whatever changed were made. This what I have now.
This is the code
listners:
{
blur: function()
{
var root_node = right_tree.getRootNode();
root_node.data.text = new_alias_name;
right_tree.store.load(); // or reload()
}
}
I know I can save dropped node into a variable and as soon as I reload the tree, I can assign those as children. But something tells me there should be simpler way. Thnaks ;)

Use:
root_node.set('text', new_alias_name');
And remove the call to load.

Related

How do I return focus to an element when the entire page changes?

I have a complicated setup. My application is driven by a set of "rules" which dictate what the user interface is. The UI is rendered by looping through the rules and creating the individual dropdowns. Initially, everything renders properly. However, once a user makes a change to the UI, other rules may be affected. In my application, an api call is made, which then returns a modified set of rules. In the attached plunker, I've simplified things such that only the new set of rules is applied, which causes the page to re-render. The problem is that my users would like to be able to tab between all of the entries on the page and make changes. However, once the page is re-rendered, the currently selected page element is now gone nothing has the focus. I've tried to put the focus back on the proper element by tracking a common Id, but to no avail.
Using either of these doesn't seem to work.
var el = document.getElementById(focusId);
el.focus();
angular.element(el).focus();
I've also tried using the autofocus attribute on the dropdown that I want to have focus, but that didn't work either. I'm using angularjs 1.2. Any ideas are appreciated.
http://plnkr.co/edit/ND9PKqULIOlixWR4XChN?p=preview
If you want to assign auto focus dynamically to a element on the DOM from angular you can use this:
var myEl = angular.element(document.querySelector('select'));
myEl.attr('autofocus',"attr val");
You can also pass in an id like: angular.element(document.querySelector('#focusId'));
You can look here for a prior answer which may be of some more help!
-Cheers!
Problem here is, you are trying to focus the element before the blur event completes. So you need to execute the focus code after blur event. Async execution of your focus code would solve the problem. You can use either setTimeout or $timeout.
setTimeout(function(){
angular.element('#'+focusId).focus();
/* //or
var el = document.getElementById(focusId);
el.focus();
*/
});
or
$timeout(function(){
angular.element('#'+focusId).focus();
/* //or
var el = document.getElementById(focusId);
el.focus();
*/
});
dont forgot to inject $timeout to your controller if you are using second code. Hope this helps :)

Stores and Dataview List - Can't Add Element - IndexOf of null

Using Sencha Touch (2.2) with Sencha Architect 2
I have a tree structure in which I navigate.
The nodes are Elements and elements can either be a folder or a leaf.
To display the elements on my Ext.dataview.dataview (LIST), I use a store (storeID: 'elementstore') and Ext.dataview.component.Dataitem.
Here is my code to fill the LIST at first and everytime we open a folder to go deeper in the tree.
Filling the store for the first time, disable event so update() is not
called twice has I will be switching to this view right after the
creation of it. It works well and give back the desired result. I have
in my LIST the first level of Folders and Leaf displayed.
This is fired directly in the list with an onItemTap Event
var EStore = Ext.getStore('elementstore');
EStore.removeAll();
EStore.suspendEvents();
EStore.add(record.get('arrElement'));
EStore.resumeEvents(true);
Emptying and refilling the store with the reached level of the tree.
This is fired directly in the LIST with an onItemTap Event
if(record.get('strUIType') === 'folder')
{
INDEX_STACK.push(index);
store = Ext.getStore('elementstore');
store.removeAll();
store.add(record.get('arrElement'));
}
What is wrong is when I try to go backward, going up in my tree. Here
is the code which is located in a Sencha Controller.
It actually does not go back one level but back at the top level. ACTIVE_PROJECT is the
index of the active tree which are all located in my project store.
var popped =INDEX_STACK.pop();
var tab = tabpanel.getParent().getParent().getParent().getComponent('projects_Tab');
if(popped === undefined)
{
tab.setActiveItem(0);
}
else
{
var eStore = Ext.getStore('elementstore');
eStore.removeAll();
//Crashes!
eStore.add(Ext.getStore('projectstore').getAt(ACTIVE_PROJECT).get('arrElement'));
}
Has you see the eStore.add(....) is the crashing line on which I get the following error :
Uncaught TypeError: Cannot call method 'indexOf' of null sencha-touch-all.js:21
Ext.Array.contains.e
Ext.Array.include
Ext.define.join
Ext.define.insert
Ext.define.add
Ext.define.onMain_TabsTap (----Yep this line is my code the rest is sencha touch...
Ext.define.doFire
The only thing I achieve to add to the store in this controller is an empty Ext.create(CarboZero.model.Element). I can not get anything from my active project.
Is there something wrong with removing and readding? Is my store getting corrupted from how I'm using it? I have been working on that for about 2 days without getting anything to work properly...
EDIT TO THE QUESTION
I just set in my Element store the destroyRemovedRecords to FALSE.
Everything works, but I don't understand ANYTHING on why it corrected the problem with my particular structure... WHat is the remove() doing exactly???
Set Element store's property to the following
destroyRemovedRecords : false
Solve the problem, still can't explain why.
I had the same issue. In my case, the caching became full. On the leaf models, you could set useCache: false to prevent the data to get cached. That fixed my issue.

How do I sort items on insert into treestore and have them displayed sorted in treepanel? extjs 4.07

I want to know how to insert items into a treestore sorted, if there is a way within extjs to do this. I then want to have the items appear in a treepanel sorted, although there may already be some nodes in the treepanel;
So, that question may be, how do I have a treepanel reload what it is displaying based on what is within my store. Let me be clear, I do not want to reload the store from some datasource. I want to reload the panel to reflect what is contained within the store. What is the best way to go about this?
There is no real default way to do this. What your going to have to do is create an empty store on the page that uses the same model as the tree, something really simple like this:
var mySortStore = Ext.create("Ext.data.Store", {
model: "MyTreeStore",
data: []
});
Then when you go to add the node to the tree, use this function instead:
function addNodeSorted(node, childToBeAdded){
//clear the store from previous additions
mySortStore.removeAll();
//remove old sorters if they are dynamically changing
mySortStore.sort();
//add the node into the tree
node.appendChild(childToBeAdded);
var cn = node.childNodes,
n;
//remove all nodes from their parent and add them to the store
while ((n = cn[0])) {
mySortStore.add(node.removeChild(n));
}
//then sort the store like you would normally do in extjs, what kind of sorting you want is up to you
mySortStore.sort('height', 'ASC');//this is just an example
//now add them back into the tree in correct order
mySortStore.each(function(record){
node.appendChild(record);
});
}

ExtJs tree panel. How to scroll to a node

I have a Tree Panel which I expand programmatically.
When I expand a node, I would like to "jump to" this node, I mean to scroll to it.
How to scroll a tree panel to a specific node ?
UPDATE:
I use Ext 4.1
Try using selectPath() http://docs.sencha.com/ext-js/4-0/#!/api/Ext.tree.Panel-method-selectPath
In extjs 3.x you can try calling focus() on the TreeNodeUI (myNode.ui.focus())
The tree is asynchronously loading every node, and you need to call to focus only after all the nodes have been loaded. What you are going to need to do is to set autoLoad to false on your root node, then later in the code manually load the root node for the first time using:
rootNode.expand(true, function(){
myTreePanel.getView().focusRow(nodeyouwanttofocus);
});
doing it this way allows you to use the first parameter of the expand function that makes the expand fully recursive and also assures that the second parameter that is a function only executes after all the nodes are loaded, guarenteeing that the view is the correct height and that the node exists visually.
Another option that allows more flexability is to hook into the expand event:
var myTreeStore = Ext.create("Ext.data.TreeStore", {
listeners: {
expand: function(theParentNode){
theParentNode.eachChild(function(node){
if(nodeIWantSelected == node)
myTreePanel.getView().focusRow(node);
}
}
}
});
and you can use the .select of the selection model to hook in to select the node (and I think it may focus the node too).
I haven't tried 'selectPath' as suggested by Sha before, which seems a lot easier to use, but you can hook in the focusRow function as the callback and I think that would work too.
You can use tree.getView().focusRow(), like it:
tree.expandPath(
'/root/1/2/3',
'id',
'/',
function() {
tree.getView().focusRow(tree.getStore().getNodeById('3'));
}
});
But, if your tree use animate: true and load every node asynchronously and any node in the path not loaded yet this approach doesnt work (tree is not scrolled to the selected node because of multiple layout updates).
As workaround you can:
set animate: false for tree;
add 'afterlayout' listener, like this:
tree.on('afterlayout', function() {
tree.getView().focusRow(tree.getSelectionModel().getSelection()[0]);
}
I guess you can add this handler when needed and remove it when everything is done.

Extjs 4 set each item an id

So i'm working with the new Ext following MVC patterns by creating controllers which listen to view events to fire methods. I have a view with a tree loaded as an admin menu and I want to listen from the 'Users' controller when the tree item called 'List all users' is clicked so I can show the grid with all users. My logic says that I have to set an id to each tree element in order to make sure I'm listening to the right and only possible one...problem is, even though I send and id to my json on each element, it never gets assigned. The element ids still have the 'ext-gen1091' type of element ids.
Any idea how do I do about assigning a unique id to each of my tree elements?
My json looks like this:
{"expanded":"true","text":"Users","id":"users","children":[{"text":"List all users","id":"userslist"....
You don't need to use HTML ids to identify the record you are handling. ExtJS provides APIs that make it easy for you to handle operations, listen to events etc on the tree or other components.
Since, you already have id assigned to each node in the tree. You can use the same id to work upon when an action / event occurs. All you have to do is add appropriate event listener methods to the tree panel. For example if you are tracking click on a node you can make use of the itemclick. The methods parameters provide you access to all information you will need.
here is the skeleton code:
itemclick: function(Ext.view.View this, Ext.data.Model record, HTMLElement item, Number index, Ext.EventObject e) {
// Access the record using record or you can access the HTML using item variable.
}
Similarly you can make use of other events and track user actions.

Resources