Reputation: 1981
Hey guys I'm new to angular2
tried several ways to achieve this kind of functionality (look at jsfiddle).
What I need is on click it add active class to next element and removes from current element same vice-versa for Prev btn.so that next element will be shown and prev one will be hided. add/remove class or add remove style could work for me..or anything else that can achieve this kind of thing
I have just achieved it with jQuery.
But I just want to implement it with Angular2, anything can work for me
html:
<ul>
<li class="active">item1</li>
<li>item2</li>
<li>item3</li>
</ul>
<button class="prev">prev</button> <button class="next">Next</button>
jQuery:
$('.next').click( function(){
$('.active').next().addClass('active').prev().removeClass('active')
})
$('.prev').click( function(){
$('.active').prev().addClass('active').next().removeClass('active')
})
https://jsfiddle.net/svgmc125/
Edit:
code updated using help of @pixelbits help
now HTML will be
<li>
<my-component></my-component>
</li>
<li>
<my-component-1></my-component-1>
</li>
<li [class]="slides[selectedIndex] == slide ? 'active': ''"
*ngFor="let slide of slides">
<img src="../../assets/images/onboarding/slides/{{slide}}.png" alt="">
</li>
<li>
<my-component-2></my-component-2>
</li>
<li>
<my-component-3></my-component-3>
</li>
ts:
export class SlidesComponent{
slides: any[];
selectedIndex: number;
constructor() {
this.selectedIndex = 0;
this.slides = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15];
}
next() {
++this.selectedIndex;
}
previous() {
--this.selectedIndex;
}
}
its all working fine for looped <li>
but still have issue with remaining <li>
Upvotes: 1
Views: 10340
Reputation: 14564
Your thinking around the problem needs to be different when dealing with Angular vs jQuery. In Angular, it's helpful to think of the HTML/View as a visual reflection of your data model in code.
So, for example, let's say you have a component like:
@Component({
template: `
<ul>
<li [class.active]="current == 0">item1</li>
<li [class.active]="current == 1">item2</li>
<li [class.active]="current == 2">item3</li>
</ul>
<button class="prev" (click)="previous()">prev</button>
<button class="next" (click)="next()">Next</button>
`
})
export class ListComponent {
current = 0;
next() {
if (current == 0) {
current = 2;
} else {
current = current - 1;
}
}
next() {
current = (current + 1) % 3;
}
}
The above component will implement the functionality as you described. But more importantly is to understand what Angular is about. You should always try to envision the raw data that you're trying to display in your component, and implement logic in your component to change that data as you need. Then your template simply becomes a visual representation of your data, along with hooks to the logic to change that data based on user input.
So, in the example given, [class.active]="current == 0" says to either add or remove the active class based on whether the current variable is zero or not.
And (click)="previous()" means to call the previous method in your class whenever a click event is fired from that button.
Upvotes: 2
Reputation: 942
You can use ng-class
to apply the class active
based on the current index of the li item.
The HTML
<div ng-controller="MainController as main">
<ul>
<li ng-class="{'active' : main.active == 1}">item1</li>
<li ng-class="{'active' : main.active == 2}">item2</li>
<li ng-class="{'active' : main.active == 3}">item3</li>
</ul>
<button class="prev" ng-click="main.back()">prev</button>
<button class="next" ng-click="main.next()">Next</button>
</div>
The Controller
var app = angular.module('plunker', []);
app.controller('MainController', function() {
this.active = 1;
this.max = 3;
this.next = function(){
this.active++;
if(this.active > this.max) this.active = this.max;
}
this.back = function(){
this.active--;
if(this.active < 1) this.active = 1;
}
});
http://plnkr.co/edit/7p6IxAnGstTWVsrrR8FX?p=preview
Upvotes: -2
Reputation: 52837
You need two models in your component class: items array and the selectedIndex. Bind class
based on whether the item at the selectedIndex equals the item.
@Component({
selector: 'list',
template: `
<ul>
<li [class]="items[selectedIndex] == item ? 'active': ''"
*ngFor="let item of items">{{ item }}</li>
</ul>
`
})
class MyComponent {
items: string[];
selectedIndex: number;
constructor() {
this.selectedIndex = 0;
this.items = ["item1", "item2","item3"];
}
next() {
++this.selectedIndex;
}
previous() {
--this.selectedIndex;
}
}
Upvotes: 3
Reputation: 691625
All you need is to have, in your component, a field referencing the active item (or its index):
items: Array<string> = ['first', 'second', 'third'];
activeItem: string = items[0];
previous() {
const currentIndex = this.items.indexOf(this.activeItem);
const newIndex = currentIndex === 0 ? this.items.length - 1 : currentIndex - 1;
this.activeItem = this.items[newIndex];
}
next() {
const currentIndex = this.items.indexOf(this.activeItem);
const newIndex = currentIndex === this.items.length - 1 ? 0 : currentIndex + 1;
this.activeItem = this.items[newIndex];
}
and in the view:
<div *ngFor="let item of items" [class.active]="item === activeItem">{{ item }}</div>
Upvotes: 6
Reputation: 657048
<ul>
<li #item class="active">item1</li>
<li #item>item2</li>
<li #item>item3</li>
</ul>
@ViewChildren('item') items:QueryList<ElementRef>;
ngAfterViewInit() {
var active = this.items.toArray()
.filter(i => i.nativeElement.classList.contains('active'));
console.log(active[0].nativeElement);
}
Upvotes: 4