<!DOCTYPE html>
<html>
<head>
<title>Angular 2 Rating - Stars - Example</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- CSS file -->
<link rel="stylesheet" type="text/css" href="style.css">
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" >
<!-- IE polyfills, keep the order please -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/es6-shim/0.33.3/es6-shim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.20/system-polyfills.js"></script>
<!-- Agular 2 -->
<script src="https://code.angularjs.org/2.0.0-beta.7/angular2-polyfills.js"></script>
<script src="https://code.angularjs.org/tools/system.js"></script>
<script src="https://code.angularjs.org/tools/typescript.js"></script>
<script src="https://code.angularjs.org/2.0.0-beta.7/Rx.js"></script>
<script src="https://code.angularjs.org/2.0.0-beta.7/angular2.dev.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.12.0/moment.min.js"></script>
<!-- Config Agular 2 and Typescript -->
<script>
System.config({
transpiler: 'typescript',
typescriptOptions: { emitDecoratorMetadata: true },
packages: {'app': {defaultExtension: 'ts'}}
});
System.import('app/main')
.then(null, console.error.bind(console));
</script>
</head>
<!-- Run the application -->
<body>
<h1>Angular 2 Rating - Stars</h1>
<my-app class="container" style="display: block">Loading Sample...</my-app>
<div style="padding-top:50px">
<a target="_blank" href="http://www.angulartypescript.com/angular-2-tutorial/" title="Angular 2 Tutorial">
<img src="http://www.angulartypescript.com/wp-content/uploads/2016/03/learn-more-angular-2.png" alt="Smiley face" height="200" width="500">
</a>
<ul class="nav nav-pills nav-stacked" >
<li><a target="_blank" href="http://www.angulartypescript.com/angular-2-tutorial/" title="Angular 2 Home"> Angular 2 Tutorial </a></li>
<li><a target="_blank" href="http://www.angulartypescript.com/angular-2-introduction/">Angular 2 Introduction</a></li>
<li><a target="_blank" href="http://www.angulartypescript.com/angular-2-architecture/">Angular 2 Architecture</a></li>
<li><a target="_blank" href="http://www.angulartypescript.com/angular-2-annotations/">Angular 2 Annotations</a></li>
<li><a target="_blank" href="http://www.angulartypescript.com/angular-2-getting-started/">Angular 2 Setup</a></li>
<li><a target="_blank" href="http://www.angulartypescript.com/angular-2-hello-world/">Angular 2 Hello World</a></li>
<li><a target="_blank" href="http://www.angulartypescript.com/angular-2-components/">Angular 2 Components</a></li>
<li><a target="_blank" href="http://www.angulartypescript.com/angular-2-template-syntax/">Angular 2 Template Syntax</a></li>
<li><a target="_blank" href="http://www.angulartypescript.com/angular-2-data-binding/">Angular 2 Data Binding</a></li>
<li><a target="_blank" href="http://www.angulartypescript.com/angular-2-forms/">Angular 2 Forms</a></li>
<li><a target="_blank" href="http://www.angulartypescript.com/angular-2-formbuilder-example/">Angular 2 Formbuilder</a></li>
<li><a target="_blank" href="http://www.angulartypescript.com/angular-2-router-example/">Angular 2 Router</a></li>
<li><a target="_blank" href="http://www.angulartypescript.com/angular-2-http-example-typescript/">Angular 2 HTTP</a></li>
<li><a target="_blank" href="http://www.angulartypescript.com/angular-2-services/">Angular 2 Service</a></li>
</ul>
</div>
</body>
</html>
<!--
Copyright 2016 angulartypescript.com. All Rights Reserved.
Everyone can use this source code; don’t forget to indicate the source please:
http://www.angulartypescript.com/
-->
/* Styles go here */
/**
* Created by Tareq Boulakjar. from angulartypescript.com
*/
import {bootstrap} from 'angular2/platform/browser';
import {Angular2Rating} from './rating-example';
bootstrap(Angular2Rating);
/*
Copyright 2016 angulartypescript.com. All Rights Reserved.
Everyone can use this source code; don’t forget to indicate the source please:
http://www.angulartypescript.com/
*/
import {
Component,
OnInit, Input, Output, HostListener,
Self, EventEmitter
} from 'angular2/core';
import { NgFor, ControlValueAccessor, NgModel } from 'angular2/common';
@Component({
selector: 'rating[ngModel]',
directives: [NgFor],
template: `
<span (mouseleave)="reset()" (keydown)="onKeydown($event)" tabindex="0" role="slider" aria-valuemin="0" [attr.aria-valuemax]="range.length" [attr.aria-valuenow]="value">
<template ngFor #r [ngForOf]="range" #index="index">
<span class="sr-only">({{ index < value ? '*' : ' ' }})</span>
<i (mouseenter)="enter(index + 1)" (click)="rate(index + 1)" class="glyphicon" [ngClass]="index < value ? r.stateOn : r.stateOff" [title]="r.title" ></i>
</template>
</span>
`
})
export class Rating implements ControlValueAccessor, OnInit {
@Input() private max:number;
@Input() private stateOn:string;
@Input() private stateOff:string;
@Input() private readonly:boolean;
@Input() private titles:Array<string>;
@Input() private ratingStates:Array<{stateOn:string, stateOff:string}>;
@Output() private onHover:EventEmitter<number> = new EventEmitter();
@Output() private onLeave:EventEmitter<number> = new EventEmitter();
private range:Array<any>;
private value:number;
private preValue:number;
@HostListener('keydown', ['$event'])
private onKeydown(event:KeyboardEvent) {
if ([37, 38, 39, 40].indexOf(event.which) === -1) {
return;
}
event.preventDefault();
event.stopPropagation();
let sign = event.which === 38 || event.which === 39 ? 1 : -1;
this.rate(this.value + sign);
}
constructor(@Self() public cd:NgModel) {
cd.valueAccessor = this;
}
ngOnInit() {
this.max = typeof this.max !== 'undefined' ? this.max : 5;
this.readonly = this.readonly === true;
this.stateOn = typeof this.stateOn !== 'undefined' ? this.stateOn : 'glyphicon-star';
this.stateOff = typeof this.stateOff !== 'undefined' ? this.stateOff : 'glyphicon-star-empty';
this.titles = typeof this.titles !== 'undefined' && this.titles.length > 0 ? this.titles : ['one', 'two', 'three', 'four', 'five'];
this.range = this.buildTemplateObjects(this.ratingStates, this.max);
}
writeValue(value:number) {
if (value % 1 !== value) {
this.value = Math.round(value);
this.preValue = value;
return;
}
this.preValue = value;
this.value = value;
}
private buildTemplateObjects(ratingStates:Array<any>, max:number) {
ratingStates = ratingStates || [];
let count = ratingStates.length || max;
let result:any[] = [];
for (let i = 0; i < count; i++) {
result.push(Object.assign({
index: i,
stateOn: this.stateOn,
stateOff: this.stateOff,
title: this.titles[i] || i + 1
}, ratingStates[i] || {}));
}
return result;
}
private rate(value:number) {
if (!this.readonly && value >= 0 && value <= this.range.length) {
this.writeValue(value);
this.cd.viewToModelUpdate(value);
}
}
private enter(value:number) {
if (!this.readonly) {
this.value = value;
this.onHover.emit(value);
}
}
private reset() {
this.value = this.preValue;
this.onLeave.emit(this.value);
}
onChange = (_:any) => {
};
onTouched = () => {
};
registerOnChange(fn:(_:any) => {}):void {
this.onChange = fn;
}
registerOnTouched(fn:() => {}):void {
this.onTouched = fn;
}
}
/**
* Created by Tareq Boulakjar. from angulartypescript.com
*/
import {Component} from 'angular2/core';
import {CORE_DIRECTIVES, FORM_DIRECTIVES} from 'angular2/common';
import {Rating} from './rating.component';
/*Angular 2 Rating - Stars Example*/
@Component({
selector: 'my-app',
template: `
<h4 style="color: #00b0e8">Angular 2 Rating - Stars Example</h4>
<h5>Current Rate: <b>{{currentRate}}</b></h5>
<rating [(ngModel)]="currentRate" [max]="maxRateValue" [readonly]="isRatingReadonly"
(onHover)="overStarDoSomething($event)" (onLeave)="resetRatingStar($event)"
[titles]="['one','two','three']"></rating>
<span class="label"
[ngClass]="{'label-warning': ratingPercent<30, 'label-info': ratingPercent>=30 && ratingPercent<70, 'label-success': ratingPercent>=70}"
[ngStyle]="{display: (overStar && !isRatingReadonly) ? 'inline' : 'none'}">{{ratingPercent}}%</span>
<hr/>
<h4 style="color: #00b0e8">Angular 2 Rating With <b>Custom icons</b></h4>
<h5><b>(<i>Current Rate:</i> {{rateValueExample1}})</b></h5>
<div>
<rating [(ngModel)]="rateValueExample1" max="10" stateOn="glyphicon-heart"
stateOff="glyphicon-ok-circle"></rating>
</div>
<hr/>
<h4 style="color: #00b0e8">Angular 2 Rating With <b>Custom icons</b></h4>
<h5><b>(<i>Current Rate:</i> {{rateValueExample2}})</b></h5>
<div>
<rating [(ngModel)]="rateValueExample2" [ratingStates]="ratingStatesItems"></rating>
</div>
`,
directives: [Rating, FORM_DIRECTIVES, CORE_DIRECTIVES],
})
export class Angular2Rating {
//value used with custom icons demo above
private rateValueExample1:number = 5;
//value used with custom icons demo above
private rateValueExample2:number = 2;
//the maximum allowed value
private maxRateValue:number = 10;
//contains the current value entred by the user
//private currentRate:number = 7;
//make the rating component readonly
private isRatingReadonly:boolean = false;
private overStar:number;
private ratingPercent:number;
private _currentRate:number = 7;
private ratingStatesItems:any = [
{stateOn: 'glyphicon-ok-sign', stateOff: 'glyphicon-ok-circle'},
{stateOn: 'glyphicon-heart', stateOff: 'glyphicon-star-empty'},
{stateOn: 'glyphicon-heart', stateOff: 'glyphicon-ban-circle'},
{stateOn: 'glyphicon-heart', stateOff: 'glyphicon-ban-circle'},
{stateOn: 'glyphicon-heart', stateOff: 'glyphicon-ban-circle'}
];
//reset the rating value to null
private resetRatingStar() {
this.overStar = null;
}
//call this method when over a star
private overStarDoSomething(value:number):void {
this.overStar = value;
this.ratingPercent = 100 * (value / this.maxRateValue);
};
public get currentRate(): string {
return this._currentRate;
}
@Input()
set currentRate(rate: number) {
console.log('oude waarde: ', this._currentRate);
console.log('nieuwe waarde: ', rate);
this._currentRate = rate;
}
}