Creating a Form in Angular 12


Hey kids! Let's continue learning to do some fun things with Angular! Next up is adding a form to your site.



I used the base Angular site demo to make the base. Then I crafted the individual changes I needed for my purposes. To follow along, you can use the link below for additional information and resources.


https://v12.angular.io/guide/forms


Verify your Angular version in the package.json file first. Other versions may not play well as-is but the basic ideas should still hold true.


Pssssst: All the code we go over in the steps below is available at the bottom of this post to be copied, if you're in a hurry and don't care it works :)



 

First you want to add a new component to your application. Let's add a component called 'form-test' in the dev Terminal. If you don't see the terminal in your Visual Studio or VS Code - go to the View menu bar, and look for 'Terminal'.



Then cd into to your Angular root - it could be the ClientApp, or whatever folder holds your 'app' folder. In the new .esproj files, it will be your high level application folder.



PS C:\Repos\YourRepo> cd C:\Repos\YourRepo\angularproject

OR


PS C:\Repos\YourRepo> cd C:\Repos\YourRepo\angularproject\ClientApp

Once you have cd'ed into your root folder, then we want to execute the command below. This line will add your new component automatically to the app.module file.


NOTE: you can add these files manually, but you need to remember to add each file AND the references to the main app.module file as well.


C:\Repos\YourRepo\angularproject> ng g c form-test --module=app.module

This command will auto-add all the files you need for your new component.


In the app.module.ts file - the component is also auto-added as an import and declaration.



Copy the selector for the new component and add this to your base page where you want to display the new component.


Paste the selector text inside the carrots.


<app-form-test>

The closing text will automatically be added for you.



Now, save your application, and build. If you need to, type

C:\Repos\YourRepo\angularproject> ng serve 

into your Terminal to build and deploy the application to your localhost. Your application should display similarly to this:


Great! It works! Next thing to do is to import the Angular FormBuilder to use. Sometimes, you're lucky and you can just add the import and the forms are there to use. Most times, you'll have to actually add the forms to your application via the Terminal.


If the FormBuilder import is not recognized, go to your Terminal and type:


npm i @angular/forms

For more detail on this import: https://www.npmjs.com/package/@angular/forms


Now the FormBuilder should resolve.


Next, we want to add a private instance of the FormBuilder to the constructor to instantiate a copy of the builder to use.


Let's utilize the new builder for the items we want to include on our form. We want to know your email and your state. Let's group these as 'aboutyou' so we can add new fields to the form later in a new group. We are adding validators to both items so we know each item has a value before the form can be submitted.



Next, let's create a ListValues object so we can capture our list items with a user view value and a data value.


Our list will be a list of States we want our user to choose from. This will not allow for choices outside of what we want as an option.


Let's make sure we have a submitted value that changes 'on submit'. This is an easy way to hide your form once the user is done with it.


Next, let's hook up the new SaveData function to fire when the Submit button is clicked. We also want the Submit button to be disabled until all required values have been filled in.


Let's create our form in HTML. Use your values we created above for the form, group(s), and field(s) created in the .ts file above.


Let's create the 2 fields we want. one will be a standard string value and the other will be a dropdown list. I am using boilerplate bootstrap for the classes.


Here is the form we created above. If you click save, or rebuild your application, this is what you should see on your page.



Let's go ahead and fill out our form with an email and choose a state in the dropdown.





The submit button should be greyed out until both values have been filled. Once the Submit button is enabled, go ahead and click it.



This is what we should see ... which is not very user friendly. :(


Let's look into adding a 'reply upon response' section.




Go back to your HTML page and add a new div AFTER the form div closes.


Go back to your .ts file and add the response object's initial value, and then the updated value upon submit.



Save or rebuild your application. Fill out your form and submit.





well, ok that's better! We have a response for the user. But we can do better.




Let's add 2 values to capture the user entries.


The best way to get the most up to date values for the Form fields, use this.myForm.get(). etc etc etc


Here, you can choose to capture the value or the viewValue from your List object.


Now, add those new objects to your response area and save or build.


Your initial view will not change at all. Fill out your form and submit.


You will then see the below values displayed. Remember, I chose the .value rather than the .viewValue to display back to the user. It is your choice what values you want to show or use.


And we're done with this basic form creation! There is so much that can be done using a form this way. I'm sure we'll go over more ways to use Forms in Angular in the future. Keep an eye out for new Angular posts here.



Full code from tutorial we did above to copy:


app.component.html


<header>
  <div >
    <span >Heading</span>
    <hr />
  </div>
  <nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
    <div class="navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse">
      <ul class="navbar-nav flex-grow ">

        <li class="nav-item underline">
          <a class="nav-link" target="_blank" href="https://google.com">Google</a>
        </li>


      </ul>
    </div>
  </nav>
</header>

<app-form-test></app-form-test>


form-test.component.ts


import { Component, OnDestroy, OnInit } from '@angular/core';
import { FormBuilder, Validators, FormArray } from '@angular/forms';

export interface ListValues {
  value: string;
  viewValue: string;
}

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

  submitted = false;
  response = true;
  email = '';
  returnemail = '';
  state = '';
  returnstate = '';
  // list initializer
  states: ListValues[] = [
    { value: 'FL', viewValue: 'Florida' },
    { value: 'MI', viewValue: 'Michigan' },
    { value: 'TX', viewValue: 'Texas' },
    { value: 'OH', viewValue: 'Ohio' },
    { value: 'CA', viewValue: 'California' }
  ];

  // intiial values on open
  myForm = this.builder.group({
    aboutyou: this.builder.group({
      email: ['', Validators.required],
      state: ['', Validators.required]
    })
  });


  constructor(private builder: FormBuilder) { }

  ngOnInit(): void {
    this.submitted = false;
    this.response = true;
  }

  SaveData() {
    this.submitted = true;
    this.response = false;
    this.returnemail = this.myForm.get('aboutyou.email')?.value;
    this.returnstate = this.myForm.get('aboutyou.state')?.value;
  }

}


form-test.component.html


<div [hidden]="submitted">
  <label style="text-align:left; padding-left:15px;">All fields marked with * are required</label>
  <form [formGroup]="myForm">
    <div class="container">
      <div class="first" formGroupName="aboutyou">
        <div class="sectionHeader">
          <span class="sectionHeader">
            Tell Us About Yourself
          </span>
        </div>
        <br />

        <!--Requester Email: string-->
        <div class="row">
          <div class="column1">
            <label for="email">Your Email * </label>
          </div>
          <div class="column2">
            <input id="email" type="text" formControlName="email" required>
          </div>
        </div>

        <!--State list: dropdown-->
        <div class="row">
          <div class="column1">
            <label for="state">State * </label>
          </div>
          <div class=" column2">
            <select class="form-select" id="state"
                    required
                    formControlName="state">
              <option *ngFor="let stat of states" [ngValue]="stat.value">{{stat.viewValue}}</option>
            </select>
          </div>
        </div>

      </div>
    </div>
    <br />
  </form>

  <button type="submit" [disabled]="!myForm.valid" (click)="SaveData()">Submit</button>


  
</div>
<div [hidden]="response">

  <p>
    Your name and state were recorded.
    <br />
    email: {{returnemail}}
    <br />
    state: {{returnstate}}
  </p>

</div>

Please let me know if I have any mistakes or can make this a better post!



Cheers!!



gif






10 views0 comments