Javascript

Updated: Ionic 2 Forms – Getting Started on the Right Foot

Preamble: You probably stumbled on this page after tirelessly searching online for a least working example of forms in Ionic 2. I’ve been in your current shoes, and know how it feels. Ionic 2 is new, and tutorials are thrown here and there, some outdated, others addressing the advanced parts of the form, without tackling what the basics are. I tell you the basics in this, so get ready.

Validations and how to use FormBuilder is discussed in my follow-up article. Many talk about how to setup Ionic 2 Side menu and tabs, so I touched on it.

Update: If you’re using the new Ionic 2 Beta.11 with AngularJS RC4, you’ll find the update to this article here: https://blog.khophi.co/new-changes-ionic-2-forms-examples/

Whenever there’s a new cool kid in town, everyone rushes to catch a glimpse. Some join the party later. Other’s struggle to catch a glimpse or even come close. It is even worse when the cool kid you knew isn’t the one standing there, nor she ain’t wearing what you always knew her to wear.

Ionic 2 forms
What we’ll be doing. Ionic 2 Forms

It is frustrating, but with the right concepts and mentality shift, you are great to adapt to this new kid and fall in love.

Ionic 2 is the new kid in town. Ionic 2 comes with tons of features and does things differently. A typical example is how navigation by default now uses the page-stack-push-and-pop approach and a different way to deal with forms.

In this article, I hope to walk you through how to handle extremely basic forms in Ionic 2. The examples used will probably be the easiest you’ll probably see online at the moment. So, before the codes start hitting left and right, how about we take a second to appreciate how Ionic 2 (Angular 2, for that matter) forms are structured.

New Concepts and Approach

Forms are a crucial aspect of many web application. You’ve heard that line probably a million times. I had to say it again. It is more like how an intro video plays at the beginning of each episode of a series, although you ‘think’ you know the story line. Well, you don’t, so,

Forms are crucial aspect of many web applications. Let that sink in!

Angular 2 (which Ionic 2 uses) having the above mantra at heart, also revised how forms are handled, to ensure Forms are better built, in an easy and fast manner.

  • Controls allows us to get access to form input values, individually, or as a group
  • Validator s, well, does validation
  • Observers allow us to provide error messages and feedback to form elements responsively

All the above except Controls were available in Angular 1, and available in Angular 2. However, how it works it kinda different a bit.

I will be touching only on Controls and ControlGroups in this article. Subsequent ones might handle the rest.

Controls – Let’s take Control, Shall we?

A Control represents a single input field – it is the smallest unit of an Angular form.
Control s encapsulate the field’s value, and states such as if it is valid, dirty (changed), or has errors.

The above quote was taken from NG-Book 2.  It is a great book, and I’ll recommend you get yourself a copy.

Previously, in Angular 1, one would do something like this in the template to bind the form input values to an object, which would be intercepted in the controller $scope for use, either sent to a service or manipulated and returned.

// typical example of a control in action
<input type="text" ngControl="name" />

Will be showing complete examples in a jiffy below, so hold on a bit as we dive through the ‘controls’ a bit.

ControlGroup
Most forms have more than one field, so we need a way to manage multiple Controls. If we wanted to check the validity of our form, it’s cumbersome to iterate over an array of Control s and check each Control for validity. ControlGroups solve this issue by providing a wrapper interface around a collection of Controls.

I think the explanations from ng-book 2 is enough to paint the picture we’re looking at here with Angular 2 forms.

Thus, building Angular 2 forms takes the form of creating Controls within a ControlGroup, then attach metadata and logic

Making actual sense from above.

As usual, if you’re the type that loves to get your hands dirty, whatever you read above is bad, and makes no sense. In fact, you probably didn’t read. I get it. The fun part begins here, and will help you get a better understanding.

Let us for a second, say we have an Ionic Project initialized probably, and have created a page called addtext using the ionic generate page addtext command. As usual, I’ll be leaving comments in the code snippets, so you can follow along in there.

addtext.js

// addtext.js in your pages/addtext/
import { Page } from 'ionic-angular';

@Page({
  templateUrl: 'build/pages/addcategory/addcategory.html',
})

export class AddtextPage {
  static get parameters() {
    return [];
  }

  constructor() {
    // do stuff here
  }

  // this function will be called
  // from template
  onSubmit(formData) {
    // let's log our findings
    console.log('Form submission is ', formData);
  }
}

addtext.html

There’s always an exception to the rule, so lemme add the commentary here instead. Take a look at the addtext.html code snippet. Afterward, let’s discuss

// addtext.html template
<ion-content class="addtrans">
    <ion-list inset>
        <form #formData='ngForm' (ngSubmit)="onSubmit(formData.value)">
            <ion-item>
                <ion-label floating>Name of Category</ion-label>
                <ion-input type="text" ngControl="name"></ion-input>
            </ion-item>
            <button block>
                <ion-icon name="add"></ion-icon>Add</button>
        </form>
    </ion-list>
</ion-content>

First:

<form #formData='ngForm' (ngSubmit)="onSubmit(formData.value)">

