Generate tag id from angularjs - javascript

I need to create a html structure as follows:
<ul>
<li id="r1_1">Root node 1
<ul>
<li id="child_node_1">Child node 1</li>
<li id="child_node_2">Child node 2</li>
<li id="child_node_3">Child node 3</li>
</ul>
</li>
<li id="r1_4">Root node 2
<ul>
<li id="child_node_4">Child node 4</li>
<li id="child_node_5">Child node 5</li>
</ul></li>
</ul> </div>
My issue is that i am unable to generate the id indexes. i need to do
this using angularjs. can someone please help? I am very new to angularjs.

As tymeJV mentioned, you can use ng-repeat and $index to do it.
Here is a working plunker with an example:
http://plnkr.co/edit/S4H08rHgpQlGhY18VkNP?p=preview
<ul>
<li ng-repeat="root in rootNodes" id="someprefix_{{calculateRootId($index)}}">
{{root.node}} calculated id: someprefix_{{calculateRootId($index)}}
<ul>
<li ng-repeat="item in root.items" id="someprefix_{{$index +1}}">Child node {{$index + 1}}</li>
</ul>
</li>
</ul>
Edit: updated plunkr to meet your requirement, note that the use of a helper function to calculate the id is very useful, BUT it would be nice to give your array items (roots and childs) an Id variable that is previously calculated on your controller and simply bind to it.
The above solution works, but I would not recommend it. I like to separate the logic from the view as much as I can, and it is a best practice to do it. Having said that, check out this other example: http://plnkr.co/edit/QsnZFlCx347nnSnkFj7W?p=preview
Here the logic of the id generation is all in the controller, so the view can bind directly to the calculated ids, and that also make it easier to change or customize even further that logic if necessary:
<ul>
<li ng-repeat="root in rootNodes" id="{{root.id}}">
{{root.name}} id: {{root.id}}
<ul>
<li ng-repeat="item in root.items" id="item.id">{{item.name}} id: {{item.id}}</li>
</ul>
</li>
</ul>
Hope that helps.

Related

Change link title with JS

how can I change the text/name(All items)of the first link using JS without adding id/classes.
<ul>
<li class="current"><a data-filter="*" href="#">All Items</a></li>
<li class="cat-item cat-item-94"> Oslavy</li>
<li class="cat-item cat-item-93">Svadby</li>
</ul>
Thanks
Grab the element with document.querySelector and then modify it's title property directly:
document.querySelector('[data-filter="*"]').title = "Banana";
<ul>
<li class="current"><a data-filter="*" href="#">All Items</a></li>
<li class="cat-item cat-item-94"> Oslavy</li>
<li class="cat-item cat-item-93">Svadby</li>
</ul>
Assuming your link that you want to change will only have its parent "current" as class and link being the first child of the parent you can try following.
window.onload = function()
{
document.getElementsByClassName('current')[0].childNodes[0].innerHTML="Hello";
}
<ul>
<li class="current"><a data-filter="*" href="#">All Items</a></li>
<li class="cat-item cat-item-94"> Oslavy</li>
<li class="cat-item cat-item-93">Svadby</li>
</ul>
Assuming that you are using jQuery, there are several ways to update the first list item, depending how your HTML was built.
If you are sure the item with the current class will always be the first :
$('ul li.current a').html('Banana');
If you prefer to rely on the order of appearance of your list item, just take the first one:
$('ul li:first-child a').html('Apple');
Notice: Be carefull not to use a too generic selector. There may be unwanted changes on your whole page. In your case, it would be better to have a clearly identifiable parent container and use it to target your list safely.

Jquery CSS- nested <li> 4 levels deep call the parent

Okay so I am stylizing a dynamic menu so I can't just assign class names or even just html code this.
Here is what I am dealing with:
I need to stylize each parent in something like this:
<div class="menu">
<ul>
<li>
Level 1
<ul>
<li>Level 2</li>
<li>Level 2
<ul>
<li>Level 3</li>
<li>Level 3</li>
<li>Level 3
<ul>
<li>Level 4</li>
<li>Level 4</li>
<li>Level 4</li>
<li>Level 4</li>
</ul>
</li>
</ul>
</li>
<li>Level 2</li>
<li>Level 2</li>
</ul>
</li>
</ul>
</div>
And I need to change all the parents with a jquery afterwards with something like:
jQuery('.menu').find('li.parent').prepend('<i class="icon-plus"></i>');
I need to change all parents with a child menu. How do I do that?
Thanks in advance
This should do the job, if I understand your question correctly:
jQuery('.menu li > ul').parent().prepend('<i class="icon-plus"></i>');
http://jsfiddle.net/Zgaj3/
I think this can work in you situation (li:parent).
jQuery('.menu').find('li:parent').prepend('<i style="" class="icon-plus"></i>');
I am not sure, if I understood your question correctly.
Anyway, the simplest solution to what I think your problem is, would be to iterate through each ul-element following a .menu and check whether the parent is a li-element and apply your styling:
jQuery('.menu').find('ul').each(function(){
if (jQuery(this).parent().is('li'))
jQuery(this).parent().prepend('<i class="icon-plus"></i>');
});
I think you'll need an if statement, something like:
if ($('.menu>ul>li>ul')){
$('.menu>ul').prepend('<i class="icon-plus"></i>');
}
Might have to do one for each level, so:
if ($('.menu>ul>li>ul>li>ul')){
$('.menu>ul>li>ul').prepend('<i class="icon-plus"></i>');
}
// return all li elements inside of the menu class
$('.menu').find('li');
this will find the 4th level and each level after that.
$('.menu').find('ul li ul li ul li ul li').each(function(index, element){
// validate that this is indeed correct
// 4th level elements and deeper
console.log(element);
// do stuff
});
Honestly its better to just use a class when constructing these html elements. Its faster and help other people read the code.
I'm not sure about your requirements, but I think you are feeling difficulty in finding LI elements which contain a UL. The following code will help you find such elements.
$('.menu li>ul').parent().addClass('node')
Now you can do the required operation on this. Please come back if further help required.
Please mark as answer if it helped you.

