Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular forms dirty when same as initial state

I'm using angular to create a simple input form as below.

I'm wondering if anyone knows of a way for me to track, what I would call, "true" state of dirty or not if a user changes a controls value then reverts back to original.

So on loading my "name" property = "John".

Then user deletes a character to make name property "Jon" now my contactForm is dirty.

If user places cursor back and types "h" again name = "John" my contactForm is still dirty even though is in original state?

import { FormControl } from '@angular/forms';
import { FormBuilder, AbstractControl, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';
import { ContactDetail } from './../../../models/contact-details.model';
import { Component, OnInit, Input } from '@angular/core';

@Component({
  selector: 'contact-edit-edit-body',
  templateUrl: './contact-edit-edit-body.component.html',
  styleUrls: ['./contact-edit-edit-body.component.css']
})
export class ContactEditEditBodyComponent implements OnInit {
  @Input() contact: ContactDetail = new ContactDetail(0);

  contactForm: FormGroup;
  name: AbstractControl;
  phoneNumber: AbstractControl;
  emailAddress: AbstractControl;

  constructor(fb: FormBuilder) {
    this.contactForm = fb.group({
      "name": [this.contact.name],
      "phoneNumber": [this.contact.phoneNumber],
      "emailAddress": [this.contact.emailAddress]
    });

    this.name = this.contactForm.controls['name'];
    this.phoneNumber = this.contactForm.controls['phoneNumber'];
    this.emailAddress = this.contactForm.controls['emailAddress'];
  }

  ngOnInit() {

  }
}
like image 910
CheGuevarasBeret Avatar asked Oct 12 '17 10:10

CheGuevarasBeret


1 Answers

What I can think of is a hackish ways perhaps, but it does what you want. Just have some change event that we can match if the values match:

<input formControlName="name" (input)="check(contact.name, name)"/>
check(val, formCtrl) {
  val === formCtrl.value ? formCtrl.markAsPristine() : ''
}

We can listen to form changes and then check if the objects match, and if so mark the form as pristine:

this.contactForm.valueChanges
  .subscribe(values => {
    this.isEquivalent(this.contact, values)
});

isEquivalent(a, b) {
  let aProps = Object.getOwnPropertyNames(a);
  let bProps = Object.getOwnPropertyNames(b);

  for (var i = 0; i < aProps.length; i++) {
    let propName = aProps[i];

    if (a[propName] !== b[propName]) {
        return false;
    }
  }
  this.contactForm.markAsPristine()
}

PS, I'm happy to see if someone comes up with better ideas :)

like image 170
AT82 Avatar answered Nov 06 '22 12:11

AT82