user4479510
user4479510

Reputation:

Angular Form Validations - values have to be different to initial values

I have reactive form validations set up as follows:

  ngOnInit(): void {
    this.userForm = this.formBuilder.group({
      status: {checked: this.selectedUser.status == 1},
      username: [this.selectedUser.username, [Validators.required, Validators.minLength(LlqaConstants.USERNAME_MIN_LENGTH)]],
      realname: [this.selectedUser.realname, [Validators.required, Validators.minLength(LlqaConstants.REALNAME_MIN_LENGTH)]],
      password: ['', this.selectedUser.passhash.length > 0 ? [Validators.required, Validators.minLength(LlqaConstants.PASSWORD_MIN_LENGTH)] : null],
      usercomment: [this.selectedUser.comment]
    });
  }

I'd like to enable the submit button, as soon as one input value is not equal to the initial value anymore. The simplest way I could find is:

disableSaveButton(): boolean {
  return !this.userform.dirty || this.userForm.invalid;
}

My problem with the dirty property ist, as soon as I enter something, dirty is true, also if I enter the same value as the initial value. I'd to have a property which tells me if one input value is not equal to the initial value. Is this possible out of the box or do I have to check each userForm.value equals to this.selectedUser.someValue?

Upvotes: 2

Views: 6386

Answers (2)

user4479510
user4479510

Reputation:

I created a custom validator to solve this issue.

The validator:

export function oneValueHasToBeChangedValidator(values: { controlName: string, initialValue: string | number | boolean }[]): ValidatorFn {
  return (form: FormControl): { [key: string]: any } => {
    let sameValues = true;

    for (let comparingValues of values) {
      if (form.value[comparingValues.controlName] != comparingValues.initialValue) {
        sameValues = false;
        break;
      }
    }

    return sameValues ? {'sameValues': {values: values}} : null;
  };
}

How I took use of it:

this.userForm = this.formBuilder.group({
  status: this.selectedUser.status == 1,
  username: [this.selectedUser.username, [Validators.required, Validators.minLength(LlqaConstants.USERNAME_MIN_LENGTH)]],
  realname: [this.selectedUser.realname, [Validators.required, Validators.minLength(LlqaConstants.REALNAME_MIN_LENGTH)]],
  password: ['', [Validators.minLength(LlqaConstants.PASSWORD_MIN_LENGTH)]],
  usercomment: this.selectedUser.comment == null ? "" : this.selectedUser.comment
});

this.userForm.setValidators(oneValueHasToBeChangedValidator([{
  controlName: "status",
  initialValue: this.selectedUser.status == 1
}, {
  controlName: "username",
  initialValue: this.selectedUser.username
}, {
  controlName: "realname",
  initialValue: this.selectedUser.realname
}, {
  controlName: "password",
  initialValue: ""
}, {
  controlName: "usercomment",
  initialValue: this.selectedUser.comment == null ? "" : this.selectedUser.comment
}]));
this.userForm.updateValueAndValidity();

Upvotes: 8

Lansana Camara
Lansana Camara

Reputation: 9873

You could cache the initial value as soon as you set the form object. Then change your disableSaveButton method to check the equality of the two values.

For instance:

export class MyComponent {
    initialValue: any;

    constructor(private fb: FormBuilder) {
        this.form = fb.group({...});
        this.initialValue = this.form.value;
    }

    disableSaveButton() {
        return JSON.stringify(this.initialValue) === JSON.stringify(this.form.value);
    }
}

The disable method will check if the current form value is the same as the initial value.

Upvotes: 0

Related Questions