Skip to content

Commit

Permalink
fix(rating): added support of reactive forms
Browse files Browse the repository at this point in the history
fixes #298
  • Loading branch information
valorkin committed Dec 7, 2016
1 parent 433c9f8 commit 7ba357e
Showing 1 changed file with 33 additions and 35 deletions.
68 changes: 33 additions & 35 deletions src/rating/rating.component.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import {
Component, EventEmitter, HostListener, Input, OnInit, Output, Self
} from '@angular/core';
import { ControlValueAccessor, NgModel } from '@angular/forms';
import { Component, EventEmitter, HostListener, Input, OnInit, Output, forwardRef } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';

/* tslint:disable-next-line */
const KeyboardEvent = (global as any).KeyboardEvent as KeyboardEvent;

export const RATING_CONTROL_VALUE_ACCESSOR: any = {
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => RatingComponent),
multi: true
};

@Component({
/* tslint:disable */
selector: 'rating[ngModel]',
Expand All @@ -18,29 +22,28 @@ const KeyboardEvent = (global as any).KeyboardEvent as KeyboardEvent;
</template>
</span>
`,
providers: [NgModel]
providers: [RATING_CONTROL_VALUE_ACCESSOR]
})
export class RatingComponent implements ControlValueAccessor, OnInit {
@Input() public max:number;
@Input() public stateOn:string;
@Input() public stateOff:string;
@Input() public readonly:boolean;
@Input() public titles:string[];
@Input() public ratingStates:{stateOn:string, stateOff:string}[];
@Input() public max: number;
@Input() public stateOn: string;
@Input() public stateOff: string;
@Input() public readonly: boolean;
@Input() public titles: string[];
@Input() public ratingStates: {stateOn: string, stateOff: string}[];

@Output() public onHover:EventEmitter<number> = new EventEmitter<number>(false);
@Output() public onLeave:EventEmitter<number> = new EventEmitter<number>(false);
@Output() public onHover: EventEmitter<number> = new EventEmitter<number>(false);
@Output() public onLeave: EventEmitter<number> = new EventEmitter<number>(false);

public onChange:any = Function.prototype;
public onTouched:any = Function.prototype;
public onChange: any = Function.prototype;
public onTouched: any = Function.prototype;

public cd:NgModel;
public range:any[];
public value:number;
protected preValue:number;
public range: any[];
public value: number;
protected preValue: number;

@HostListener('keydown', ['$event'])
public onKeydown(event:KeyboardEvent):void {
public onKeydown(event: KeyboardEvent): void {
if ([37, 38, 39, 40].indexOf(event.which) === -1) {
return;
}
Expand All @@ -51,12 +54,7 @@ export class RatingComponent implements ControlValueAccessor, OnInit {
this.rate(this.value + sign);
}

public constructor(@Self() cd:NgModel) {
this.cd = cd;
cd.valueAccessor = this;
}

public ngOnInit():void {
public ngOnInit(): void {
this.max = typeof this.max !== 'undefined' ? this.max : 5;
this.readonly = this.readonly === true;
this.stateOn = typeof this.stateOn !== 'undefined'
Expand All @@ -72,7 +70,7 @@ export class RatingComponent implements ControlValueAccessor, OnInit {
}

// model -> view
public writeValue(value:number):void {
public writeValue(value: number): void {
if (value % 1 !== value) {
this.value = Math.round(value);
this.preValue = value;
Expand All @@ -83,37 +81,37 @@ export class RatingComponent implements ControlValueAccessor, OnInit {
this.value = value;
}

public enter(value:number):void {
public enter(value: number): void {
if (!this.readonly) {
this.value = value;
this.onHover.emit(value);
}
}

public reset():void {
public reset(): void {
this.value = this.preValue;
this.onLeave.emit(this.value);
}

public registerOnChange(fn:(_:any) => {}):void {
public registerOnChange(fn: (_: any) => {}): void {
this.onChange = fn;
}

public registerOnTouched(fn:() => {}):void {
public registerOnTouched(fn: () => {}): void {
this.onTouched = fn;
}

public rate(value:number):void {
public rate(value: number): void {
if (!this.readonly && value >= 0 && value <= this.range.length) {
this.writeValue(value);
this.cd.viewToModelUpdate(value);
this.onChange(value);
}
}

protected buildTemplateObjects(ratingStates:any[], max:number):any[] {
protected buildTemplateObjects(ratingStates: any[], max: number): any[] {
ratingStates = ratingStates || [];
let count = ratingStates.length || max;
let result:any[] = [];
let result: any[] = [];
for (let i = 0; i < count; i++) {
result.push(Object.assign({
index: i,
Expand Down

0 comments on commit 7ba357e

Please sign in to comment.