Igor Simic
4 years ago

Angular 5 star rating example


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.

Example:
https://floyk.com/en/post/angular-star-rating-example