Add a class to last 3 list items in AngularJS - angularjs

I have a list that is generated via ng-repeat. E.g i have the html like this
<ul class="my-list">
<li>List Item</li>
<li>List Item</li>
<li>List Item</li>
<li>List Item</li>
<li>List Item</li>
<li>List Item</li>
<li>List Item</li>
<li>List Item</li>
</ul>
I want to add a class of .last-itmes to the last 3 list items using angular. How can i do this?

In ng-repeat, Angular provides $index, $first, $last to get the index position of list item.
In your case you can use $last and substract from it like $last-1, $last-2.
Sample code :
<li ng-repeat="item in itemList"
ng-class="{'last':($index === $last) || ($index === ($last-1)) || ($index === ($last-2))}"
>List Item
</li>

Please see demo below
ie:
ng-class="{'last-itmes':$index>=data.length-3}"
var app = angular.module('app', []);
app.controller('homeCtrl', function($scope) {
$scope.data = [1, 2, 3, 4, 5, 6, 7, 8, 9]
});
.last-itmes {
color: red
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
<div ng-controller="homeCtrl">
<ul class="my-list">
<li ng-repeat="i in data" ng-class="{'last-itmes':$index>=data.length-3}">{{i}}</li>
</ul>
</div>
</div>

My suggestion is that you can go for Directives which is a neat and clean way
var app = angular.module('myApp', []);
app.controller('ArrayController', function ($scope) {
$scope.datas = ['List Item',
'List Item',
'List Item',
'List Item',
'List Item',
'List Item',
'List Item',
'List Item'];
})
.directive("itemWatch", [function () {
return {
scope: {
index: '=index',
length: '=length'
},
replace: false,
link: function ($scope, $element, $attrs, Controller) {
if ($scope.length - $scope.index <= 3) {
$element.addClass('last-itmes');
}
}
};
}]);
.last-itmes
{
color:red;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app='myApp' ng-controller="ArrayController">
<ul class="my-list">
<li ng-repeat="item in datas track by $index" index="$index" length="datas.length" item-watch>{{item}}</li>
</ul>
</div>

You can use with js object and ng-show.
var items = [
{id:1,isLast:false}
{id:2,isLast:true}
{id:3,isLast:true}
]
And your html with angularjs:
<li ng-repeat="item in items">
<div class="last-items" ng-show="item.isLast">
</li>

When setting up your ng-repeat, you can use track by $index to determine which position you are on. Doing that, you can easily do things within the repeat. To get it to add a class for just the last three items, you can put a condition on the ng-class directive like so:
<table>
<tbody ng-repeat="row in people track by $index">
<tr ng-class="{'blue': $index > people.length - 4 }">
<td>
<p style="font-weight:bold;">{{ row }}</p>
</td>
</tr>
<tbody>
</table>
I've made a plunker to show an example:
http://plnkr.co/edit/g24eYggfIRFS2El8R5Mu

Related

ng-repeat not listing different json values, instead it just displays the entire json file content in single list item

ng-repeat is not listing different json values, instead it just displays the entire json file content in single list item
codepen
html:
<div ng-app="myApp">
<div ng-controller="myCtrl" class="container">
<h2>Basic List</h2>
<ul class="list-group">
<li class="list-group-item" ng-reapeat="student">
{{student}}
</li>
</ul>
</div>
</div>
All the json file content is in here. I just need the specific data to display on each list item.
For Example,
Student One
Student Two
Student Three
Student Four
Student Five
See image for issue
JS
<script>
var app = angular.module('myApp', []);
//$.ajax({url: app, crossDomain:true, dataType: 'json', type: 'GET'})
app.controller('myCtrl', function($scope, $http){
$http.get("student.json")
// $http.get("stud.json")
.then(function(response) {
$scope.student = response.data;
});
});
</script>
json
[
{
"name" : "Student One"
},
{
"name" : "Student Two"
},
{
"name" : "Student Three"
},
{
"name" : "Student Four"
},
{
"name" : "Student Five"
}
]
Your ng-repeat should be look like, to be more on that, you are missing the proper syntax and its ng-repeat not ng-reapeat
<li class="list-group-item" ng-repeat="stu in student" >
{{stu.name}}
</li>
DEMO
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.student =
[
{
"name": "Student One"
},
{
"name": "Student Two"
},
{
"name": "Student Three"
},
{
"name": "Student Four"
},
{
"name": "Student Five"
}
];
});
<!DOCTYPE html>
<html>
<head>
</head>
<body >
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl" >
<div class="container">
<h2>Basic List</h2>
<ul class="list-group">
<li ng-repeat="stu in student" >
{{stu.name}}
</li>
</ul>
</div>
</div>
</body>
I figured it out!
I fixed the syntax of the parameter in ng-repeat attribute.
So instead of the previous :
<ul class="list-group">
<li class="list-group-item" ng-reapeat="student">
{{student}}
</li>
Before
it should be like this :
<ul class="list-group" >
<li class="list-group-item" ng-repeat="student in student" >
{{student.name}}
</li>
Result:
After

