How to show mat-error once the textbox is dirty and is on focus?












2















I want to show the mat-error just after the user has started writing something on an input element. Following is my code:



<mat-form-field appearance="outline">
<mat-label>Password</mat-label>
<input matInput type="password" placeholder="Password" required [(ngModel)]='model.password' #password='ngModel' name='Password' [minlength]='requiredLength' [pattern]="passwordPattern">
<mat-error *ngIf="password.errors?.pattern">
Password must be 8 characters long, one numeric, one special character....
</mat-error>
</mat-form-field>


I want to show the error-message once the user has started typing in the input. Currently the error shows up on text-box lost-focus. I have also tried in following way:



<mat-error *ngIf="password.dirty">
<mat-error *ngIf="password.errors?.pattern">
Password must be 8 characters long, one numeric, one special character....
</mat-error>
</mat-error>


But this also produces the same behavior as before.
One possible way around would probably using mat-hint. But I don't want to show it as hint as per requirement, I need to show this as error.



By the way, I am using ng-form.



Is it possible to get the specified behavior by using mat-error on ng-form? or I need to customize the css for mat-hint to look it as like the error message?










share|improve this question

























  • Can you post the code of the component?

    – Fabian Küng
    Jan 20 at 8:33











  • @FabianKüng I have used ng-form and in my component file I have just initialized the model and other variables.

    – Tasnim Fabiha
    Jan 20 at 8:49
















2















I want to show the mat-error just after the user has started writing something on an input element. Following is my code:



<mat-form-field appearance="outline">
<mat-label>Password</mat-label>
<input matInput type="password" placeholder="Password" required [(ngModel)]='model.password' #password='ngModel' name='Password' [minlength]='requiredLength' [pattern]="passwordPattern">
<mat-error *ngIf="password.errors?.pattern">
Password must be 8 characters long, one numeric, one special character....
</mat-error>
</mat-form-field>


I want to show the error-message once the user has started typing in the input. Currently the error shows up on text-box lost-focus. I have also tried in following way:



<mat-error *ngIf="password.dirty">
<mat-error *ngIf="password.errors?.pattern">
Password must be 8 characters long, one numeric, one special character....
</mat-error>
</mat-error>


But this also produces the same behavior as before.
One possible way around would probably using mat-hint. But I don't want to show it as hint as per requirement, I need to show this as error.



By the way, I am using ng-form.



Is it possible to get the specified behavior by using mat-error on ng-form? or I need to customize the css for mat-hint to look it as like the error message?










share|improve this question

























  • Can you post the code of the component?

    – Fabian Küng
    Jan 20 at 8:33











  • @FabianKüng I have used ng-form and in my component file I have just initialized the model and other variables.

    – Tasnim Fabiha
    Jan 20 at 8:49














2












2








2


1






I want to show the mat-error just after the user has started writing something on an input element. Following is my code:



<mat-form-field appearance="outline">
<mat-label>Password</mat-label>
<input matInput type="password" placeholder="Password" required [(ngModel)]='model.password' #password='ngModel' name='Password' [minlength]='requiredLength' [pattern]="passwordPattern">
<mat-error *ngIf="password.errors?.pattern">
Password must be 8 characters long, one numeric, one special character....
</mat-error>
</mat-form-field>


I want to show the error-message once the user has started typing in the input. Currently the error shows up on text-box lost-focus. I have also tried in following way:



<mat-error *ngIf="password.dirty">
<mat-error *ngIf="password.errors?.pattern">
Password must be 8 characters long, one numeric, one special character....
</mat-error>
</mat-error>


But this also produces the same behavior as before.
One possible way around would probably using mat-hint. But I don't want to show it as hint as per requirement, I need to show this as error.



By the way, I am using ng-form.



Is it possible to get the specified behavior by using mat-error on ng-form? or I need to customize the css for mat-hint to look it as like the error message?










share|improve this question
















I want to show the mat-error just after the user has started writing something on an input element. Following is my code:



