Angularjs ng-repeat and child elements - javascript

I'm attempting to insert a <br/> every nth element to achieve something like this (using ng-repeat and ng-if="!($index % 2)"):
<div class="container">
<div>
<span>1</span>
<span>2</span>
<br/>
<span>3</span>
</div>
</div>
I thought I could mimic how i've used ng-repeat in the past for <ul/> elements, as so:
<div class="container">
<ul ng-repeat="item in list">
<li>{{item}}</li>
</ul>
</div>
which produces a list such as this:
<div class="container">
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
</div>
Yet when I attempt to do something like this:
<div class="container">
<div ng-repeat="item in list">
<span>{{item}}</span>
</div>
</div>
I get this differing result from the <ul/> usecase:
<div class="container">
<div>
<span>1</span>
</div>
<div>
<span>2</span>
</div>
<div>
<span>3</span>
</div>
</div>
The question is two-fold:
Why does the ng-repeat directive on a <ul/> behave differently
How can I have multiple span elements then a break without wrapping each span in a div?

https://docs.angularjs.org/api/ng/directive/ngRepeat
The ngRepeat directive instantiates a template once per item from a
collection. Each template instance gets its own scope, where the given
loop variable is set to the current collection item, and $index is set
to the item index or key.
In your loop, your 'item' has following local variables: $index, $first, $middle, $last, $even, $odd. Each except $index returns a boolean value that tells you if the item is, for example, $odd. Also take a look at the directive ngClassEven.

ng-repeat acts equal to any tag, maybe the presatantion of ul creates confusion,
look next example:
http://plnkr.co/edit/ig766DNNlQXihNS5ZGdY?p=preview
im separated:
<ul class="example-animate-container">
<li class="animate-repeat" ng-repeat="friend in friends">
and
<legeng>ul - ng repeat</legeng>
<ul class="example-animate-container" ng-repeat="friend in friends">

Try this.
<div ng-repeat="num in [1,2,3,4,5,6]">
<div>{{num}}</div>
<div ng-if="$index%2">whatever you want</div>
</div>
Result looks something like this.
1
2
whatever you want
3
4
whatever you want
5
6
whatever you want

Update:
If you want to insert a <br> every nth <span> then you can change your HTML to the following:
<div id="container">
<span ng-repeat="item in list">{{item}}
<br ng-if="$index % 2">
</span>
</div>
Tested in Firefox,Chrome,and Internet Explorer the results look like this:
12
34
56
All you have to do is remove the surrounding div elements and then change your html to the following(live preview: http://codepen.io/larryjoelane/pen/qbJXJm). The ng-repeat directive duplicates the number of child elements that are contained within the parent element. The <li> elements in your example do not contain any child elements. In other words <li> elements are child elements of the <ul> element by default. However <span> elements are not child elements of <div> elements by default. You will see similar behavior when you use ng-repeat for other elements like the <table> element and its <tr> and <td> tags.
HTML:
<div ng-app="app" ng-controller="spans">
<div id="container">
<span ng-repeat="item in list">{{item}}
</span>
</div>
</div>
Angular/JavaScript:
angular.module("app", []).controller("spans", ["$scope", function($scope) {
$scope.list = [1, 2, 3, 4, 5, 6];
}]);
And if you want each span to have a line break then apply the following CSS:
#container span {
display: block;
}

Related

Capture navigation text on click of item

I'm trying to capture using jQuery or Javascript the text value from parent classes in a site navigation
Example navigation:
Level 1 - bish
Level 2 - bash
if I click on Level 2 - 'bash' I'd like to capture level 1 text 'bish' into variable
An example of code I'm working with
`<li class="class1">
<a href="/bish" class="class2">
<div class="class3">
<p class="class4 level1">bish</p>
</div>
</a>
<ul class="class5">
<div class="class4">
<li class="class6">
<div class="class7">
bash
</div>
</li>
</ul>
</div>
</li>`
Id be grateful for any help.
I'm expecting that the value bish will output to a variable. The challenges I'm having is that because it's navigation the same class values are being used for other navigation.
For example:
$('.level2').click(function(e) {
e.preventDefault()
let level1 = $(this).closest('.class1').find('.level1').text();
console.log(level1);
});

ng-repeat within ng-repeat in angular