How do I get the 'PowerTools' plugin to work for MooTools?

Specifically, I am trying to use the Tree functionality, as can be seen here:
http://cpojer.net/MooTools/tree/Demos/# The source can be seen here:
https://github.com/cpojer/mootools-tree/blob/master/README.md
This is my HTML:
<ul class="tree" id="tree">
<div id="admin">Admin Controls</div>
<li class="selected">Test
<ul>
</ul>
</li>
<div id="admin">Admin Controls</div>
<li>Test 2
<ul>
</ul>
</li>
<div id="admin">Admin Controls</div>
<li>Top Links
<ul>
<li id="article">Link 1</li>
<li id="article">Link 2</li>
<li id="article">Link 3</li>
<li id="article">Link 4</li>
</ul>
</li>
<div id="admin">Admin Controls</div>
<li>Lame Links
<ul>
<li id="article">Link 9</li>
<li id="article">Link 10</li>
</ul>
</li>
<div id="admin">Admin Controls</div>
<li>Awesome Links
<ul>
<li id="article">Link 11</li>
<li id="article">Link 12</li>
</ul>
</li>
</ul>
I have added the Tree.js to my mootools.js core file.
This is my JS call:
window.addEvent('domready', function(){
var tree = new Tree('#tree');
tree.serialize();
});
As is, the sorting of the tree doesn't work.
Thoughts?
In the instantiation, you are passing a selector "#tree. If the tree class expects an ID, you don't use a pound sign, just "tree". In MooTools, there is a $ fn for ID lookups and a $$ fn for full selector lookups, there are various reasons they chose to separate the two.
Found this question and thought about answering.
A bit late though, but I was not member on SO when you asked this question :)
What I changed to put this working:
You need to pass just tree, the ID without the #.
Your tree has to have only <ul> and <li> elements, otherwise tree.js will not be able to drag them over normal divs.
You need unique ID's, I renamed all you id="admin" to class="admin" instead.
So you can use the javascript/mootools like:
window.addEvent('domready', function(){
var tree = new Tree('tree');
tree.serialize();
});
Demo here

Jquery list within a list menu

So I would like to build a unsorted list and and another unsorted list within it so there is a basic menu functionality.
I basically need to know how to have Jquery access the elements so when a main level item is clicked, its children show.
So for example:
<ul class="category-links">
<li>
<span>Category 1</span>
<ul class="sub-category-links">
<li>Sub-category 1</li>
<li>Sub-category 2</li>
<li>Sub-category 3</li>
</ul>
</li>
</ul>
I might have several of these. Essentially I set the subcategories to display:none and I want Jquery to allow for when I click on the "category-links", only its children are displayed.
Thanks!
You can do something like this:
$('.category-links li').click(function(){
$(this).find('.sub-category-links').show();
});

Angular ng-repeat without html element

I'm in trouble with a foreach that I need to do with Angular.
Thats's what I want to do :
<ul>
<div ng-repeat="g in groups">
<li ng-repeat="c in g.commands">{{c.text}}</li>
<li class="divider"></li>
</div>
</ul>
How can I do something like that, but in valid HTML structure ? (without a <div> between <ul> and <li>)
I see only one solution :
Replace the <div> with a <ul> and make a lot of css rules to make it like it doesn't exists
In addition, I use Angular 1.4.8.
Thanks !
You shouldn't have to alter your data structure at all. Instead just utilize the ng-repeat-start & ng-repeat-end directive. You'll have separate <ul>s but in terms of rendering, you can easily modify the CSS to make it appear to be a seamless list.
<ul ng-repeat-start="g in groups">
<li ng-repeat="c in g.commands">{{c.text}}</li>
<li ng-repeat-end class="divider"></li>
</ul>
http://codepen.io/jusopi/pen/KVZBLv
Probably the easiest way is to use a custom collection groupedCommands that is bound to the angular scope in code and contains the items in the correct order.
Then use ng-repeat-start for the enhanced repeat directive. There is a special ng-repeat-start and ng-repeat-end attribute combination that you can use for this case:
<ul>
<li ng-repeat-start="c in groupedCommands">{{c.text}}</li>
<li class="divider" ng-repeat-end></li>
</ul>
Try This one,
<ul>
<!-- ng-repeat: g in groups -->
<span ng-repeat="g in groups">
<li ng-repeat="c in g.commands">{{c.text}}</li>
<li class="divider"></li>
</span>
</ul>
This may solve your problem.
Caution : It is not a good way to use <span> between <ul> and <li>.

Categories