<mat-form-field appearance="outline">
<mat-label>Password</mat-label>
<input matInput type="password" placeholder="Password" required [(ngModel)]='model.password' #password='ngModel' name='Password' [minlength]='requiredLength' [pattern]="passwordPattern">
<mat-error *ngIf="password.errors?.pattern">
Password must be 8 characters long, one numeric, one special character....
</mat-error>
</mat-form-field>


I want to show the error-message once the user has started typing in the input. Currently the error shows up on text-box lost-focus. I have also tried in following way:



<mat-error *ngIf="password.dirty">
<mat-error *ngIf="password.errors?.pattern">
Password must be 8 characters long, one numeric, one special character....
</mat-error>
</mat-error>


But this also produces the same behavior as before.
One possible way around would probably using mat-hint. But I don't want to show it as hint as per requirement, I need to show this as error.



By the way, I am using ng-form.



Is it possible to get the specified behavior by using mat-error on ng-form? or I need to customize the css for mat-hint to look it as like the error message?







angular-material angular6 angular-material2






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jan 20 at 9:27







Tasnim Fabiha

















asked Jan 20 at 7:13









Tasnim FabihaTasnim Fabiha

707820




707820













  • Can you post the code of the component?

    – Fabian Küng
    Jan 20 at 8:33











  • @FabianKüng I have used ng-form and in my component file I have just initialized the model and other variables.

    – Tasnim Fabiha
    Jan 20 at 8:49



















  • Can you post the code of the component?

    – Fabian Küng
    Jan 20 at 8:33











  • @FabianKüng I have used ng-form and in my component file I have just initialized the model and other variables.

    – Tasnim Fabiha
    Jan 20 at 8:49

















Can you post the code of the component?

– Fabian Küng
Jan 20 at 8:33





Can you post the code of the component?

– Fabian Küng
Jan 20 at 8:33













@FabianKüng I have used ng-form and in my component file I have just initialized the model and other variables.

– Tasnim Fabiha
Jan 20 at 8:49





@FabianKüng I have used ng-form and in my component file I have just initialized the model and other variables.

– Tasnim Fabiha
Jan 20 at 8:49












3 Answers
3






active

oldest

votes


















1














you can do it in this way -



<mat-form-field appearance="outline">
<mat-label>Password</mat-label>
<input matInput
type="password"
placeholder="Password"
name='Password'
[ngModel]='model.password'
(ngModelChange)="onChange($event, password)"
#password='ngModel'
[minlength]='requiredLength'
[pattern]="passwordPattern"
required>
<mat-error *ngIf="password.errors?.pattern"">
Password must be 8 characters long, one numeric, one special character....
</mat-error>
</mat-form-field>


and in your component.ts add onChange() method -



onChange($event, password){
this.model.password = $event;
if(!password.control.touched){
password.control.markAsTouched();
}
}





share|improve this answer
























  • yes, this does serve the purpose. But I don't understand why I should send the event parameter and bind it from the component.ts file? as it is already bound using ngModel. is there any reason for doing that?

    – Tasnim Fabiha
    Jan 29 at 5:46



















1














If you want to trigger validation on every keystroke done by the user, you have to use a little workaround. I suggest you use a FormControl, which will then allow you to set a validator directly on that control and also listen to the changes emitted by valueChanges to mark the FormControl as touched to trigger validation (maybe there is a better solution to this?).



See the following stackblitz. Validation is done via the Validators.pattern (minimum of 8 characters, at least one letter, one number and one special character), so there is no need for a required or minimum length validator anymore.






share|improve this answer
























  • Thank you for the suggestion. upvoted it as this is definitely a way around. But actually, this is a small portion of a larger form where I needed to show the expected behavior with a minimal change throughout the whole page. The form is already developed on ng-form, converting it into FormControl would lead to change in every input throughout the page. I was looking for a solution without using FormControl,if there is any!

    – Tasnim Fabiha
    Jan 20 at 9:23





















0














This will apply the new matcher to your entire app:



dirty-error-state.matcher.ts



import {FormControl, FormGroupDirective, NgForm } from '@angular/forms';
import {ErrorStateMatcher} from '@angular/material/core';

export class DirtyErrorStateMatcher implements ErrorStateMatcher {
isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean {
return !!(control && control.invalid && (control.dirty));
}
}