I have a record that is returned from an angular $resource promise like below.
The record is an array and within each array of record there another variable array. I try displaying in my view like below.
div(ng-repeat="category in categories")
h6
img(src="{{category.ImageUrl}}")
|{{category.Name}}
ul(class="list-unstyled")
li(item in category.CategoryItems)
a(href="#") {{item.Item}} (0)
The problem is , category.CategoryItems returned undefined and empty as a result even though its actually an array of objects. Please how do i print those? Each category has category items of an array type. How do i best achieve this pls?
You didn't use ng-repeat the second time. Try this:
div(ng-repeat="category in categories")
h6
img(src="{{category.ImageUrl}}")
|{{category.Name}}
ul(class="list-unstyled")
li(ng-repeat="item in category.CategoryItems") //ng-repeat added
a(href="#") {{item.Item}} (0)
I used nested ng-repeat in my project some time ago. In my project the requirement was to show all blogs like in snapshot:
To achieve this you can use ng-repeat like in below code:
<div class="panel ">
<div class="panel-body">
<div class="col-sm-12 " ng-repeat="blogBlock in blogs" >
<h2 class="hot-topics-heading">{{blogBlock.year}}</h2>
<div class="blog-year>
<div class="col-sm-6" ng-repeat="months in blogBlock.data">
<span class="hot-topics-heading">{{months.monthName}}</span>
<div class="blog-month" >
<ul class="hot-topics-ul" >
<li class="blogTitle" ng-repeat="blog in months.data">
{{blog.title}}
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
In the above code ng-repeat inside the ng-repeat and also inside the ng-repeat.
<div ng-repeat="blogBlock in blogs" >
<div ng-repeat="months in blogBlock.data">
<ul>
<li ng-repeat="blog in months.data"></li>
</ul>
</div>
</div>

ng-class to be only added if <a> exists after given element

I have a list of items that are grouped by labels, and am using filter to search through this list. The issue is that labels for lists are still showing in the search, however lists themselves are empty, hence I need to hide appropriate label. To do so I can check if anchor tag exists after my label with class .item, if it doesn't then I want to add .hidden class to the label.
I tried following, but as I am new to angular it obviously didn't work:
<div class="label" ng-class="next(a).length <= 0 ? 'hidden'">
My Label
</div>
And this is how whole group/section looks if there are items in the list:
<div class="list search-list">
<div class="label" ng-class="next(a).length <= 0 ? 'hidden'">
My Label
</div>
<a class="item> .. </a>
<!-- More a tags here -->
<div class="label" ng-class="next(a).length <= 0 ? 'hidden'">
My Label 2
</div>
<a class="item> .. </a>
<!-- More a tags here -->
</div>
I checked with inspector, relevant a tags are indeed being removed if they don't match search.
UPDATE:
added false case to ng-class, but still no luck
<div class="label" ng-class="next(a).length <= 0 ? 'hidden' : 'shown'">
My Label
</div>
UPDATE2: Full structure
<ion-view view-title="Search">
<ion-content ng-controller="SearchCtrl">
<div class="list search-bar">
<label class="item item-input">
<i class="icon ion-ios-search-strong placeholder-icon"></i>
<input type="text" placeholder="What are you looking for?" ng-model="searchFilter">
</label>
</div>
<div class="list search-list">
<!-- Group 1 -->
<div class="item item-divider" ng-class="angular.next('a').length <= 0 ? 'hidden' : 'shown'">
My Title
</div>
<a
class="item item-avatar"
href="#/app/{{item.link}}"
ng-repeat="item in items | filter:searchFilter">
<img src="img/item.png">
<h2>{{item.title}}</h2>
<p>Description</p>
</a>
<!-- Group 2 -->
<div class="item item-divider" ng-class="angular.next('a').length <= 0 ? 'hidden' : 'shown'">
My Title 2
</div>
<a
class="item item-avatar"
href="#/app/{{item2.link}}"
ng-repeat="item2 in items2 | filter:searchFilter">
<img src="img/item2.png">
<h2>{{item.title}}</h2>
<p>Description 2</p>
</a>
</div>
</ion-content>
</ion-view>
In case you want to follow the original approach of checking if there is <a/> element after your <div> you can write a custom directive. Here is one that checks for that condition:
.directive('conditionalDisplay', function() {
return {
restrict: 'A',
link: function(scope, element, attrs) {
if (element.next('a.item').length == 0)
element.css('display', 'none');
}
}
});
And here is how I used it:
<div class="list search-list">
<div conditional-display class="label">
My Label (Not Displayed, because there is no next a element)
</div>
<!--<a class="item"> .. </a>-->
<!-- More a tags here -->
<div conditional-display class="label">
My Label 2 (Displayed)
</div>
<a class="item"></a>
<!-- More a tags here -->
</div>
Here is a working plunker: http://plnkr.co/edit/ytCVxuBnbZAbX0faiQ4m?p=preview
One important thing: Make sure you include jquery for the next() selector to work. JQLite does not support next() with selectors.
Personally, I like #pgreen2 's approach. It more like angular way of doing stuff.
As described by ng-init, you could store the results of the filter and then reference like below:
<!-- Group 1 -->
<div ng-init="filteredItems = (items | filter:searchFilter)" ng-if="filteredItems">
<div class="item item-divider">
My Title
</div>
<a class="item item-avatar" href="#/app/{{item.link}}" ng-repeat="item in filteredItems">
<img src="img/item.png">
<h2>{{item.title}}</h2>
<p>Description</p>
</a>
</div>
I wrapped the whole group in a div that has ng-init which creates a variable called filteredItems that us it two other places. The first is to conditinally render the entire div using ng-if. I believe this will resolve your actual question. Secondly, I use filteredItems in the ng-repeat for the anchor tags.

