alarcl
alarcl

Reputation: 372

FormControl display value

How to display some text in input FormControl that not equal to value of this FormControl?

For example, get some object from a server - {id: 1, name: "Name1"}, and set value of FormControl to that object or to object.id but display value set to object.name - "Name1".

Why i need it:

I use angular material autocomplete and it set the value of FormControl to object (from selected mat-option) and display value to string via displayWith. I want to repeate this behavior when fetch data from server for some consistency and convenience

Upvotes: 10

Views: 12922

Answers (4)

Ala Mouhamed
Ala Mouhamed

Reputation: 316

I've subscribed to the formControl valueChanges observable and validate the value with a condition, and reset it if it needs to:

this.myForm.valueChanges.subscribe( value => {
  if(this.validateFormValue(value)){
    this.myForm.patchValue(this.extractValue(value))
  }
})

validateFormValue(value){
  // if condition
  return true
  // else return false
}

extractValue(value){
  // return the value you want after calculation or extraction
  return value.realValue
}

Upvotes: 0

Eliseo
Eliseo

Reputation: 57939

Another aproach is use [ngModel] and (ngModelChange) inside the FormGroup. Remember that the formControl exist always. The idea is simple. Imagine you has a FormGroup

form=new FormGroup({
   control:new FormControl()
})

<form [formGroup]="form">
   <input [ngModel]="form.get('control').value?form.get('control').value.name:''"
       (ngModelChange)="form.get('control').setValue({id:$event})"
       [ngModelOptions]="{standalone:true}">
</form>

But if you're using mat-autocomplete, by defect is asigned to the formControl the object and you can also "initialize" the formControl :(. Is the second example in the docs

Upvotes: 0

Moshe Kohavi
Moshe Kohavi

Reputation: 457

You can also just use the setValue() twice. First set the control value to the value that you want to display (view). Then set the control value again with the value that you want to save (model), but this time without changing the view, by using {emitModelToViewChange: false}

  this.form?.controls.country.setValue('Value to display')
  this.form?.controls.country.setValue('realValue', {emitModelToViewChange: false});

Upvotes: 3

alarcl
alarcl

Reputation: 372

I do some research for my question.

It is need to use FormControlDirective and its valueAccessor.writeValue() for set display value of input (it use renderer) or as alternative nativeElement.value.

And FormControl's setValue() with emitModelToViewChange = false for set FormControl value.

In template

<input [formControl]="ctrlF" #ctrlD="ngForm">

In controller

 @ViewChild('ctrlD', {read: FormControlDirective})
 ctrlD :FormControlDirective
 ...
 this.ctrlD.valueAccessor.writeValue("display value")
 this.ctrlD.control.setValue({foo: "foo", bar: "bar"}, {
     emitModelToViewChange: false
 })

planker

Upvotes: 7

Related Questions