Angular 2 change ngFor items class knowing only it's index - javascript

I have a lot of buttons in my *ngFor, and I want that when someone click's on a button - it becomes active(it gets active class).
What I've done :
HTML :
<button
[ngClass]="{'activeBtn': buttActive }"
(click)="addDistrict(item);changeActive(i)"
*ngFor="let item of items; let i = index"
ion-button
#disable>
{{item.name}}
</button>
TS : (changing all buttons class to active (i want to change only that one i clicked)
buttActive = false;
changeActive(i) {
console.log(i);
this.buttActive = !this.buttActive;
}

have a buttActive property in the object and change it
button [ngClass]="{'activeBtn': item.buttActive }" (click)="addDistrict(item);changeActive(item,i)"
*ngFor="let item of items; let i = index" ion-button #disable>{{item.name}}</button>
changeActive(item, i){
console.log(i);
item.buttActive = !item.buttActive;
}

If you don't want to create a property on each item, then create a lastClickedIndex property in your Component class and set it with the index of the button that was clicked:
lastClickedIndex;
changeActive(i) {
this.lastClickedIndex = i;
}
And in your template, check for the lastClickedIndex button based on index to apply the activeBtn class.
<button
*ngFor="let item of items; let i = index"
[ngClass]="(lastClickedIndex == i) ? 'activeBtn': ''"
(click)="addDistrict(item);changeActive(i)"
ion-button
#disable>
{{item.name}}
</button>
That way you won't have to create a property on each item object. This will also take care of removing the class from the previously selected button when some other button is clicked.
Here's a StackBlitz for your ref.

Related

How to access dynamically created buttons in angular?

So, I am creating a quiz application where I have a scrollbar for questions and in that scrollbar I have buttons depending on the length of a question set. So I've created those buttons using *ngFor directive. Now what I want to do is whenever a user selects any option (mcq), the question buttons in the scrollbar should get highlighted in following way:
If user selects any option, then change the question button color to Green
If user skips the question, then change the question button color to Yellow
HTML Code for Question Scrollbar:
<div id="answer-buttons" class="ques-grid ">
<button #navBarButton *ngFor="let item of items">{{item}}</button>
</div>
I'm have tried doing it by first accessing the buttons using ViewChild in ts file and then apply some logic, but it's not working, it is only changing the color of first button
#ViewChild('navBarButton',{ static: false }) navBarButton:ElementRef
//and in some function I've tried this logic
if(this.attemptedQuestionCount[this.currentQuestionIndex]==1){
this.navBarButton.nativeElement.style.backgroundColor = "#228B22"
}
else{
this.navBarButton.nativeElement.style.backgroundColor = "#FCF55F"
}
How can I achieve my objective?
You can check for attemptedQuestionCount and change background color like this
<div id="answer-buttons" class="ques-grid ">
<button *ngFor="let question of questions; let i=index"
[style.background-color]="attemptedQuestionCount[i] === 1 ? '#228B22' : '#FCF55F'">{{question}}</button>
</div>
Add button tag as follows:
<button *ngFor="let question of questions; let i=index"
[style.background-color]="attemptedQuestionCount[i] === 1 ? '#228B22' : '#FCF55F'">{{question}}</button>
You can add the click handler directly to the button using
<button *ngFor="let item of items; let indexOfelement=index"
(click)="heyYouClicked(indexOfelement)">{{item}}</button>
And then in the component you place the handler
export class AppComponent {
items = ["hello", "world"]
heyYouClicked(index){
console.log("you clicked " + index)
}
}
You can try ngClass for simplicity.
<button #navBarButton *ngFor="let item of items" class="defualt_state" [ngClass]="{'new_state': (condition_here)}">{{item}}</button>
And in the stylesheet you can have the above class configured
.new_state { background-color: #228B22 !important }
And set the default color of the button this way
.default_state { background-color : #FCF55F}
So when the condition matches it will take the color specified in the new_state class or else will take the default color from default_state class.

How to get active class name of a button, in angular (2+)?

I need to get active class name of this button when
A) reactive form is submitted
B) when this button is clicked
HTML
<button
type="button"
[className]=" condition ? 'classA' : 'classB'
(click) = "buttonClicked($event)"
>
</button>
TS
buttonClicked(event: Event) {
console.log(event);
//get class active class name here i.e. classA or classB
}
The class is set in the view by the condition condition ? 'classA' : 'classB'. Therefore, you can just know which class is applied in your TS code by writing const classApplied = this.condition ? 'classA' : 'classB'.

Ionic 2: Add Class to Item While Removing Class From Other Items

I have a div full of buttons that, when clicked, should add a class (selected-date-item) that changes the color of the button. Immediately before that, I want to remove that class (selected-date-item) from any button that previously held that class.
CSS
.selected-date-item {
background:#272829;
color:white;
}
HTML
<button class="date-time-select" *ngFor="let chooseDate of possibleDates" (tap)="selectPickupDate(chooseDate)">{{chooseDate}}</button>
JS
selectPickupDate(selectedDate) {
this.selectedDate = selectedDate;
}
=>
Use [ngClass]-directive to set a CSS-class dynamically .
<button [ngClass]="{'selected-date-item': chooseDate == selectedDate, 'not-selected-item': chooseDate != selectedDate}" *ngFor="let chooseDate of possibleDates" (tap)="selectPickupDate(chooseDate)">{{chooseDate}}</button>
[ngClass] broken out:
[ngClass]="{'selected-date-item': chooseDate == selectedDate, 'not-selected-item': chooseDate != selectedDate}"

how to select multiple items at a time in ng2

In ng2, I want to select multiple items when i click on the item, as of now, it selecting one item where clicked, but, i want to retain already selected items as well when i click on the current selection.
html
<span class="tag" *ngFor="let selectedTagItem of tagsAvailable;let i = index" [ngClass]="{'activeTag': selectedIdx == i}" (click)="selectItem(i)">{{selectedTagItem}}</span>
ts
export class listComponent implements OnInit {
public tagsAvailable:string[] = ['Alabama', 'Alaska', 'Arizona', 'Arkansas',
'California', 'Colorado']
selectedIdx = 0;
selectItem(index):void {
this.selectedIdx = index;
}
}
plnker: http://plnkr.co/edit/7b3VUnGERBspSU1JKEXi?p=preview
this code, currently selecting only one item that i clicked, but, what i am expecting is i want to retain the last selection, previous so on.
Any help
You can also do like this.
selectItem(index,event):void {
console.log(index);
event.target.attributes.class.nodeValue="tag activeTag"
this.itemsSelected.push(this.tagsAvailable[index]);
this.itemsSelectedIndex.push(index)
}
DEMO
You should be using as below
<p><span class="tag"
*ngFor="let selectedTagItem of tagsAvailable;let i = index"
(click)="selectItem(i)">{{selectedTagItem}}</span></p>
{{itemsSelected |json}}
selectItem(index):void {
this.itemsSelected.push(index);
console.log(this.itemsSelected);
}
LIVE DEMO

Start List at the bottom

I am using Ionic 2. I have a list of items:
this.firelist = this.dataService.findMessages(this.chatItem).map(items => {
this.updateReadMessages(items);
return items.reverse();
});
Displayed in a list:
<ion-content padding class="messages-page-content">
<ion-list class="message-list">
<ion-item class="message-item" *ngFor="let item of firelist | async">
....
This works, but as you can see, I have a reverse list. So the latest item is at the bottom. As a result, I would like to start the display at the bottom.
I have tried:
window.setTimeout(()=> {this.content.scrollToBottom();}, 2000);
This works, but there is a delay on the scroll, and visually the scroll doesn't look as good as if the list could just start at the bottom, and not have to scroll.
Is this possible?
Thanks
I doubt you will find a very elegant solution for this, but you can try the following:
Try using ionViewWillEnter:
ionViewWillEnter() {
this.content.scrollToBottom(0)
}
You could also try bind to the last item of your ngFor and then fire the scroll as the last item is rendered. Something similar to this:
<ion-item class="message-item" *ngFor="let item of firelist | async; let last = last">
{{ item }}
{{ last ? doScroll() : '' }}
</ion-item>
In your component:
export class somePage{
...
constructor(...) {
setTimeout(() => {
for (let i = 0; i < 100; i++) {
this.items[i] = i
}
}, 300)
}
doScroll(){
this.content.scrollToBottom(0)
}
}

Categories

Resources