Creating a multi step form with Angular.js

Before we start, you might want to check out this example of the form in action.

While I was working with Angular.js to create a nice little recipe / cookbook site for myself, I was creating a form that required me to split it up into multiple parts or steps. I found this surprisingly easy to do actually but I can imagine that not everybody will have the same experience I did. In this short post I will provide you with a good starting point for your html and your javascript.

I'll be using the power of Angular.js directives to hide and show parts of the form. Well, let's dive in then!

First of all, we'll set up a form. It could look a little like this. I'm using bootstrap to style the form in this example. You can just ignore the classes I've used.

<form class="form-vertical" name="myForm" ng-controller="FormController" novalidate>
    <fieldset ng-show="step == 1">
        <legend>Step one</legend>
        <div class="form-group">
           <label for="name">Your name</label>
           <input class="form-control" type="text" id="name" name="name" ng-model="name" />
        </div>
        <button class="btn btn-primary" ng-click="nextStep()">Next step</button>
    </fieldset>
    <fieldset ng-show="step == 2">
        <legend>Step two</legend>
        <div class="form-group">
            <label for="email">Your email</label>
            <input class="form-control" type="email" id="email" name="email" ng-model="email" />
        </div>
        <button class="btn btn-default" ng-click="prevStep()">Previous step</button>
        <button class="btn btn-primary" ng-click="nextStep()">Next step</button>
    </fieldset>
    <fieldset ng-show="step == 3">
        <legend>Step three</legend>
        <div class="form-group">
            <label for="msg">Short message</label>
            <input class="form-control" type="text" id="msg" name="msg" ng-model="msg" />
        </div>
        <button class="btn btn-default" ng-click="prevStep()">Previous step</button>
        <button class="btn btn-primary" ng-click="submitForm()">Submit</button>
    </fieldset>
</form>

So, that's not very bizarre right? It's a regular Angular.js style form with a bunch of fieldsets. The magic happens with the ng-show directives that are set on the fieldsets. These directive will make sure that we will only show a certain fieldset if the stepĀ property of our controller is equal to a certain number.

Let's tie this up with some Javascript.

(function(){
    var app = angular.module('myApp', []);
    app.controller('FormController', ['$scope', function($scope){
        $scope.step = 1;

        $scope.nextStep = function() {
            $scope.step++;
        }

        $scope.prevStep = function() {
            $scope.step--;
        }

        $scope.submitForm = function() {
            // submit code goes here
        }
    }]);
})();

If we were to test this out in an actual app we would have a pretty neat form that spans multiple steps. The model data is preserved for each because we're just showing and hiding different parts of a single form!

Source on github