Let's build simple five star rating widget using Angular, Angular Material and Flex layout. This star rating widget will be purely based on CSS and we will use Angular only to manipulate selected star.
So let' start, first let's create component, and module
ng g c StarRating
ng g m StarRating
In our Module file let's include needed libraries, open star-rating.module.ts and add this:
@NgModule({
declarations: [
StarRatingComponent
],
imports: [
CommonModule,
MatCardModule,
MatButtonModule,
MatIconModule,
FlexLayoutModule
],
exports: [
StarRatingComponent
]
})
Next let's create our HTML, open star-rating.component.html and add this:
<div class="star-rating-container star-rating-animation" fxLayout="row" fxLayoutAlign="start center" >
<div *ngFor="let star of stars" [ngClass]="[star.class]" (click)="selectStar(star.id)">
<mat-icon>{{star.icon}}</mat-icon>
</div>
</div>
And now, let's create our simple logic in component it self, open star-rating.component.ts
import {Component, OnInit} from '@angular/core';
@Component({
selector: 'app-star-rating',
templateUrl: './star-rating.component.html',
styleUrls: ['./star-rating.component.sass']
})
export class StarRatingComponent implements OnInit {
selectedRating = 0;
stars = [
{
id: 1,
icon: 'star',
class: 'star-gray star-hover star'
},
{
id: 2,
icon: 'star',
class: 'star-gray star-hover star'
},
{
id: 3,
icon: 'star',
class: 'star-gray star-hover star'
},
{
id: 4,
icon: 'star',
class: 'star-gray star-hover star'
},
{
id: 5,
icon: 'star',
class: 'star-gray star-hover star'
}
];
constructor() {}
ngOnInit(): void {
}
selectStar(value): void{
// prevent multiple selection
if ( this.selectedRating === 0){
this.stars.filter( (star) => {
if ( star.id <= value){
star.class = 'star-gold star';
}else{
star.class = 'star-gray star';
}
return star;
});
}
this.selectedRating = value;
}
}
And last thing, little bit of CSS:
.star
margin: 0px 0px
color: #a9a5a5
display: inline-block
cursor: pointer
transition: all .3s
transform: scale(1)
.star
mat-icon
width: 40px
height: 40px
.star-gold
color: orange
// make all stars orange
.star-rating-animation:hover .star-hover
color: orange
// make all stars right from selected gray
.star-rating-animation .star-hover:hover ~ .star-hover
color: #ddd
.star-rating-animation .star-hover:hover
transform: scale(1.3)
How does it work?
We will define array of stars object and put it in stars
which we will loop in our HTML using *ngFor
and we will add click method for each item:
<div *ngFor="let star of stars" [ngClass]="[star.class]" (click)="selectStar(star.id)">
<mat-icon>{{star.icon}}</mat-icon>
</div>
And now with little bit of css magic we will use hovering animation and when user clicks on one stars we will take the star id, replace classes to disable further selection and mark selected stars in different color in comparison with stars that are not selected. So if user select third star, we will use classes to change color of stars 1-3 while stars 4 and 5 will stay in non selected color.
But best is to see it live: