barteloma
barteloma

Reputation: 6865

How to create calculated field in angular reactive forms?

I have created a form in my application.

  mapForm = this.fb.group({
    name: ['', Validators.required],
    view: this.fb.group({
      width: ['', Validators.required],
      height: ['', Validators.required]
    })
  });

In this form, I am creating a JSON like following:

  {
    name: "x", 
    view:{ 
        width: "100%", 
        height: "100%" 
    } 
  }

So my form is:

<form [formGroup]="myForm" (ngSubmit)="onSubmit()">
  <label>
    First Name:
    <input type="text" formControlName="firstName" required>
  </label>

   <div formGroupName="view">
    <h3>View</h3>

        <label>
          width:
          <input type="text" formControlName="width">
        </label>

        <label>
          height:
          <input type="text" formControlName="height">
        </label>
    </div>
 </form>

But I want to seperate my view's width/height value (100) and unit (%) properties two input elements and join them in json.

    <label>
      width:
      <input type="text" formControlName="height" value="100">
    </label>
    <label>
      unit:
      <input type="text" formControlName="unit" value="%">
    </label>

But my view.width will be "100%". How can I do it?

Upvotes: 2

Views: 1381

Answers (2)

Eliseo
Eliseo

Reputation: 57939

why not, in submit?

submit(form)
{
   if (form.valid)
   {
      result={
        name:form.value.name,
        view:{
           width:form.value.width+form.value.widthUnit,
           heigth:form.value.height+form.value.heightUnit
        }
      }
      console.log(result)
   }
}

If you want to use in .html just concat, e.g.

<div [style.height]="form.value.height+form.value.heightUnit"
     [style.width]="form.value.width+form.value.widthUnit">
</div>

It's not necesary that the form ajust exactly to your json until you submit it

Upvotes: 1

Blind Despair
Blind Despair

Reputation: 3295

I can only imagine that you can create extra form control fields, then use .valueChanges with combineLatest() on the form controls you want to join and in the subscription update the values of those updated form controls. There is no such functionality from within reactive forms. However, unless you really have a reason to do this merging on the fly, it's better to just merge them when you retrieve the form value to send it somewhere.

Example:

combineLatest(
  this.form.controls.width.valueChanges(), 
  this.form.controls.unit.valueChanges()
).pipe(takeUntil(this.destroyed$)) // don't forget to have unsubscription
 .subscribe(([width, unit]) => {
   this.form.controls.combinedWidth.setValue(`${width}${unit}`);
   // if you're using onPush, also markForCheck() here
 });

You can do this right after form was initialized.

Upvotes: 0

Related Questions