FormControl display value

Viewed 7365

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

4 Answers

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

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});

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

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
}
Related