Angular, template-driven forms


Simple example of component. Everything what you need will be generated after executing this commands ng new hello-word to create new app and ng g c contact-form to create new component. After that, what you have to do, is adjust few files. Of course more you can find in Angular documentation, here we have only my notes. One more thing, if you don’t like to install node mess on your local computer you can use my or similar docker image https://hub.docker.com/r/szalek/angular-cli/

This what we want to build



New app and component

By this two simple commants you will be able to create skeleton for you app. If you don’t have already angular ci, you can use my docker image https://hub.docker.com/r/szalek/angular-cli/

ng new hello-world
ng g c contact-form

Bootstrap installation

You don’t need but it will be good to install bootstrap, everything is described here
http://blog.michalszalkowski.com/java-script/angular-cli-add-bootstrap/

Requred dependencies. FormsModule

You have to extend app.module.ts by adding FormsModule (one new import and one new item in imports section)

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';

import { ContactFormComponent } from './contact-form/contact-form.component';
import { FormsModule }   from '@angular/forms';

@NgModule({
  declarations: [
    AppComponent,
    ContactFormComponent
  ],
  imports: [
    BrowserModule,
    FormsModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

contact-form.component.ts

import {Component} from '@angular/core';

@Component({
  selector: 'app-contact-form',
  templateUrl: './contact-form.component.html',
  styleUrls: ['./contact-form.component.css']
})
export class ContactFormComponent {

  constructor() {
  }

  types = [
    {id: '1', label: 'Type 1'},
    {id: '2', label: 'Type 2'},
    {id: '3', label: 'Type 3'}
  ];

  languages = [
    {id: 'PL', label: 'Polski'},
    {id: 'EN', label: 'English'},
  ];

  devlanguages = [
    {id: 1, label: 'JAVA'},
    {id: 2, label: 'PYTHON'},
    {id: 3, label: 'HTML'},
    {id: 4, label: 'JS'},
  ];

  submit(form) {
    console.log("Form", form);
  }

  debug(str) {
    console.log("Log ", str);
  }

}

contact-form.component.html

<h2>Contact form</h2>

<div class="row">

  <div class="col-xs-6">

    <form #form="ngForm" (ngSubmit)="submit(form)">

      <!-- ------------------------------------- -->

      <div class="form-group">

        <label for="name">* Name</label>

        <input
          ngModel name="name" #name="ngModel" (change)="debug(name)"
          required minlength="3" maxlength="255"
          id="name" type="text" class="form-control"/>

        <div *ngIf="!name.valid && name.touched" class="alert alert-danger">
          <div *ngIf="name.errors.required">User 'name' is required</div>
          <div *ngIf="name.errors.minlength">User 'name' should be minimum 3 characters</div>
        </div>

      </div>

      <!-- ------------------------------------- -->

      <div class="form-group">
        <label for="comment">* Comment</label>
        <textarea
          ngModel name="comment" #comment="ngModel" (change)="debug(comment)"
          required minlength="20" maxlength="255"
          id="comment" cols="30" rows="10" class="form-control"></textarea>

        <div *ngIf="!comment.valid && comment.touched" class="alert alert-danger">
          <div *ngIf="comment.errors.required">Comment is required</div>
          <div *ngIf="comment.errors.minlength">Comment should be minimum 20 characters</div>
        </div>

      </div>

      <!-- ------------------------------------- -->

      <div class="checkbox">
        <label>
          <input
            ngModel name="option_1" #option_1="ngModel" (change)="debug(option_1)"
            type="checkbox" value="">Option 1
        </label>
      </div>

      <!-- ------------------------------------- -->

      <div class="checkbox">
        <label>
          <input
            ngModel name="option_2" #option_2="ngModel" (change)="debug(option_2)"
            type="checkbox" value="">Option 2
        </label>
      </div>

      <!-- ------------------------------------- -->

      <div class="form-group">
        <label for="lang">Language</label>
        <select
          ngModel
          name="lang" id="lang" class="form-control">
            <option *ngFor="let lang of languages" [value]="lang.id">{{lang.label}}</option>
            <!--<option *ngFor="let lang of languages" [ngValue]="lang">{{lang.label}}</option>-->
        </select>
      </div>

      <!-- ------------------------------------- -->

      <div class="form-group">
        <label for="devLang">Dev Language</label>
        <select
          multiple
          ngModel
          name="devLang" id="devLang" class="form-control">
            <option *ngFor="let devLang of devlanguages" [value]="devLang.id">{{devLang.label}}</option>
        </select>
      </div>

      <!-- ------------------------------------- -->

      <div class="radio" *ngFor="let type of types">
        <label>
          <input ngModel type="radio" name="contactType" [value]="type.id"> {{type.label}}
        </label>
      </div>

      <!-- ------------------------------------- -->

      <button
        [disabled]="!form.valid"
        class="btn btn-primary">
        Submit
      </button>

    </form>

  </div>
  <div class="col-xs-6">

    <pre>{{form.value | json}}</pre>

  </div>

</div>

styles.css

@import "~bootstrap/dist/css/bootstrap.css";

.form-control.ng-touched.ng-invalid {
  border: 1px solid #ff6557;
}

app.component.html

<section class="container">
  <div class="row">
    <div class="col-xs-12">
      <app-contact-form></app-contact-form>
    </div>
  </div>
</section>