Setting values of input fields with Angular 6


Setting values of input fields with Angular 6



I've ran into some trouble setting the value of an input element using Angular.



I'm trying to set the value of dynamically created input elements in my application by this method:


copyPricingToAll(): void {
var copyValue: string = document.getElementById("priceInputGlobal").value;

this.currentItem.orderLines.forEach(orderLine => {
document.getElementById("priceInput-" + orderLine.id).setAttribute("value", copyValue);
});
}



I'm creating the rows like this:


<ng-container *ngFor="let orderLine of currentItem.orderLines let i=index">
<tr>
<td>{{getCorrectTimeString(orderLine)}}</td>
<td>{{orderLine.quantity}}</td>
<td><input id="priceInput-{{orderLine.id}}" type="number" value="{{orderLine.price}}"></td>
</tr>
</ng-container>



Unfortunately .value is not recognized as a valid operation. I'm not sure how to correctly set the value of a dynamically created element in angular. I hope someone is able to help me out with this issue.





Can you post your HTML please?
– William Moore
2 days ago





are you calling this function after the view initialization or before?
– Prachi
2 days ago





You should use ngModel property instead of value : angular.io/api/forms/NgModel
– Arthur Chennetier
2 days ago





Use [ngModel] instead of traversing the DOM, using getElementById while you can use data-binding is like using a spoon to cut your meat.
– n00dl3
2 days ago


[ngModel]


getElementById





when this function copyPricingToAll() is called?
– Surjeet Bhadauriya
2 days ago




2 Answers
2



You should use the following:


<td><input id="priceInput-{{orderLine.id}}" type="number" [(ngModel)]="orderLine.price"></td>



You will need to add the FormsModule to your app.module in the inputs section as follows:


FormsModule


app.module


inputs


import { FormsModule } from '@angular/forms';

@NgModule({
declarations: [
...
],
imports: [
BrowserModule,
FormsModule
],
..



The use of the brackets around the ngModel are as follows:


ngModel



The show that it is taking an input from your TS file. This input should be a public member variable. A one way binding from TS to HTML.




The () show that it is taking output from your HTML file to a variable in the TS file. A one way binding from HTML to TS.


()



The [()] are both (e.g. a two way binding)


[()]



See here for more information:
https://angular.io/guide/template-syntax



I would also suggest replacing id="priceInput-{{orderLine.id}}" with something like this [id]="getElementId(orderLine)" where getElementId(orderLine) returns the element Id in the TS file and can be used anywere you need to reference the element (to avoid simple bugs like calling it priceInput1 in one place and priceInput-1 in another. (if you still need to access the input by it's Id somewhere else)


id="priceInput-{{orderLine.id}}"


[id]="getElementId(orderLine)"


getElementId(orderLine)


priceInput1


priceInput-1





Thank you for your reply. How do I access the ngModel value in code?
– Mikey123
2 days ago





Hi Mikey123, because of the two-way binding the orderLine object is automatically updated when the input field is updated.
– William Moore
2 days ago


orderLine





This solved my question. Thanks for explanation and advice, I understand it now!
– Mikey123
2 days ago



As an alternate you can use reactive forms. Here is an example: https://stackblitz.com/edit/angular-pqb2xx



Template


<form [formGroup]="mainForm" ng-submit="submitForm()">
Global Price: <input type="number" formControlName="globalPrice">
<button type="button" [disabled]="mainForm.get('globalPrice').value === null" (click)="applyPriceToAll()">Apply to all</button>
<table border formArrayName="orderLines">
<ng-container *ngFor="let orderLine of orderLines let i=index" [formGroupName]="i">
<tr>
<td>{{orderLine.time | date}}</td>
<td>{{orderLine.quantity}}</td>
<td><input formControlName="price" type="number"></td>
</tr>
</ng-container>
</table>
</form>



Component


import { Component } from '@angular/core';
import { FormGroup, FormControl, FormArray } from '@angular/forms';

@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
name = 'Angular 6';
mainForm: FormGroup;
orderLines = [
{price: 10, time: new Date(), quantity: 2},
{price: 20, time: new Date(), quantity: 3},
{price: 30, time: new Date(), quantity: 3},
{price: 40, time: new Date(), quantity: 5}
]
constructor() {
this.mainForm = this.getForm();
}

getForm(): FormGroup {
return new FormGroup({
globalPrice: new FormControl(),
orderLines: new FormArray(this.orderLines.map(this.getFormGroupForLine))
})
}

getFormGroupForLine(orderLine: any): FormGroup {
return new FormGroup({
price: new FormControl(orderLine.price)
})
}

applyPriceToAll() {
const formLines = this.mainForm.get('orderLines') as FormArray;
const globalPrice = this.mainForm.get('globalPrice').value;
formLines.controls.forEach(control => control.get('price').setValue(globalPrice));
}

submitForm() {

}
}





Thanks, looks helpful!
– Mikey123
2 days ago






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Comments

Popular posts from this blog

paramiko-expect timeout is happening after executing the command

how to run turtle graphics in Colaboratory

Export result set on Dbeaver to CSV