How to show object in array angular?

How to show comments in items?
This is where items save
$scope.items = [
{ 'item': 'one',
'comments':[{'comment':'comment'}]
},
{ 'item': 'two',},
{'item': 'three'}
];
<ul>
<li ng-repeat="ite in items">
{{ite.item}} {{ite.comments.length}}
<button ng click="remove($index)">Remove</button> <div ng-repeat="c in ite.comments">{{c.comment}}</div>
</li>
</ul>
http://plnkr.co/edit/19w1Q3XhoWQcpxm5SuxX?p=preview
You Just missed to add your comment Div in between the list tag. please update the code like above code. I have checked on Plunker.
<li ng-repeat="ite in items">
{{ite.item}} {{ite.comments.length}}
<button ng-click="remove($index)">Remove</button> <div ng-repeat="c in ite.comments">{{c.comment}}</div></li>

Hide and Display Subsections

I have menu with sections and subsections, like this:
Section 1
Sub 1.1
Sub 1.2
Section 2
Sub 2.1
Sub 2.2
I want to hide subsections and show one of them by clicking on section (click on Section 2):
Section 1
Section 2
Sub 2.1
Sub 2.2
Here is my code and JSFiddle:
<div ng-controller="MyCtrl">
<div ng-repeat="(meta, counts) in info">
{{ meta }}
<ul class="subsection">
<li ng-repeat="(group, cnt) in counts">
{{ group }}
</li>
</ul>
</div>
</div>
Controller:
var myApp = angular.module('myApp',[]);
//myApp.directive('myDirective', function() {});
//myApp.factory('myService', function() {});
function MyCtrl($scope) {
$scope.name = 'Superhero';
$scope.info = { "one": { "a": 1, "b": 2 },
"two" : { "c": 3, "d": 4 }};
$scope.display = function(meta) {
// ????
};
}
CSS:
ul.subsection {
display: none;
}
How can I fix this code to show one of the subsection by click on the section ?
Update: I fixed the link on JSFiddle
Since ng-repeat creates its own scope, you can simply toggle a variable within the loop, and use ng-show on that variable:
<div ng-repeat="(meta, counts) in info">
{{ meta }}
<ul class="subsection" ng-show="display">
<li ng-repeat="(group, cnt) in counts">
{{ group }}
</li>
</ul>
</div>
Edit: If you can only show one function at a time, then you can do what you were trying to do in your original code with a function:
<div ng-repeat="(meta, counts) in info">
{{ meta }}
<ul class="subsection" ng-show="sectionIndex == $index>
<li ng-repeat="(group, cnt) in counts">
{{ group }}
</li>
</ul>
</div>
$scope.display = function(index) {
$scope.sectionIndex = index;
}
You can simply do something like this:
<div ng-repeat="(meta, counts) in info">
{{meta}}
<ul class="subsection" ng-show="$parent.display == meta">
<li ng-repeat="(group, cnt) in counts">
{{ group }}
</li>
</ul>
</div>
Note, that you can refer $parent scope to avoid local scope display property.
In this case you don't need CSS rule. Bonus point is that you can set in controller $scope.display = 'two' and the second item will expand.
However cleaner way would be using a controller function as demonstrated by #tymeJV, this is the best approach.
Demo: http://plnkr.co/edit/zXeWjXLGHMv0BZZRZtud?p=preview