How to remove last element from div?

I have list of descriptions and after remove one of them, I'd like to remove last element from div, not refreshing site. I don't know javascript in fact, so I'd like to ask how should my destroy.js.erb looks like? I can refresh whole class "descriptions" using
$('.descriptions').load(location.href + " .descriptions");
but I'm interested, if there is way to remove only last element.
<div class="descriptions">
<%= render #descriptions %>
</div>
//_description.html.erb
<div class="description-field">
<%= #description.text %>
</div>
Thank you for any help
<div class="parent">
<div class="child">
Item 1
</div>
<div class="child">
Item 2
</div>
<div class="child">
Item 3
</div>
</div>
The following line of jQuery would delete "Item 3."
$('.parent').children().last().remove();
Use css selector :last-child to remove it (found here). Then use jQuery to remove last element.
$(".yourdiv :last-child").remove();
Here is jsFiddle example:
html:
<div>
<p> Hello </p>
<p> World </p>
<p> last element </p>
</div>
JavaScript:
$("div :last-child").remove();
Use this if you want to remove the last div:
$("div:last").remove();
Use this if you want to remove the last sibling of some div with id "#mydiv"
$('#mydiv:last-child')
<div id="parent">
<div id="child">
Item 1
</div>
<div id="child">
Item 2
</div>
<div id="child">
Item 3
</div>
</div>
The following is a JQuery code that removes the last child item 3
$("#child").remove();
or you can also use
$("#child").css({"display": "none"});

AngularJS/CSS Move one div out and another in on the same modal

I am working on an app and want to use AngularJs for doing this :-
<div class="main">
<div class="one">Content 1 here ...</div>
<div class="two">Content 2 here ...</div>
</div>
div one contains a button which on click brings out div two and replaces div one.
Can anyone help regarding this, (Do i need to use ng-Animate or a better CSS trick) ?
EDIT: I will make it a little more clear
Div one has a list and a button called ADD which on click brings a list which is in div two, I select what to add and then submit, the list in div one appears updated.
Try this JS FIDDLE
HTML
<div ng-app="myApp">
<div ng-controller="listCtrl">
<div class="one">
<ul>
<li ng-repeat="list in lists">{{list}}</li>
</ul>
<button ng-click="showOptions = !showOptions">{{showOptions?'Hide':'Show'}} Options</button>
</div>
<div class="two" ng-show="showOptions">
<ul>
<li ng-repeat="list in options" ng-click="add($index)">{{list}}</li>
</ul>
</div>
</div>
Controller
var myApp = angular.module('myApp',[]);
myApp.controller('listCtrl',function($scope){
$scope.lists =['Monday','Tuesday'];
$scope.options =['Sunday','Saturday'];
$scope.add = function(index){
$scope.lists.push($scope.options[index]);
$scope.options.splice(index,1);
};
});

Categories

Resources