Reputation: 825
I need to insert a sibling item to tree on click in angular-ui-tree (https://github.com/angular-ui-tree/angular-ui-tree)
it means I have:
<item><input value"item A #1"><button>insert under</button></item>
<item><input value"item B #2"><button>insert under</button></item>
<item><input value"item C #3"><button>insert under</button></item>
<item><input value"item D #4"><button>insert under</button></item>
when I click in Item C "insert under" I need to add new item between Item B and Item C - and focus this new item's input.
How to do that?
Thank you a lot!
Upvotes: 1
Views: 2360
Reputation: 289
you made it more complicated for yourself by not providing exact sample of your data and html, so I made only generic solution but should help you.
1) how to make "add below" button
ui-tree only does render your tree model. So as is natural in angular, only thing you need to do is to alter the data in the way you want - add node under some other.
So you only need to get array of sibling nodes and current index. Index is available in $index
since ui-tree uses standart ngRepeat
. More tricky is to get the array of siblings. Quick look at documentation reveal $parentNodesScope
is scope of tree-nodes (ie siblings container) and this scope then contains $modelValue
which is, guess, siblings array. So this does the job:
<button ng-click='$parentNodesScope.$modelValue.splice($index+1,0,{value:"New",nodes:[]})'>Add below</button>
Note that {value:"New",nodes:[]}
is what will be added, change it to what data structure you have.
2) how to make input of added node focused
There is lot of info on how to focus inputs in agular, for example here How to set focus on input field?
I like this https://stackoverflow.com/a/20865048 answer most and it works. It basically focus all elements when they are insterted to DOM - so also when ui-tree re-render the tree with new nodes. Drawback is that after first page load, the last node will be focused, but it's now up to you to deal with it.
You can find whole demo here: http://plnkr.co/edit/NWGvJY4YHaDlCG26W7Fd?p=preview
Upvotes: 1
Reputation: 796
Try this. First I've added onclick event listeners to the HTML buttons:
<item><input value="item A #1"><button onclick="onClickItem(this);">insert under</button></item>
<item><input value="item B #2"><button onclick="onClickItem(this);">insert under</button></item>
<item><input value="item C #3"><button onclick="onClickItem(this);">insert under</button></item>
<item><input value="item D #4"><button onclick="onClickItem(this);">insert under</button></item>
Then the JavaScript:
<script>
function onClickItem( clickedItem)
{
var newElement = document.createElement( "item");
newElement.innerHTML = '<input><button>insert under</button>';
if( newElement.addEventListener)
newElement.lastChild.addEventListener( "click", function() { onClickItem( newElement) });
else if( newElement.attachEvent)
newElement.lastChild.attachEvent( "onclick", function() { onClickItem( newElement) }); // for IE8 or earlier
var parentNode = clickedItem.parentNode.parentNode;
newElement = parentNode.insertBefore( newElement, clickedItem.parentNode.nextElementSibling );
}
</script>
The first two lines of the JavaScript just create the new item (I assumed you would want the same elements in the new items as in the original ones, but you can change that if you want something else).
Then it adds the same event listener as the original buttons have - that means the new item behaves the same as the originals, so that clicking on a new one creates yet another item.
Finally it uses the JavaScript insertBefore DOM method to insert the new item into the tree, referencing nextElementSibling to make sure it's inserted after the clicked item, not before. I hope this gives you what you want.
Upvotes: 0