I want to implement the show/hide feature of the play and pause buttons on a list of tracks in angular 7. I originally got this feature partially working using angular animation, but my method would change the state of all buttons in my list instead of a single item. I've also tried using ngClass but couldn't seem to get it working right.
Below is my latest efforts. Please help me.
<mat-card class="track-box" *ngFor="let track of tracks" cdkDrag>
<div class="custom-placeholder" *cdkDragPlaceholder></div>
<span>
<mat-icon
class="play-button md-48"
[ngClass]="{'show' : track === selectedTrack}"
(click)="toggle(track)"
> play_circle_outline</mat-icon>
<mat-icon
class="pause-button md-48"
[class.selected2]="track === selectedTrack"
(click)="toggle(track)"
>pause_circle_outline</mat-icon>
</span>
I would have to disagree with #Tomato 's answer, as per my comment on his answer.
However, what I would recommend is using Angular's NgClass which is similar to ngIf. But here's the catch.
When it comes to ngIf, you're creating 2 components, hiding one and showing the other, and doing that operation over and over again. Which is not the best code practice.
However, in the case of ngClass, you're creating one component and 2 separate SCSS classes for the same component. Whenever a certain condition is satisfied, one SCSS Class gets applied, and so forth.
HTML File
<span>
<button
class="play-pause-button"
[ngClass]="toggle(track)"></button>
</span>
TS File
export class Component {
let isPlay = false;
public toggle(track: string) {
this.isPlay = !this.isPlay;
this.isPlay ? return 'play-button'; : return 'pause-button'
}
}
That way, the toggle() function will return a SCSS class name based on the current status of the button itself.
Using ngClass
You could change the shown button icon by using ngClass as following:
<mat-card class="track-box" *ngFor="let track of tracks" cdkDrag>
<div class="custom-placeholder" *cdkDragPlaceholder></div>
<span>
<mat-icon
class="md-48"
[ngClass]="{'play-button' : track != selectedTrack,
'pause-button' : track === selectedTrack}"
(click)="toggle(track)">Some output here</mat-icon>
</span>
</mat-card>
Using ngIf
You could maybe use an ngIf (docs) to show/hide the buttons, though as Chris pointed out, this creates two elements for every track in your list and could cause performance issues on a very huge list.
<mat-card class="track-box" *ngFor="let track of tracks" cdkDrag>
<div class="custom-placeholder" *cdkDragPlaceholder></div>
<span>
<mat-icon
class="play-button md-48"
*ngIf="track != selectedTrack"
(click)="toggle(track)">play_circle_outline</mat-icon>
<mat-icon
class="pause-button md-48"
*ngIf="track === selectedTrack"
(click)="toggle(track)">pause_circle_outline</mat-icon>
</span>
</mat-card>
When your selectedTrack does not equal the track, show the play-button, if it is the same track, show the pause-button.
You could also use the if-else-block for this (from the docs):
<div *ngIf="condition; else elseBlock">Content to render when condition is true.</div>
<ng-template #elseBlock>Content to render when condition is false.</ng-template>
Related
Hi I am writing a react code for a button. Here is the code:
<Button
block={true}
className={`sc-pc-action-button ${className}`.trim()}
disabled={disabled}
onClick={onClick}
> Click me
</Button>
There is a condition in which I dont need this sc-pc-action-button css.
Now this class sc-pc-action-button is hardcoded.
How can I write a CSS which tells me to ignore the contents of sc-pc-action-button and take fresh CSS I am giving.
I need a CSS solution to remove the properties. I don't need JS Solution
<Button
block={true}
className={`${someCondition ? "sc-pc-action-button" : ""} ${className}`.trim()}
disabled={disabled}
onClick={onClick}
> Click me
</Button>
I wrote some simple logic in a reusuable component to clear the value of a select input when the "x" is clicked.
select.component.ts
#Input() selectFormControlName: string;
#Input() selectAbstractControl: AbstractControl;
...
clearInput() {
this.selectAbstractControl.patchValue("");
this.selectAbstractControl.updateValueAndValidity();
}
Here's what it looks like before:
And here's what it looks like after I click the "X":
Is there a way to clear the contents without the select options opening up when doing so?
I was hoping it is just an HTML or CSS property, but I haven't found anything so far.
EDIT: Here is the full html for the select:
<mat-select
[formControlName]="selectFormControlName"
(openedChange)="isActive = $event"
>
<mat-option
*ngFor="let selection of selectionData | async"
[value]="valuePropertyName ? selection[valuePropertyName] : selection"
(click)="toggleSingleOption()"
>
{{ selection[displayPropertyName] }}
</mat-option>
</mat-select>
<button
*ngIf="includeClearButton && selectAbstractControl.value"
matSuffix
mat-icon-button
type="button"
(click)="clearInput()"
[tabindex]="tabIndex"
>
<mat-icon>close</mat-icon>
</button>
And as far as the typescript logic, it's pretty much just the clearInput() method I have shown above.
I think it is default behavior of selects and autocompletes to launch the options dropdown when clicked anywhere within the input box.
I'm wondering if there is a way to override that behavior only in the case of the "x" that clears the form value.
Try to prevent the event bubbling with $event.stopPropagation()
(click)="clearInput(); $event.stopPropagation()"
In my angular code, I am trying to assign a css color to my button and need to call a ts function to return the css class name.
I tried the following code
<button style="height: 10%" class="getColor(days.date)">{{days.date}}</button>
In my ts code,
I have something like this
getColor(item: any) {
return 'bg-green'; // define in my style.css
}
I quickly noticed that class="getColor()" does not even call the function.
I thought about ngIf and ngTemplate but not sure if that will work. I using setting to 4 different colors as indicators like default gray, blue, red, and yellow.
Any help is appreciated. Thanks.
You should use ngClass
<button style="height: 10%" [ngClass]="getColor(days.date)">{{days.date}}</button>
Repro
In order to call the function you need to use property binding like this
<button style="height: 10%" [class]="getColor(days.date)">{{days.date}}</button>
If you want to toogle classes based on a condition you can use ngClass, like in the following example:
<div [ngClass]="{
'example-class': condition;
'another-class': getColor(days.date)
}">
</div>
Or:
<div [example-class]="condition ? 'example-class' : 'other-class'"></div>
I was using routerLinkActive="active" inside the html file with routerLink=[myId] to highlight the active anchor in a ul.
Example:
<a [routerLink]="[myId]" class="list-group-item clearfix" routerLinkActive="active">
<div class="pull-left">
<h4 class="list-group-item-heading">{{someName}}</h4>
</div>
</a>
But when I remove the [routerlink]="[myId]" and replace it with a click listener (that does some calculation and then redirects the route using this.router.navigate(['/someURL', myId]) ) the routerLinkActive="active" no longer works/highlights.
Example:
<a (click)="onClick(myId)" class="list-group-item clearfix" routerLinkActive="active">
<div class="pull-left">
<h4 class="list-group-item-heading">{{someName}}</h4>
</div>
</a>
When inspecting the anchor elements using the routerLink=[myId], the style is set to:
.list-group-item.active, .list-group-item.active:focus, .list-group-item.active:hover {
z-index: 2;
color: #fff;
background-color: #337ab7;
border-color: #337ab7;
}
Is it possible to set the active anchor style in the .ts file in the onClick() function? Or is there a simpler way around this?
Highlighting a specific link in the navigation is a reflection of the current state of the app: link A is highlighted because the user is looking at page A.
You're asking how to highlight the link as the result of a click. This approach is less than ideal: you could end up highlighting the link before the new route/page is actually activated. Most importantly, if the user reloads the page or navigates to it directly because they bookmarked it, the link will NEVER be highlighted (because no one clicked it).
You need to find a way to highlight the link based on app state, NOT as the result of an action (the typical flow is: action => changes state => updates UI).
Maybe something like this:
#Component({
template: `
<a [class.active]="currentPath == 'home'">HomeComponent</a>
`
})
export class HomeComponent {
currentPath = '';
constructor(route: ActivatedRoute) {
// Retrieve current path.
this.currentPath = snapshot.url.join('');
}
}
The idea is to retrieve the current path and expose it to the template.
Like Günter suggested, you can probably find more robust code for testing the current path in routerLinkActive's source code.
I have a simple example at plunker. I have an ng-show on one element and a select as another element. The select should toggle showing/hiding the other (input) element. Initially setting the select to Yes shows the other input element as expected. Then setting the select to No does toggle the scope value to false as expected, but does not hide the input element.
I've scoured the other posts related to this and the ones I found are around having or not having {{}} on the ng-show (I don't as it should be) or not having the value on $scope (which I do). I thought is may be a $scope.apply() issue, but then why does the 1st change to Yes work? Also adding the apply still does not make the No(false) work. What am I missing?
TIA!
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.conf = {};
});
You need to check ng-show="conf.is_ieee=='true'" instead of ng-show="conf.is_ieee". Check this plunker.
<div class="col-md-4" ng-show="conf.is_ieee=='true'">
<label class="form-label">IEEE Conference ID:</label>
<input type="text" class="form-control" name="ieee-id" ng-model="conf.ieee_id"/>
</div>
http://plnkr.co/edit/MXvuhSPB0ChJyDrvPI55?p=preview