0

The following Angular 2 (version 4.3.5) code does not work as expected.

<link 
    rel="stylesheet" 
    href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" 
    integrity="sha384-rwoIResjU2yc3z8GV/NPeZWAv56rSmLldC3R/AZzGRnGxQQKnKkoFVhFQhNUwEyJ"
    crossorigin="anonymous">   
<script 
    src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js" 
    integrity="sha384-vBWWzlZJ8ea9aCX4pEW3rVHjgjt7zpkNpZk+02D9phzyeVkE+jo0ieGizqPLForn"
    crossorigin="anonymous">
</script>
<form style="margin:50px;">
    <div class="form-control">
        <label for="firstName">First Name</label>
        <input 
            ngControl="firstName" 
            id="firstName" 
            #firstName 
            type='text' 
            class='form-control' 
            required>
        <div 
            class="alert alert-danger" 
            *ngIf="!firstName.valid && firstName.touched">
                A first name is required
        </div>
    </div>
    <br/>
    <button class="btn btn-primary" type="submit">
        Submit!
    </button>
</form>

When the ngIf statement is

*ngIf="!firstName.valid"

the error message div is shown when the page is loaded and remains visible after text has been entered into the input.

When the ngIf statement is as above

*ngIf="!firstName.valid && firstName.touched"

the error message is not shown.

What am I missing? thank you A.G.

Eric
  • 336
  • 4
  • 17
A.G.
  • 43
  • 3
  • You have imported the ´FormsModule´, not the ´ReactiveFormsModule´, right? Try to replace ngControl by [(ngModel)] and add a name attribute. – Kim Kern Aug 22 '17 at 20:43

2 Answers2

0

I think you need to specify what type of template variable that # refers to by putting ="ngControl" or ="ngModel"

<input ngControl="firstName" 
        id="firstName" 
        #firstName="ngForm"   // or ngModel if you're using 2-way binding
        type='text' 
        class='form-control' 
        required>
    <div 
        class="alert alert-danger" 
        *ngIf="!firstName.valid && firstName.touched">
            A first name is required
    </div>

See here: Angular2 Forms :Validations, ngControl, ngModel etc

diopside
  • 2,981
  • 11
  • 23
  • I've tried using #firstName="ngForm" and see the following error using the browser's developer's tools. `code` Uncaught Error: Template parse errors: There is no directive with "exportAs" set to "ngForm" (" ]#firstName="ngForm" type='text' class='form-control' required> ... When the directive is added to the component @Component({ ... exportAs : 'ngForm' }) the same error occurs. – A.G. Aug 22 '17 at 21:31
  • Have you imported ngForm in the component? A plunker would help. I think for ngForm / ngModel / ngControl to work properly, they need to be wrapped in an ngForm element.
    ...rest of your form here....
    If you do it like that, "f" is the name of your ngForm object, and then you can access properties inside it like f.firstName, etc.
    – diopside Aug 22 '17 at 21:36
0

added a class Contact with firstName and comment properties imported FormsModule in app.module.ts add property and initialized model of type Contact to ContactFormComponent type

<form #contactForm='ngForm' style='margin:50px;'>
    <div class='form-group'>
        <label for='firstName'>First Name</label>
        <br />
        <input id='firstName' type='text' class='form-control' [(ngModel)]='model.firstName' required name='firstName' #firstName="ngModel"
            (change)='onChange(ngModel)'>
        <div [hidden]="firstName.valid || firstName.pristine" class="alert alert-danger">
            A first name is required.
        </div>
    </div>
    <div class='form-group'>
        <label for='comment'>Comment</label>
        <br />
        <textarea id='comment' class='form-control' [(ngModel)]='model.comment' required name='comment' #comment="ngModel" ></textarea>
        <div [hidden]="comment.valid || comment.pristine" class="alert alert-danger">
            A comment is required.
        </div>
    </div>
    <button class='btn btn-primary' type='submit'>
         Submit
    </button>
</form>

The changes were made after following the example at https://angular.io/guide/forms and now the component works as expected.

A.G.
  • 43
  • 3