app.module.ts



import { DirtyErrorStateMatcher } from 'your-path-here';
import { ErrorStateMatcher } from '@angular/material/core';

@NgModule({
...
providers: [{
provide: ErrorStateMatcher,
useClass: DirtyErrorStateMatcher
}]
})





share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54274350%2fhow-to-show-mat-error-once-the-textbox-is-dirty-and-is-on-focus%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    3 Answers
    3






    active

    oldest

    votes








    3 Answers
    3






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    1














    you can do it in this way -



    <mat-form-field appearance="outline">
    <mat-label>Password</mat-label>
    <input matInput
    type="password"
    placeholder="Password"
    name='Password'
    [ngModel]='model.password'
    (ngModelChange)="onChange($event, password)"
    #password='ngModel'
    [minlength]='requiredLength'
    [pattern]="passwordPattern"
    required>
    <mat-error *ngIf="password.errors?.pattern"">
    Password must be 8 characters long, one numeric, one special character....
    </mat-error>
    </mat-form-field>


    and in your component.ts add onChange() method -



    onChange($event, password){
    this.model.password = $event;
    if(!password.control.touched){
    password.control.markAsTouched();
    }
    }





    share|improve this answer
























    • yes, this does serve the purpose. But I don't understand why I should send the event parameter and bind it from the component.ts file? as it is already bound using ngModel. is there any reason for doing that?

      – Tasnim Fabiha
      Jan 29 at 5:46
















    1














    you can do it in this way -



    <mat-form-field appearance="outline">
    <mat-label>Password</mat-label>
    <input matInput
    type="password"
    placeholder="Password"
    name='Password'
    [ngModel]='model.password'
    (ngModelChange)="onChange($event, password)"
    #password='ngModel'
    [minlength]='requiredLength'
    [pattern]="passwordPattern"
    required>
    <mat-error *ngIf="password.errors?.pattern"">
    Password must be 8 characters long, one numeric, one special character....
    </mat-error>
    </mat-form-field>


    and in your component.ts add onChange() method -



    onChange($event, password){
    this.model.password = $event;
    if(!password.control.touched){
    password.control.markAsTouched();
    }
    }





    share|improve this answer
























    • yes, this does serve the purpose. But I don't understand why I should send the event parameter and bind it from the component.ts file? as it is already bound using ngModel. is there any reason for doing that?

      – Tasnim Fabiha
      Jan 29 at 5:46














    1












    1








    1







    you can do it in this way -



    <mat-form-field appearance="outline">
    <mat-label>Password</mat-label>
    <input matInput
    type="password"
    placeholder="Password"
    name='Password'
    [ngModel]='model.password'
    (ngModelChange)="onChange($event, password)"
    #password='ngModel'
    [minlength]='requiredLength'
    [pattern]="passwordPattern"
    required>
    <mat-error *ngIf="password.errors?.pattern"">
    Password must be 8 characters long, one numeric, one special character....
    </mat-error>
    </mat-form-field>


    and in your component.ts add onChange() method -



    onChange($event, password){
    this.model.password = $event;
    if(!password.control.touched){
    password.control.markAsTouched();
    }
    }





    share|improve this answer













    you can do it in this way -



    <mat-form-field appearance="outline">
    <mat-label>Password</mat-label>
    <input matInput
    type="password"
    placeholder="Password"
    name='Password'
    [ngModel]='model.password'
    (ngModelChange)="onChange($event, password)"
    #password='ngModel'
    [minlength]='requiredLength'
    [pattern]="passwordPattern"
    required>
    <mat-error *ngIf="password.errors?.pattern"">
    Password must be 8 characters long, one numeric, one special character....
    </mat-error>
    </mat-form-field>


    and in your component.ts add onChange() method -



    onChange($event, password){
    this.model.password = $event;
    if(!password.control.touched){
    password.control.markAsTouched();
    }
    }






    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Jan 28 at 16:53









    Sadid KhanSadid Khan

    986824




    986824













    • yes, this does serve the purpose. But I don't understand why I should send the event parameter and bind it from the component.ts file? as it is already bound using ngModel. is there any reason for doing that?

      – Tasnim Fabiha
      Jan 29 at 5:46



















    • yes, this does serve the purpose. But I don't understand why I should send the event parameter and bind it from the component.ts file? as it is already bound using ngModel. is there any reason for doing that?

      – Tasnim Fabiha
      Jan 29 at 5:46

















    yes, this does serve the purpose. But I don't understand why I should send the event parameter and bind it from the component.ts file? as it is already bound using ngModel. is there any reason for doing that?

    – Tasnim Fabiha
    Jan 29 at 5:46





    yes, this does serve the purpose. But I don't understand why I should send the event parameter and bind it from the component.ts file? as it is already bound using ngModel. is there any reason for doing that?

    – Tasnim Fabiha
    Jan 29 at 5:46













    1














    If you want to trigger validation on every keystroke done by the user, you have to use a little workaround. I suggest you use a FormControl, which will then allow you to set a validator directly on that control and also listen to the changes emitted by valueChanges to mark the FormControl as touched to trigger validation (maybe there is a better solution to this?).



    See the following stackblitz. Validation is done via the Validators.pattern (minimum of 8 characters, at least one letter, one number and one special character), so there is no need for a required or minimum length validator anymore.






    share|improve this answer
























    • Thank you for the suggestion. upvoted it as this is definitely a way around. But actually, this is a small portion of a larger form where I needed to show the expected behavior with a minimal change throughout the whole page. The form is already developed on ng-form, converting it into FormControl would lead to change in every input throughout the page. I was looking for a solution without using FormControl,if there is any!

      – Tasnim Fabiha
      Jan 20 at 9:23


















    1














    If you want to trigger validation on every keystroke done by the user, you have to use a little workaround. I suggest you use a FormControl, which will then allow you to set a validator directly on that control and also listen to the changes emitted by valueChanges to mark the FormControl as touched to trigger validation (maybe there is a better solution to this?).



    See the following stackblitz. Validation is done via the Validators.pattern (minimum of 8 characters, at least one letter, one number and one special character), so there is no need for a required or minimum length validator anymore.






    share|improve this answer
























    • Thank you for the suggestion. upvoted it as this is definitely a way around. But actually, this is a small portion of a larger form where I needed to show the expected behavior with a minimal change throughout the whole page. The form is already developed on ng-form, converting it into FormControl would lead to change in every input throughout the page. I was looking for a solution without using FormControl,if there is any!

      – Tasnim Fabiha
      Jan 20 at 9:23
















    1












    1








    1







    If you want to trigger validation on every keystroke done by the user, you have to use a little workaround. I suggest you use a FormControl, which will then allow you to set a validator directly on that control and also listen to the changes emitted by valueChanges to mark the FormControl as touched to trigger validation (maybe there is a better solution to this?).



    See the following stackblitz. Validation is done via the Validators.pattern (minimum of 8 characters, at least one letter, one number and one special character), so there is no need for a required or minimum length validator anymore.






    share|improve this answer













    If you want to trigger validation on every keystroke done by the user, you have to use a little workaround. I suggest you use a FormControl, which will then allow you to set a validator directly on that control and also listen to the changes emitted by valueChanges to mark the FormControl as touched to trigger validation (maybe there is a better solution to this?).



    See the following stackblitz. Validation is done via the Validators.pattern (minimum of 8 characters, at least one letter, one number and one special character), so there is no need for a required or minimum length validator anymore.







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Jan 20 at 9:16









    Fabian KüngFabian Küng

    1,336616




    1,336616













    • Thank you for the suggestion. upvoted it as this is definitely a way around. But actually, this is a small portion of a larger form where I needed to show the expected behavior with a minimal change throughout the whole page. The form is already developed on ng-form, converting it into FormControl would lead to change in every input throughout the page. I was looking for a solution without using FormControl,if there is any!

      – Tasnim Fabiha
      Jan 20 at 9:23





















    • Thank you for the suggestion. upvoted it as this is definitely a way around. But actually, this is a small portion of a larger form where I needed to show the expected behavior with a minimal change throughout the whole page. The form is already developed on ng-form, converting it into FormControl would lead to change in every input throughout the page. I was looking for a solution without using FormControl,if there is any!

      – Tasnim Fabiha
      Jan 20 at 9:23



















    Thank you for the suggestion. upvoted it as this is definitely a way around. But actually, this is a small portion of a larger form where I needed to show the expected behavior with a minimal change throughout the whole page. The form is already developed on ng-form, converting it into FormControl would lead to change in every input throughout the page. I was looking for a solution without using FormControl,if there is any!

    – Tasnim Fabiha
    Jan 20 at 9:23







    Thank you for the suggestion. upvoted it as this is definitely a way around. But actually, this is a small portion of a larger form where I needed to show the expected behavior with a minimal change throughout the whole page. The form is already developed on ng-form, converting it into FormControl would lead to change in every input throughout the page. I was looking for a solution without using FormControl,if there is any!

    – Tasnim Fabiha
    Jan 20 at 9:23













    0














    This will apply the new matcher to your entire app:



    dirty-error-state.matcher.ts



    import {FormControl, FormGroupDirective, NgForm } from '@angular/forms';
    import {ErrorStateMatcher} from '@angular/material/core';

    export class DirtyErrorStateMatcher implements ErrorStateMatcher {
    isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean {
    return !!(control && control.invalid && (control.dirty));
    }
    }


    app.module.ts



    import { DirtyErrorStateMatcher } from 'your-path-here';
    import { ErrorStateMatcher } from '@angular/material/core';

    @NgModule({
    ...
    providers: [{
    provide: ErrorStateMatcher,
    useClass: DirtyErrorStateMatcher
    }]
    })





    share|improve this answer




























      0














      This will apply the new matcher to your entire app:



      dirty-error-state.matcher.ts



      import {FormControl, FormGroupDirective, NgForm } from '@angular/forms';
      import {ErrorStateMatcher} from '@angular/material/core';

      export class DirtyErrorStateMatcher implements ErrorStateMatcher {
      isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean {
      return !!(control && control.invalid && (control.dirty));
      }
      }


      app.module.ts



      import { DirtyErrorStateMatcher } from 'your-path-here';
      import { ErrorStateMatcher } from '@angular/material/core';

      @NgModule({
      ...
      providers: [{
      provide: ErrorStateMatcher,
      useClass: DirtyErrorStateMatcher
      }]
      })





      share|improve this answer


























        0












        0








        0







        This will apply the new matcher to your entire app:



        dirty-error-state.matcher.ts



        import {FormControl, FormGroupDirective, NgForm } from '@angular/forms';
        import {ErrorStateMatcher} from '@angular/material/core';

        export class DirtyErrorStateMatcher implements ErrorStateMatcher {
        isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean {
        return !!(control && control.invalid && (control.dirty));
        }
        }


        app.module.ts



        import { DirtyErrorStateMatcher } from 'your-path-here';
        import { ErrorStateMatcher } from '@angular/material/core';

        @NgModule({
        ...
        providers: [{
        provide: ErrorStateMatcher,
        useClass: DirtyErrorStateMatcher
        }]
        })





        share|improve this answer













        This will apply the new matcher to your entire app:



        dirty-error-state.matcher.ts



        import {FormControl, FormGroupDirective, NgForm } from '@angular/forms';
        import {ErrorStateMatcher} from '@angular/material/core';

        export class DirtyErrorStateMatcher implements ErrorStateMatcher {
        isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean {
        return !!(control && control.invalid && (control.dirty));
        }
        }


        app.module.ts



        import { DirtyErrorStateMatcher } from 'your-path-here';
        import { ErrorStateMatcher } from '@angular/material/core';

        @NgModule({
        ...
        providers: [{
        provide: ErrorStateMatcher,
        useClass: DirtyErrorStateMatcher
        }]
        })






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Jan 28 at 21:14









        ChristianChristian

        1,159613




        1,159613






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54274350%2fhow-to-show-mat-error-once-the-textbox-is-dirty-and-is-on-focus%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Liquibase includeAll doesn't find base path

            How to use setInterval in EJS file?

            Petrus Granier-Deferre