Remember the boring concept lessons we took above. Bring them here. We said the building blocks of forms in Angular 2 is the Controls and ControlGroup. In the above snippet, lemme translate that to English.

  • Create an ControlGroup implicitly called ngForm and bind what it will have to the variable, namely, formData
  • (ngSubmit) directive comes for free when using ngForm . So, when the form is submitted, carry the ControlsGroup data values – which in turn means the individual Controls, or in other words the values of each input field – into the onSubmit() function.
<ion-input type="text" ngControl="name"></ion-input>

The ngControl on the <ion-input> is to allow the value from the input to be available in the parent ControlGroup object.

As we saw in the addtext.js file, the onSubmit() function simply logs whatever that comes through from the form to console.

And this is what I get in console:

Form submission is  Object {name: "I am submitted"}

I still don’t Understand the Forms

If you still don’t get what is happening here with Angular 2 forms as found in Ionic 2, then I might have to slap you hard with the source code of this article.

First slap goes to your right cheek, and that’s the repo for this simple example above. The next slap to the left cheek is finding a bigger picture of how Ionic 2 forms are handled as seen in the Conference app by the Ionic team, to display some the goodness of the features of Ionic 2. Clone their app to your local PC, and you’ll be amazed the tons of tricks in there, not just forms.

[wp_ad_camp_1]

Link to this article on Github: https://github.com/seanmavley/ionic2-forms

Link to Conference App by Ionic team: https://github.com/driftyco/ionic-conference-app

UPDATE: May 18, 14:05 GMT

And Speaking of Conference App…

I have been going through the code of the conference app from the above repo. One way of building forms that caught my eyes immediately was the use of hybrid, so to speak, of the implicit and explicit way of form building. I do not know if those are the right words for me to use, but …

Let’s see an example to flesh out the point. This is more of an off-the-book add on to the above tutorial, which introduces you to forms in Ionic 2 (Angular 2) on the right foot.

Below are snippets taken from an Ionic project I am working. The form below is a form for editing a Category object. To edit a form, you usually want to pre-populate your form with data from the database. In that way, your users know what they already added, then from there, they can make changes.

One way to get this pre-populating of data is to use FormBuilder, which I have already talked about. Another way is what you’ll see. Consider the snippet below and let’s discuss.

<ion-list inset>
        <form #formData='ngForm'>
            <ion-input type="text" hidden [(ngModel)]="category.id" ngControl="id"></ion-input>
            <ion-item>
                <ion-label floating>Name of Category</ion-label>
                <ion-input type="text" [(ngModel)]="category.name" ngControl="name"></ion-input>
            </ion-item>
            <ion-list radio-group ngControl="type" [(ngModel)]="category.type">
                <ion-list-header>Choose type</ion-list-header>
                <ion-row>
                    <ion-col width-50>
                        <ion-item>
                            <ion-label>Income</ion-label>
                            <ion-radio value="income"></ion-radio>
                        </ion-item>
                    </ion-col>
                    <ion-col width-50>
                        <ion-item>
                            <ion-label>Expense</ion-label>
                            <ion-radio value="expense"></ion-radio>
                        </ion-item>
                    </ion-col>
                </ion-row>
            </ion-list>
            <button block (click)="onSubmit(formData.value)">
                <ion-icon name="update"></ion-icon>Add</button>
        </form>
    </ion-list>
  // in my controller  
  constructor(nav, navparams) {
    this.nav = nav;
    this.params = navparams;
    this.category = {
      'id': this.params.get('obj').id,
      'name': this.params.get('obj').name,
      'type': this.params.get('obj').type
    }
  }

First of all, if you don’t know about NavParams, please read about it. What we’re basically doing with the NavParams is using the .get function to capture the parameters passed in from the previous page. That might be something like this:

  // obj is a category object
  // so I can do something like obj.id or obj.name  
  editCategory(obj) {
    this.nav.push(EditcategoryPage, {
      'obj': obj
    });
  }

I don’t wanna digress, so let’s get to the form again.

<form #formData='ngForm'>
            <ion-input type="text" hidden [(ngModel)]="category.id" ngControl="id"></ion-input>

The first part is obvious. The second part, same, except we’re using [(ngModel)]. Remember ng-model from Angular 1? This is probably the closest syntax you’ve got, which happens to work in a similar way.

[(ngModel)] is binding the current input field context to the this.category object we created in the constructor. So, in this case, we’re binding to the id field of that this.category object.

Which means, by assigning any value to the id field in the this.category object pushes that value into the template form for our usage. In our case, I decided to capture the obj object passed in from the previous page, using the NavParams then accessing the id field on that.

We win! Our form is prepopulated. You might be wondering, why the ngControl?

Good question! Remember the ngForm creates a kinda ControlGroup for us and the ngControl refers to the individual fields of the form, the basic unit?

When we do submit the form, we submit the ControlGroup, in the object stored in the formData variable. Without applying the ngControl to the form, we will be able to prepopulate the form, but won’t be able to submit. So the this.category is our ticket to form pre-population, and the ngControl is our other way round ticket, to get the form values submitted and committed to the server for processing.

I hope that is clear. You may see the Conference app source code above to learn more about how using the approach above can simplify form building. It is fast and simple.

Related Articles

Back to top button