Angular-JS: ng-repeat multiple times without having a nested structure - angularjs

Is there a way for me to do a nested ng-repeat call, but not having it create a nested structure.
I.e.
Say I have this in my script:
$scope.animals = {
dog : {
rupert: {
size: 'big'
}
},
cat : {
jon: {
size: 'small'
},
don: {
size: 'small'
}
},
pig : {
mike: {
size: 'big'
}
}
}
and this in my html
<ul>
<ul ng-repeat="(type,animal) in animals">
<li ng-repeat="(name,description) in animal">
<span>
This is {{name}} the {{type}}, he is really {{description.size}}.
</span>
</li>
</ul>
</ul>
Here is a plunkr : http://plnkr.co/edit/BtAIejohzzVjrwWDfBWK?p=preview
Basically at the moment this creates something like this:
<ul>
<ul>
<li>
<span>
This is don the cat, he is really small.
</span>
</li>
<li>
<span>
This is jon the cat, he is really small.
</span>
</li>
</ul>
<ul>
<li>
<span>
This is rupert the dog, he is really big.
</span>
</li>
</ul>
<ul>
<li>
<span>
This is mike the pig, he is really big.
</span>
</li>
</ul>
</ul>
I'd like it to make something like this:
<ul>
<li>
<span>
This is don the cat, he is really small.
</span>
</li>
<li>
<span>
This is jon the cat, he is really small.
</span>
</li>
<li>
<span>
This is rupert the dog, he is really big.
</span>
</li>
<li>
<span>
This is mike the pig, he is really big.
</span>
</li>
</ul>
So is there a way to formulate this to get this result, do something of this sort (this doesn't work lol)
<ul>
<ng-repeat="(type,animal) in animals">
<li ng-repeat="(name,description) in animal">
<span>
This is {{name}} the {{type}}, he is really {{description.size}}.
</span>
</li>
</ng-repeat>
</ul>
*note I'd like to avoid doing this
<ul>
<li ng-repeat="(name,description) in animals.dog">
<span>
This is {{name}} the dog, he is really {{description.size}}.
</span>
</li>
<li ng-repeat="(name,description) in animals.cat">
<span>
This is {{name}} the cat, he is really {{description.size}}.
</span>
</li>
<li ng-repeat="(name,description) in animals.pig">
<span>
This is {{name}} the pig, he is really {{description.size}}.
</span>
</li>
</ul>

You could probably create a couple of dummy ng-repeat-start/ng-repeat-end directives for the top level repeater.
<ul>
<!-- Remove it with an ng-if -->
<li ng-repeat-start="(type,animal) in animals" ng-if="0"></li>
<!-- Or do -->
<!-- <li ng-repeat-start="(type,animal) in animals" ng-if="::type<0"></li> -->
<li ng-repeat="(name,description) in animal">
<span>
This is {{name}} the {{type}}, he is really {{description.size}}.
</span>
</li>
<!-- Remove it with an ng-if -->
<li ng-repeat-end ng-if="0"></li>
<!-- Or do -->
<!-- <li ng-repeat-end ng-if="::type<0"></li> -->
</ul>
Plnkr

Related

Smarty foreach from 0 to a number

I am trying to create a pagination on a template. I need a helping hand.
I have a total page count: $numberOfPage.
I would like to loop over it to display my pages.
However, it is a number and not an array.
I don't know how to make it loop between "1" and my total page count to create my navigation.
Here is the piece of code I created.
Thanks for any help.
<ol class="">
{foreach $numberOfPage as $page }
{dump($numberOfPage)}
{if !$page#first}
<li>
<a href="#" class="">
<span class="icon-chevron-left"></span>
Préc.
</a>
</li>
<li>
{$page-1}
</li>
{/if}
<li>
{$page}
</li>
{if !$page#last}
<li>
{$page+1}
</li>
<li>
<a href="#" class="">
Suiv.
<span class="icon-chevron-right"></span>
</a>
</li>
{/if}
{/foreach}
</ol>
Smarty provides a for function.

Ordered Lists Inside ShieldUI Accordion

Is it possible to include an ordered list inside a ShieldUI accordion? Including one seems to break my accordion; I'm hoping there is some sort of flag or work around to get ordered lists working.
<div class='accordion-container'>
<h2>Delivery Instructions</h2>
<ul id='accordion'>
<li>
<h2>Vehicle Delivery to Media / Client</h2>
<p>Accordion 1</p>
<li>Header
<ol>
<li>One</li>
<li>Two</li>
</ol>
</li>
</li>
<li>
<h2>Delivery to Airport</h2>
<p>Accordion 2</p>
</li>
</ul>
</div>
Try putting it in a DIV, like this:
<div class='accordion-container'>
<h2>Delivery Instructions</h2>
<ul id='accordion'>
<li>
<h2>Vehicle Delivery to Media / Client</h2>
<p>Accordion 1</p>
<li>
<h2>Header</h2>
<div>
<ol>
<li>One</li>
<li>Two</li>
</ol>
</div>
</li>
</li>
<li>
<h2>Delivery to Airport</h2>
<p>Accordion 2</p>
</li>
</ul>
</div>

make long css path short in selenium web driver

The CSS selector I'm using is
#menu-container > div.navbar-collapse.collapse.bs-navbar-collapse > ul:nth-child(1) > li.dropdown.open > ul > li:nth-child(1) > a > span.menu-label
Is there a way to make it shorter?
HTML
<div id="menu-container" class="navbar navbar-inverse navbar-fixed-top" role="navigation">
<div class="navbar-header">
<a class="navbar-brand">SmartStudio</a>
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".bs-navbar-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
</div>
<div class="navbar-collapse collapse bs-navbar-collapse">
<ul class="nav navbar-nav">
<li class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown">File</a>
<ul class="dropdown-menu">
<li>
<a>
<span class="pull-left"></span>
<span class="menu-label">Save</span>
<span class="pull-right">⌘ S</span>
</a>
</li>
<li>
<a>
<span class="pull-left"></span>
<span class="menu-label">Fonts</span>
</a>
</li>
<li class="divider"><span></span></li>
<li>
<a>
<span class="pull-left"></span>
<span class="menu-label">Publish</span>
</a>
</li>
</ul>
</li>
<li class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown">Edit</a>
<ul class="dropdown-menu">
<li>
<a>
<span class="pull-left"></span>
<span class="menu-label">Undo</span>
<span class="pull-right">⌘ Z</span>
</a>
</li>
<li>
<a>
<span class="pull-left"></span>
<span class="menu-label">Redo</span>
<span class="pull-right">⇧ ⌘ Z</span>
</a>
</li>
<li class="divider"><span></span></li>
<li>
<a>
<span class="pull-left"></span>
<span class="menu-label">Cut</span>
<span class="pull-right">⌘ X</span>
</a>
</li>
<li>
<a>
<span class="pull-left"></span>
<span class="menu-label">Copy</span>
<span class="pull-right">⌘ C</span>
</a>
</li>
<li>
<a>
<span class="pull-left"></span>
<span class="menu-label">Paste</span>
<span class="pull-right">⌘ V</span>
</a>
</li>
<li>
<a>
<span class="pull-left"></span> its too long to use in code. Is there a way to make it shorter in selenium web driver?
<span class="menu-label">Paste in Place</span>
<span class="pull-right">⇧ ⌘ V</span>
</a>
</li>
<li class="divider"><span></span></li>
<li class="dropdown-submenu">
<a>
<span class="pull-left"></span>
<span class="menu-label">Arrange</span>
</a>
<ul class="dropdown-menu">
<li>
<a>
<span class="pull-left"></span>
<span class="menu-label">Bring to Front</span>
<span class="pull-right">⇧ ⌘ ↑</span>
</a>
</li>
<li>
<a>
<span class="pull-left"></span>
<span class="menu-label">Bring Forward</span>
<span class="pull-right">⌘ ↑</span>
</a>
</li>
<li>
<a>
<span class="pull-left"></span>
<span class="menu-label">Send Backward</span>
<span class="pull-right">⌘ ↓</span>
</a>
</li>
<li>
<a>
<span class="pull-left"></span>
<span class="menu-label">Send to Back</span>
<span class="pull-right">⇧ ⌘ ↓</span>
</a>
</li>
</ul>
</li>
</ul>
</li>
<li class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown">View</a>
<ul class="dropdown-menu">
<li>
<a>
<span class="pull-left"></span>
<span class="menu-label">Hide Panels</span>
</a>
</li>
<li>
<a>
<span class="pull-left"></span>
<span class="menu-label">Hide Off Page Dimming</span>
</a>
</li>
</ul>
</li>
<li class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown">Panel</a>
<ul class="dropdown-menu">
<li>
<a>
<span class="pull-left icon icon-check"></span>
<span class="menu-label">Project</span>
</a>
</li>
<li>
<a>
<span class="pull-left icon icon-check"></span>
<span class="menu-label">Properties</span>
</a>
</li>
<li>
<a>
<span class="pull-left icon icon-check"></span>
<span class="menu-label">Design</span>
</a>
</li>
</ul>
</li>
<li class="dropdown open"><a class="dropdown-toggle" data-toggle="dropdown" aria-expanded="true">Help</a>
<ul class="dropdown-menu">
<li>
<a>
<span class="pull-left"></span>
<span class="menu-label">Support Resources</span>
</a>
</li>
<li>
<a>
<span class="pull-left"></span>
<span class="menu-label">Rate Us</span>
</a>
</li>
<li>
<a>
<span class="pull-left"></span>
<span class="menu-label">Suggest a Feature</span>
</a>
I think you've got several options... I'll list a couple that you can try and see if they work for you.
The super simplest way is to use the link text of the menu and then the submenu items. It may or may not work... one issue may be the uniqueness of the "Help" link on the page, there may be more than one. It looks like you will have to click the Help menu to expose the submenu that contains the "Support Resources" link.
String menuName = "Help";
String submenuName = "Support Resources";
driver.findElement(By.linkText(menuName)).click();
driver.findElement(By.linkText(submenuName)).click();
If that doesn't work, this should... or at least point you in the right direction. You will need to loop through the menus looking for the correct link text, click on it exposing the submenu, loop through the submenus looking for the correct link text, and then click on it.
String menuName = "Help";
String submenuName = "Support Resources";
List<WebElement> menus = driver.findElements(By.cssSelector("#menu-container > div > ul.nav.navbar-nav > li.dropdown"));
// List<WebElement> menus = driver.findElements(By.cssSelector("#menu-container li.dropdown")); // possible shorter alternative
for (WebElement menu : menus)
{
if (menu.getText().equals(menuName))
{
menu.click();
List<WebElement> submenus = menu.findElements(By.cssSelector("span.menu-label"));
for (WebElement submenu : submenus)
{
if (submenu.getText().equals(submenuName))
{
submenu.click();
break;
}
}
break;
}
}
This is impossible to figure out for sure without seeing the HTML you're referring to. However, it looks like you may be able to get away with this:
#menu-container span.menu-label
It looks like you're acquainted with the > operator, which selects a direct child of an element. The operator (a space) selects any descendant of an element.
This only works if there are no other spans with a class of menu-label inside of the element with the ID of menu-container. I'm assuming this is the case.
If you want a more certain answer, you'll need to provide a complete HTML file.
EDIT: Okay, now that you've provided your HTML, it's very clear what the problem is: your HTML is using styling classes, but no descriptive classes. You have two choices: adding more specific classes to your HTML elements, or just dealing with your very long selector. There are no other options.
Of course, if you choose the second option, you should store that CSS selector in a variable to give it a useful name, make it reusable, and make it easy to change when needed.

Best way to add class to link with ui-sref?

What's the best way to add a class to link that uses ui-sref="state1"?
My issue is that I have my menu outside the ui-view.
<ul>
<li>
<a data-ng-class="{active: active=='dash'}" data-ui-sref="dash">Dashboard</a>
</li>
<li>
<a data-ui-sref="reports">Reports</a>
</li>
</ul>
<div data-ui-view="main"></div>
I am trying to highlight the active link but not quite sure what the best method would be in this scenario?
You can do that using the ui-sref-active directive:
<ul>
<li>
<a ui-sref-active="active" data-ui-sref="dash">Dashboard</a>
</li>
<li>
<a data-ui-sref="reports">Reports</a>
</li>
</ul>
<div data-ui-view="main"></div>
function myFunction() {
$("[ui-sref='state1']").addClass('newClass');
}
$(document).ready(myFunction);
.newClass{
color:red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<ul>
<li>
<a data-ng-class="{active: active=='dash'}" data-ui-sref="dash">Dashboard</a>
</li>
<li>
<a data-ui-sref="reports" ui-sref='state1'>Reports</a>
</li>
</ul>
<div data-ui-view="main"></div>

How to loop only internal html/dom/content using ng-repeat?

I want to loop li with different condition and apply different html depending on that condition.
If i code this way
<ul ng-repeat="item in items">
<li ng-if="item == '1'">
<div><span> <span>My test 123</span>
{{item }}
</span></div>
</li>
<li ng-if="item == '2'">
<div><span class="xyz"> <span class="abc">My new test XXX</span>
{{item }}
</span>
<span>123</span>
</div>
</li>
</ul>
It repeat as
<ul ng-repeat="item in items">
<li>My test 123
1</li>
</ul>
<ul ng-repeat="item in items">
<li>
My new test XXX
2 123</li>
</ul>
But i want
<ul ng-repeat="item in items">
<li>My test 123
1</li>
<li>
My new test XXX
2 123</li>
</ul>
Any solution?
Thanks.
Repeat on the DOM element you want repeated?
<ul>
<li ng-repeat="item in items">{{item }}</li>
</ul>
<ul >
<li ng-repeat="item in items">{{item }}</li>
</ul>

Resources