Angular custom control - star rating - value from input
up vote
1
down vote
favorite
<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;
}
}
Im trying to make a component for star rating. I made it to work properly as an input. So i can press on the stars to get the correct value as a formControl and pass it to my services. But my problem is that i have tried to make my component to get value as an @input and set number of stars based on that value. I have tried inputing the value and setting it everywhere i could but still had no effect. If you could suggest me how can i proceed to set value form the input i would be glad :)
angular typescript angular-material
add a comment |
up vote
1
down vote
favorite
<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;
}
}
Im trying to make a component for star rating. I made it to work properly as an input. So i can press on the stars to get the correct value as a formControl and pass it to my services. But my problem is that i have tried to make my component to get value as an @input and set number of stars based on that value. I have tried inputing the value and setting it everywhere i could but still had no effect. If you could suggest me how can i proceed to set value form the input i would be glad :)
angular typescript angular-material
The only input in that is thedisabled
property?
– user184994
Nov 11 at 11:15
Beforeu, is a custom form control component. So, the logic is that work as any input, you can use < star-ratting [(ngModel)]="your_variable" /> or < star-ratting fromControlName="myControl" />
– Eliseo
Nov 11 at 11:23
add a comment |
up vote
1
down vote
favorite
up vote
1
down vote
favorite
<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;
}
}
Im trying to make a component for star rating. I made it to work properly as an input. So i can press on the stars to get the correct value as a formControl and pass it to my services. But my problem is that i have tried to make my component to get value as an @input and set number of stars based on that value. I have tried inputing the value and setting it everywhere i could but still had no effect. If you could suggest me how can i proceed to set value form the input i would be glad :)
angular typescript angular-material
<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;
}
}
Im trying to make a component for star rating. I made it to work properly as an input. So i can press on the stars to get the correct value as a formControl and pass it to my services. But my problem is that i have tried to make my component to get value as an @input and set number of stars based on that value. I have tried inputing the value and setting it everywhere i could but still had no effect. If you could suggest me how can i proceed to set value form the input i would be glad :)
angular typescript angular-material
angular typescript angular-material
edited Nov 15 at 9:55
Eluvatar
2,0291421
2,0291421
asked Nov 11 at 11:11
Beforeu
154
154
The only input in that is thedisabled
property?
– user184994
Nov 11 at 11:15
Beforeu, is a custom form control component. So, the logic is that work as any input, you can use < star-ratting [(ngModel)]="your_variable" /> or < star-ratting fromControlName="myControl" />
– Eliseo
Nov 11 at 11:23
add a comment |
The only input in that is thedisabled
property?
– user184994
Nov 11 at 11:15
Beforeu, is a custom form control component. So, the logic is that work as any input, you can use < star-ratting [(ngModel)]="your_variable" /> or < star-ratting fromControlName="myControl" />
– Eliseo
Nov 11 at 11:23
The only input in that is the
disabled
property?– user184994
Nov 11 at 11:15
The only input in that is the
disabled
property?– user184994
Nov 11 at 11:15
Beforeu, is a custom form control component. So, the logic is that work as any input, you can use < star-ratting [(ngModel)]="your_variable" /> or < star-ratting fromControlName="myControl" />
– Eliseo
Nov 11 at 11:23
Beforeu, is a custom form control component. So, the logic is that work as any input, you can use < star-ratting [(ngModel)]="your_variable" /> or < star-ratting fromControlName="myControl" />
– Eliseo
Nov 11 at 11:23
add a comment |
1 Answer
1
active
oldest
votes
up vote
2
down vote
accepted
You already have implemented ControlValueAccessor
so you should be able to set the value by ngModel
which is two binding. You don't need any other input to set the value. So you can use your StarRatingComponent
as -
<jfg-star-rating [ngModel]="3"></jfg-star-rating>
OR
<jfg-star-rating [(ngModel)]="rating"></jfg-star-rating>
Working copy is here - https://stackblitz.com/edit/angular-material-sample-vv4s6b
yep that works perectly. Thank you :)
– Beforeu
Nov 11 at 11:57
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
2
down vote
accepted
You already have implemented ControlValueAccessor
so you should be able to set the value by ngModel
which is two binding. You don't need any other input to set the value. So you can use your StarRatingComponent
as -
<jfg-star-rating [ngModel]="3"></jfg-star-rating>
OR
<jfg-star-rating [(ngModel)]="rating"></jfg-star-rating>
Working copy is here - https://stackblitz.com/edit/angular-material-sample-vv4s6b
yep that works perectly. Thank you :)
– Beforeu
Nov 11 at 11:57
add a comment |
up vote
2
down vote
accepted
You already have implemented ControlValueAccessor
so you should be able to set the value by ngModel
which is two binding. You don't need any other input to set the value. So you can use your StarRatingComponent
as -
<jfg-star-rating [ngModel]="3"></jfg-star-rating>
OR
<jfg-star-rating [(ngModel)]="rating"></jfg-star-rating>
Working copy is here - https://stackblitz.com/edit/angular-material-sample-vv4s6b
yep that works perectly. Thank you :)
– Beforeu
Nov 11 at 11:57
add a comment |
up vote
2
down vote
accepted
up vote
2
down vote
accepted
You already have implemented ControlValueAccessor
so you should be able to set the value by ngModel
which is two binding. You don't need any other input to set the value. So you can use your StarRatingComponent
as -
<jfg-star-rating [ngModel]="3"></jfg-star-rating>
OR
<jfg-star-rating [(ngModel)]="rating"></jfg-star-rating>
Working copy is here - https://stackblitz.com/edit/angular-material-sample-vv4s6b
You already have implemented ControlValueAccessor
so you should be able to set the value by ngModel
which is two binding. You don't need any other input to set the value. So you can use your StarRatingComponent
as -
<jfg-star-rating [ngModel]="3"></jfg-star-rating>
OR
<jfg-star-rating [(ngModel)]="rating"></jfg-star-rating>
Working copy is here - https://stackblitz.com/edit/angular-material-sample-vv4s6b
answered Nov 11 at 11:45
Sunil Singh
5,6461625
5,6461625
yep that works perectly. Thank you :)
– Beforeu
Nov 11 at 11:57
add a comment |
yep that works perectly. Thank you :)
– Beforeu
Nov 11 at 11:57
yep that works perectly. Thank you :)
– Beforeu
Nov 11 at 11:57
yep that works perectly. Thank you :)
– Beforeu
Nov 11 at 11:57
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53248133%2fangular-custom-control-star-rating-value-from-input%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
The only input in that is the
disabled
property?– user184994
Nov 11 at 11:15
Beforeu, is a custom form control component. So, the logic is that work as any input, you can use < star-ratting [(ngModel)]="your_variable" /> or < star-ratting fromControlName="myControl" />
– Eliseo
Nov 11 at 11:23