6

I used a template driven form for my login page. I want a red border on input elements if they are invalid or have any errors but the class borderRed is not being added on an input element when the input is blank or invalid.

<form (ngSubmit)="f.form.valid && signin()" #f="ngForm" class="m-login__form m-form" action="">
  <ng-template #alertSignin></ng-template>

  <div class="form-group form-md-line-input form-md-floating-label">
    <label>
      Email <span class="text-danger">*</span>
    </label>
    <input [class.borderRed]="email.invalid" class="form-control m-input" type="text" required="required" name="email" [(ngModel)]="model.email" #email="ngModel" autocomplete="off">
  </div>

  <div class="form-group form-md-line-input form-md-floating-label">
    <label [pTooltip]="attachementTooltipmsg" tooltipPosition="top" for="form_control_1">
      Password <span class="text-danger">*</span>
    </label>
    <input [class.borderRed]="password.invalid" class="form-control m-input" required="" name="password" type="password" [(ngModel)]="model.password" #password="ngModel">
  </div>

  <div class="m-login__form-action">
    <button [disabled]="loading" [ngClass]="{'m-loader m-loader--right m-loader--light': loading}" id="m_login_signin_submit" class="btn btn-focus m-btn m-btn--pill m-btn--custom m-btn--air">
      Sign In
    </button>
  </div>
</form>
3
  • 4
    Can you provide a small repro with stackblitz? Commented Apr 30, 2018 at 6:22
  • in your password input why is required field like required="" Commented May 1, 2018 at 15:04
  • try to console log email.invalid when it should trigger a change. Commented May 1, 2018 at 16:26

7 Answers 7

3
+25

Use this

   <input [class.borderRed]="email.touched && !email.valid" class="form-control m-input" type="email" pattern="[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,3}$" required name="email" [(ngModel)]="model.email" #email="ngModel" autocomplete="off">

Check out StackBiltz

Edited code

Sign up to request clarification or add additional context in comments.

Comments

1

Angular adds some css classes when an input is valid or not. You can override the css to make it look as you want. With this approach you don't have to do [class.borderRed]=... on every input. https://angular.io/guide/forms

.ng-valid[required], .ng-valid.required  {
  border: 1px solid green;
}

.ng-invalid:not(form)  {
  border: 1px solid red;
}

Comments

0

This should work

<input [ngClass]="{'borderRed':email.invalid}" class="form-control m-input" type="text" required="required" name="email" [(ngModel)]="model.email" #email="ngModel" autocomplete="off">

2 Comments

Actually I got both methods to work - did you define border red? See this: angular-cic9xb.stackblitz.io
stackblitz.com/edit/angular-m6r5tt - ignore the other link this has the edit so you can see it working
0

For email validation add the email directive for example <input type="email" name="email" ngModel email>

Or you can use the pattern attribute, example :

<div class="form-group">
              <label for="inputEmail">Email</label>
              <input type="text"
                [ngModel] = "user.email" name="email"
                #email="ngModel" id="inputEmail"
                placeholder="Email"
                pattern="[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,3}$"
                required>
            </div>

<!-- This is the error section -->

<div *ngIf="email.invalid && (email.dirty || email.touched)"
    class="alert alert-danger">
    <div *ngIf = "email.errors?.required">
        Email field can't be blank
    </div>
    <div *ngIf = "email.errors?.pattern && email.touched">
        The email id doesn't seem right
    </div>
 </div>

Also better mark the fields required just by adding required. For password input you can use a validator like this minlength ="8".

Generally you have to specify the validations rules. In reactive forms you would specify that in the component class for example :

this.myForm = this.f.group({ name: ['', Validators.required ], });

Comments

0

You can do this. this works for me:-

<div class="form-group" [class.has-error]="fullnameControl.invalid && (fullnameControl.dirty || fullnameControl.touched)" 
        [class.has-success]="fullnameControl.valid">
            <label class="control-label">Full Name Field </label>
            <input 
                type="text" 
                required
                class="form-control" 
                name="fullname" 
                id="fullname" [(ngModel)]="fullname"
                #fullnameControl="ngModel"

            />
            <span class="help-block" 
               *ngIf="fullnameControl.invalid && (fullnameControl.dirty 
              || fullnameControl.touched)">Full Name is required. </span>
        </div>

Comments

0

Use ngClass for dynamically adding different classes. Example:

     <input class="form-control" id="firstName" name="firstName" type="text" placeholder="First Name" formControlName="firstName" [ngClass]="{
            'has-success': firstName.valid,
            'has-danger': (firstName.invalid && firstName.dirty) || (!isFormSubmitted && firstName.invalid)}">

If FirstName is invalid and dirty (user has actually touched this field), then add has-danger class.
If firstName is valid, then add has-success class.
Note: firstName is a form-control

Comments

0

To ensure that borderRed class is added to input elements when they are invalid or have any errors in an Angular template-driven form, you need to correctly bind to the ngModel directive and utilize the state properties it provides. Here’s a detailed approach to achieve this:

1 Ensure Correct Binding:

 -> Make sure your `ngModel` directives are correctly set up.

 -> Use the Angular-provided state properties `(invalid, dirty, touched)` to determine the validation state of the input fields.

2 Apply Conditional Classes: - Bind the borderRed class conditionally based on the validation state.

Here’s how you can modify your form to correctly apply the borderRed class when the inputs are invalid or have errors:

<form (ngSubmit)="f.form.valid && signin()" #f="ngForm" class="m-login__form m-form" action="">
  <ng-template #alertSignin></ng-template>

  <div class="form-group form-md-line-input form-md-floating-label">
    <label>
      Email <span class="text-danger">*</span>
    </label>
    <input [class.borderRed]="email.invalid && (email.dirty || email.touched)" 
           class="form-control m-input" 
           type="text" 
           required 
           name="email" 
           [(ngModel)]="model.email" 
           #email="ngModel" 
           autocomplete="off">
  </div>

  <div class="form-group form-md-line-input form-md-floating-label">
    <label [pTooltip]="attachementTooltipmsg" tooltipPosition="top" for="form_control_1">
      Password <span class="text-danger">*</span>
    </label>
    <input [class.borderRed]="password.invalid && (password.dirty || password.touched)" 
           class="form-control m-input" 
           required 
           name="password" 
           type="password" 
           [(ngModel)]="model.password" 
           #password="ngModel">
  </div>

  <div class="m-login__form-action">
    <button [disabled]="loading" [ngClass]="{'m-loader m-loader--right m-loader--light': loading}" id="m_login_signin_submit" class="btn btn-focus m-btn m-btn--pill m-btn--custom m-btn--air">
      Sign In
    </button>
  </div>
</form>
  1. Class Binding:
  • [class.borderRed]="email.invalid && (email.dirty || email.touched)": This binding ensures that the borderRed class is applied only when the email field is invalid and either dirty or touched.
  • [class.borderRed]="password.invalid && (password.dirty || password.touched)": Similarly, this binding ensures that the borderRed class is applied only when the password field is invalid and either dirty or touched.
  1. State Properties:
  • invalid: This property is true when the input field fails validation.
  • dirty: This property is true when the user has changed the value of the input field.
  • touched: This property is true when the user has focused on the input field and then blurred (focused out of) it.

Ensure you have the borderRed class defined in your SCSS file:

.borderRed {
  border: 1px solid red;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.