htmlangulartypescript

Angular 16: Input box, reactive forms. Detect change and clear class


so I've got a problem. I'm new at Angular and typescript, I'm kinda new at front-end developing all together.

So, I've got a task where I need to create an input box, with the following specifications:

Now here's the issue: I'm trying to validate on change. Example,

A correct number has been added and I've got the green bar, see below:

Correct number

I have removed two numbers but the green bar is still there and I want it to go back to neutral (white) Changed input, but status (green) unchanged

So basically, I want to "reset" the textbox when I start deleting the numbers.

back to neutral state

I have no idea how to do it combined with reactive forms. I've googled and tried adding an Onchange method but for some reason I can't get it working.

BONUS: Any tips on removing the unwanted characters

Here's the code:

import { Component } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';

@Component({
  selector: 'app-about',
  templateUrl: './about.component.html',
  styleUrls: ['./about.component.scss']
})

export class AboutComponent {
  public pageTitle = "Test input box";
  submitted = false;


  custFormControl = new FormControl('', {
    validators: [Validators.required, Validators.pattern('^.{6}$|^.{8}$')],
    updateOn: 'submit'


  });
  inputFormGroup = new FormGroup({
    inputCustNo: this.custFormControl
  });



  submit(custFormControl: FormControl) {
    this.submitted = true;


    if (this.custFormControl.invalid) {

      return console.log("Bummer");
    }

    if (this.custFormControl.valid) {

      return console.log("This went well" + this.custFormControl);
    }


  }



}
<div class="card">
    <div class="card-header">
        <h2>{{pageTitle}}
        </h2>
    </div>
    <div class="card-body py-6">
        <div class="container-fluid">
            <form [formGroup]="inputFormGroup" (ngSubmit)="submit(custFormControl)">
              <div class="form-group">
                <label for="inputCustNo">Search for Data</label>
                <span class="form-info">Find Customer data</span>
                <div class="group"
                  [ngClass]="{ 'is-invalid': submitted && custFormControl.errors, 
                  'is-valid': submitted && custFormControl.valid,
                  ' ': custFormControl.invalid }">
                  <input type="number" [formControl]="custFormControl" class="form-control" id="inputCustNo"
                    placeholder="Enter Customer number" onKeyPress="if(this.value.length==8) return false;" #inputElement />
                  <button type="submit" class="btn btn-primary">
                    Search
                  </button>
                </div>
                <span class="form-info">
                  <div *ngIf="submitted && custFormControl.errors" class="invalid-feedback">
                    <div *ngIf="custFormControl.errors?.['required']">Customer number is required</div>
                    <div *ngIf="custFormControl.errors?.['pattern']">Input must be either 6 and 8 numbers long</div>
                  </div>
                </span>
              </div>
            </form>
          </div>
    </div>
</div>


Solution

  • first update your form control to change

    custFormControl = new FormControl('', {
      validators: [Validators.required, Validators.pattern('^.{6}$|^.{8}$')],
      updateOn: 'change'
    });
    

    in the constructor capture the changes

    constructor() {
      this.custFormControl.valueChanges.subscribe(value => {
        this.submitted = false;
      });
    }
    

    use the following input

    <input type="number" [formControl]="custFormControl" class="form-control" id="inputCustNo"
        placeholder="Enter Customer number" onKeyPress="if(this.value.length==8) return false;"
        (keydown)="blockCharacters($event)" #inputElement />
    

    last add the block function to your component

    blockCharacters(event: KeyboardEvent) {
      const forbiddenChars = ['e', '+', '-', '.'];
      if (forbiddenChars.includes(event.key)) {
        event.preventDefault();
      }
    }