<div class="rating">
<div style="display: inline-block"
*ngFor="let starred of stars; let i = index"
(click)="rate(i + (starred ? (value > i + 1 ? 1 : 0) : 1))">
<ng-container *ngIf="starred; else noStar"><mat-icon class="filled">star</mat-icon></ng-container>
<ng-template #noStar><mat-icon class="empty">star_outline</mat-icon></ng-template>
</div>
</div>
@Component({
selector: 'jfg-star-rating',
templateUrl: './star-rating.component.html',
styleUrls: ['./star-rating.component.scss'],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => StarRatingComponent),
multi: true
}
]
})
export class StarRatingComponent implements ControlValueAccessor{
stars: boolean[] = Array(3).fill(true);
// Allow the input to be disabled, and when it is make it somewhat transparent.
@Input() disabled = false;
@HostBinding('style.opacity')
get opacity() {
return this.disabled ? 1 : 1;
}
// Function to call when the rating changes.
onChange = (rating: number) => {
};
// Function to call when the input is touched (when a star is clicked).
onTouched = () => {
};
get value(): number {
if(!this.disabled){
return this.stars.reduce((total, starred) => {
return total + (starred ? 1 : 0);
}, 0);
}
}
rate(rating: number) {
if (!this.disabled) {
this.writeValue(rating);
}
}
// Allows Angular to update the model (rating).
// Update the model and changes needed for the view here.
writeValue(rating: number): void {
if (!this.disabled) {
this.stars = this.stars.map((_, i) => rating > i);
this.onChange(this.value);
}
}
// Allows Angular to register a function to call when the model (rating) changes.
// Save the function as a property to call later here.
registerOnChange(fn: (rating: number) => void): void {
this.onChange = fn;
}
// Allows Angular to register a function to call when the input has been touched.
// Save the function as a property to call later here.
registerOnTouched(fn: () => void): void {
this.onTouched = fn;
}
// Allows Angular to disable the input.
setDisabledState(isDisabled: boolean): void {
this.disabled = isDisabled;
}
}
Developing a star rating component that functions well as an input. The component accurately captures user ratings through star clicks which are then passed along to services. However, encountering an issue where setting the number of stars based on an input value hasn't yielded results. Seeking advice on how to proceed in effectively setting the star value from the input provided. Appreciate any suggestions!