Reputation: 1173
I have edited the official Angular.io tutorial on Dynamic Forms, in order to add a form control/input field of type "number".
https://plnkr.co/edit/NslBCrFZLQnLblAqcmzV
NumberQuestion class
import { QuestionBase } from './question-base';
export class NumberQuestion extends QuestionBase<string> {
controlType = 'numberbox';
type: string;
constructor(options: {} = {}) {
super(options);
this.type = options['type'] || '';
}
}
Creating a new NumberQuestion :
//...
new NumberQuestion({
key: 'years',
label : 'Years active',
type : 'number',
order : 4
})
Template :
<div [formGroup]="form">
<label [attr.for]="question.key">{{question.label}}</label>
<div [ngSwitch]="question.controlType">
<input *ngSwitchCase="'textbox'" [formControlName]="question.key"
[id]="question.key" [type]="question.type">
<input *ngSwitchCase="'numberbox'" [formControlName]="question.key"
[id]="question.key" [type]="question.type">
<select [id]="question.key" *ngSwitchCase="'dropdown'" [formControlName]="question.key">
<option *ngFor="let opt of question.options" [value]="opt.key">{{opt.value}}</option>
</select>
</div>
<div class="errorMessage" *ngIf="!isValid">{{question.label}} is required</div>
</div>
If you click on the Load Defaults button, and then the Save button you will see that the form's value object, preserves the numeric type of the formControl 'Years active'.
But if you firstly type inside the 'Years active' control and then hit Save, you will see that the value has been transformed to string.
I understand that this is normal behavior, as described here : https://stackoverflow.com/a/35791893/2025271
I would like to know if there is a way to instruct Angular's FormControl to preserve number type inputs as "numbers", when accessing their value.
I know that i can do this manually, by using parseInt() to edit value on change, but i am trying to find if there is a built in way to do it.
Upvotes: 8
Views: 33298
Reputation: 2291
I manage to fix it by prefixing form value with a plus sign and assign to a temporary variable.
let myNumber : number = + this.form.value.myNumber;
Upvotes: 3
Reputation: 3297
as an alternative dynamic solution to your question :
myObject
in the codecreateMyObject()
that fetchs your questions one by one number
:
number
property to the object , where the key is the key of the question and the value of it is the value of the formControl
, then add the property to myObject
string
property and add it to myObject
Ts Code of DynamicFormComponent:
import { Component, Input, OnInit } from '@angular/core';
import { FormGroup } from '@angular/forms';
import { QuestionBase } from './question-base';
import { QuestionControlService } from './question-control.service';
@Component({
selector: 'app-dynamic-form',
templateUrl: './dynamic-form.component.html',
providers: [ QuestionControlService ]
})
export class DynamicFormComponent implements OnInit {
@Input() questions: QuestionBase<any>[] = [];
form: FormGroup;
payLoad = '';
myObject : any = {};
createMyObject(){
for(let question of this.questions){
let key = question.key;
if(question.type === "number"){
let tempObj : number = +this.form.value[key];
this.myObject[key] = tempObj;
}
else{
let tempObj : string = this.form.value[key];
this.myObject[key] = tempObj;
}
}
}
constructor(private qcs: QuestionControlService) { }
ngOnInit() {
this.form = this.qcs.toFormGroup(this.questions);
}
onSubmit() {
this.payLoad = JSON.stringify(this.form.value);
this.createMyObject();
}
load(){
this.form.patchValue({"firstName":"kratos","emailAddress":"[email protected]","brave":"solid","years":132});
}
}
/*
Copyright 2017 Google Inc. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/
Html Code DynamicFormComponent :
<div>
<button type="button" (click)="load()">Load Defaults</button>
<form (ngSubmit)="onSubmit()" [formGroup]="form">
<div *ngFor="let question of questions" class="form-row">
<app-question [question]="question" [form]="form"></app-question>
</div>
<div class="form-row">
<button type="submit" [disabled]="!form.valid">Save</button>
</div>
</form>
<div *ngIf="payLoad" class="form-row">
<strong>Saved the following values</strong><br>{{payLoad}}
</div>
<div *ngIf="payLoad" class="form-row">
<strong>Saved the following values</strong><br>{{myObject | json}}
</div>
</div>
Hope this will help :)
Upvotes: 0