Two way binding is not working with angular js

I have the html code like this:
<div ng-controller="MainCtrl">
<tr data-ng-repeat="element in awesomeThings">
<div ng-if="$even">
<td ng-click="getServiceDetails(element)">
<a href="#">
{{element['serviceDetail']['name']}}
</a>
</td>
</div>
</tr>
//after some html
<span >{{publicName}}</span>
</div>
My controller looks like this:
angular.module('dcWithAngularApp')
.controller('MainCtrl', function ($scope,$http,test) {
$scope.awesomeThings = {"serviceDetail":{"name":"batman"}}
$scope.getServiceDetails = function(serviceDetails)
{
console.log('Called')
$scope.publicName = serviceDetails.name
}
});
After clicking on the td tag, the span text are not changing! Even though me changing the publicName in the current scope!
Where I'm making the mistake?
You don't have a name property in your $scope.awesomeThings array.
Here I added some animals for you.
angular.module('dcWithAngularApp')
.controller('MainCtrl', function ($scope,$http,test) {
$scope.awesomeThings = [
{ name: "Dog" },
{ name: "Cat" }
];
$scope.getServiceDetails = function(serviceDetails)
{
console.log('Called')
$scope.publicName = serviceDetails.name
}
});
Edit:
I put together a JSFiddle that solves your edit.
http://jsfiddle.net/HB7LU/7191/
$scope.awesomeThings is an array of string so element does not have a 'name' property.
You also have a missing ; after your console.log which may be stopping the code from running.
It may help you to log what the object is.
<div ng-controller="MainCtrl">
<tr data-ng-repeat="element in awesomeThings">
<div ng-if="$even">
<td ng-click="getServiceDetails(element)">
<a href="#">
{{element.name}}
</a>
</td>
</div>
</tr>
//after some html
<span >{{publicName}}</span>
</div>
angular.module('dcWithAngularApp')
.controller('MainCtrl', function ($scope,$http,test) {
$scope.awesomeThings = {"serviceDetail":{"name":"batman"}};
$scope.getServiceDetails = function(serviceDetails)
{
console.log(serviceDetails);
$scope.publicName = serviceDetails.name;
}
});
Your main issue is this:
$scope.publicName = serviceDetails.name
It needs to be
$scope.publicName = serviceDetails;
$scope.awesomeThings is an array of strings, not objects. You're ng-repeating through the string array and passing the string to your getServiceDetails method, so 'serviceDetails' is just a string.
As an unrelated warning, I see you're using tr inside a div. The tr should be inside a table, thead, or tbody.

How to use a variable inside the ng-repeat?

I'm using the ng-repeat to list all the products, and I want to print out a star symbol x times depending on the product.rating. So, the code looks like following:
<p class="bs-rating"><i class="fa fa-star" ng-repeat="i in getRating({{ product.rating }}) track by $index"></i></p>
However, it parsed the product.rating as a String: Error: [$parse:syntax] http://errors.angularjs.org/1.3.0-beta.8/$parse/syntax?p0=product.rating&p1=is
I have tried to remove the curly brackets, {{ }}:
<p class="bs-rating"><i class="fa fa-star" ng-repeat="i in getRating(product.rating) track by $index"></i></p>
It gave me undefined. My getRating() is declared as following:
$scope.getRating = function(rating){
return new Array(parseInt(rating));
}
Could you help me figure it out how to pass a variable to ng tag?
The problem is on getRating function ie on generating the array.
I have developed an alternative solution on this link rating using ng-repeat #jsfiddle
<div ng-app="myApp" ng-controller="myCtrl">
<ol>
<li ng-repeat="product in products">
{{product.name}}
(
<span style="font-weight:bold" ng-repeat="i in
getRating(product.rating)">
x
</span>
)
</li>
</ol>
var myApp = angular.module("myApp", []);
myApp.controller("myCtrl", function($scope){
$scope.products = [
{name : "product1", rating:3},
{name : "product2", rating:5},
{name : "product3", rating:1}
];
$scope.getRating = function(rating){
var ratingArray = [];
for (var i = 1; i <= rating; i++) {
ratingArray.push(i);
}
return ratingArray;
};
});
Hopefully it will help.
Cheers

Resources