Creating Wizard in Angular using Ui-Router

In this blog we will be creating a Student Registration wizard using ui-router and angularJs.

Let’s start by creating a project and adding the dependent files:

PREREQUISITES:

Below are the tools and technologies, which we will be using to complete this package

  1. VS 2015
  2. Nuget Package Manager
  3. Angular 1.5.x
  4. UI Router

INTRODUCTION:

Many times we get some requirement where we need to provide a wizard, where user can fill data on multiple forms and submit at once. Let’s create the same model using AngularJs.

  1. Let’s create our project we will be using Empty project here, so go to File->New Project and Name it StudentWizard and click ok. On next screen, from available template select Empty Template.Do not choose any option from MVC/Web Forms.Project
  2. Now our project is ready, but we don’t have any files so let’s add our dependent files. Right click on Project and choose Mange Nuget Packages, and search for angular and install it, it will add angular files to our project. Let’s add ui-router as well, search for ui-router and install the same.
  3. After adding all required files this is how our project structure looks like.Project Structure
  4. Now let’s start creating our angular modules. We will follow the same folder structure described in previous blogs. Add a new folder called as App, and add a new file called App.js in the same folder. To add just right click on folder and       Add->JavaScript File.
  5. Let’s initialize our module, and define the routes using ui-router, below is the code for our App.js file, if you are aware of ui-router than ok, otherwise you can drop a mail, will explain the same. 
    var studentApp = angular.module('studentApp', ['ngAnimate', 'ui.router']); //
    
    studentApp.config(function ($stateProvider, $urlRouterProvider) {
        $stateProvider
        .state('student', {
            url: '/student',
            templateUrl: 'App/Views/student.html',
            controller: 'studentController'
        }).
            //nested states
        state('student.profile', {
            url: '/profile',
            templateUrl: 'App/Views/student-profile.html'
        })
        .state('student.interests',
        {
            url: '/interests',
            templateUrl: 'App/Views/student-interests.html'
        })
        .state('student.payment',
        {
            url: '/payment',
            templateUrl: 'App/Views/student-payment.html'
        });
    
        $urlRouterProvider.otherwise('/student/profile');
    });
    
  6. Now lets go ahead and add the required views, as visible from config file, we need 4 html files. Add a new folder under App Folder as “Views” and add student.html, student-profile, student-payment, student-interests.html files, keep all files blank. Below is the current structure.Project Structure1
  7. We will also add an index.html page which will be our default page, it will be in our root folder, so right click on your project add a new html page and name it as index.html. Keep this file as it is, and include all .js files in head section. 
    <!DOCTYPE html>
    <html>
    <head>
        <title></title>
        <meta charset="utf-8" />
        <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootswatch/3.1.1/darkly/bootstrap.min.css">
        <link href="Contents/style.css" rel="stylesheet" />
        <script src="Scripts/angular.min.js"></script>
        <script src="Scripts/angular-ui-router.js"></script>
        <script src="Scripts/angular-animate.min.js"></script>
        <script src="App/App.js"></script>
        <script src="App/Controller/studentController.js"></script>
    </head>
    <body ng-app="studentApp">
        <div class="container">
            <div ui-view></div>
        </div>
    </body>
    </html>
    
  8. ui-view is where our views will be loaded.Let’s add our controller, to add controller add a new folder under App folder and name it as controller. Once folder is created add a new java-script file under the controller folder,and name it as studentController. We will keep this controller very simple, 
    studentApp.controller('studentController', ['$scope', function ($scope) {
    
        $scope.studentData = {};
    
        $scope.processRequest = function () {
            alert('Form Submitted');
        }
    
    }]);
  9. Now lets design our student.html page, we will add 3 links on this page which will help us to navigate through wizard. 
    <div class="row">
        <div class="col-sm-8 col-sm-offset-2">
            <div id="form-container">
                <div class="page-header text-center">
                    <h2>Fill your details</h2>
                    <div id="status-buttons" class="text-center">
                        <a ui-sref-active="active" ui-sref=".profile"><span>1</span> Profile</a>
                        <a ui-sref-active="active" ui-sref=".interests"><span>2</span> Interests</a>
                        <a ui-sref-active="active" ui-sref=".payment"><span>3</span> Payment</a>
                    </div>
                </div>
    
                <form id="signup-form" ng-submit="processRequest()">
                    <div id="form-views" ui-view></div>
                </form>
            </div>
            <pre>
            {{studentData}}
            </pre>
        </div>
    </div>
  10. Here ui-sref attribute value is states from our config section, .profile refers to student form and profile state. so if we click on Profile tab, it will load profile Tab.
  11. Now open the student-profile.html and add text “Profile Page”, for student-interests.html add “Interest Page”,and for student-payment.html add “Payment Page”.
  12. Now press F5 to see the changes. We should see below page. If there are any design issue please include style.css file, given below.profileHtml
  13. For designing add one style.css file and copy the given css.
    /* style.css */
    /* BASIC STYLINGS
    ============================================================================= */
    body                            { padding-top:20px; }
    
    /* form styling */
    #form-container                { background:#2f2f2f; margin-bottom:20px;
        border-radius:5px; }
    #form-container .page-header   { background:#151515; margin:0; padding:30px; 
        border-top-left-radius:5px; border-top-right-radius:5px; }
    
    /* numbered buttons */
    #status-buttons                 {  }
    #status-buttons a               { color:#FFF; display:inline-block; font-size:12px; margin-right:10px; text-align:center; text-transform:uppercase; }
    #status-buttons a:hover         { text-decoration:none; }
    
    /* we will style the span as the circled number */
    #status-buttons span            { background:#080808; display:block; height:30px; margin:0 auto 10px; padding-top:5px; width:30px; 
        border-radius:50%; }
    
    /* active buttons turn light green-blue*/
    #status-buttons a.active span   { background:#00BC8C; }
    
    /* style.css */
    /* ANIMATION STYLINGS
    ============================================================================= */
    #signup-form            { position:relative; min-height:300px; overflow:hidden; padding:30px; }
    #form-views             { width:auto; }
    
    /* basic styling for entering and leaving */
    /* left and right added to ensure full width */
    #form-views.ng-enter,
    #form-views.ng-leave      { position:absolute; left:30px; right:30px;
        transition:0.5s all ease; -moz-transition:0.5s all ease; -webkit-transition:0.5s all ease; 
    }
        
    /* enter animation */
    #form-views.ng-enter            { 
        -webkit-animation:slideInRight 0.5s both ease;
        -moz-animation:slideInRight 0.5s both ease;
        animation:slideInRight 0.5s both ease; 
    }
    
    /* leave animation */
    #form-views.ng-leave            { 
        -webkit-animation:slideOutLeft 0.5s both ease;
        -moz-animation:slideOutLeft 0.5s both ease;
        animation:slideOutLeft 0.5s both ease;   
    }
    
    /* ANIMATIONS
    ============================================================================= */
    /* slide out to the left */
    @keyframes slideOutLeft {
        to      { transform: translateX(-200%); }
    }
    @-moz-keyframes slideOutLeft {  
        to      { -moz-transform: translateX(-200%); }
    }
    @-webkit-keyframes slideOutLeft {
        to      { -webkit-transform: translateX(-200%); }
    }
    
    /* slide in from the right */
    @keyframes slideInRight {
        from    { transform:translateX(200%); }
        to      { transform: translateX(0); }
    }
    @-moz-keyframes slideInRight {
        from    { -moz-transform:translateX(200%); }
        to      { -moz-transform: translateX(0); }
    }
    @-webkit-keyframes slideInRight {
        from    { -webkit-transform:translateX(200%); }
        to      { -webkit-transform: translateX(0); }
    }
    
  14. Now lets add some controls to all 3 forms. Open profile page and add few controls for profile data, like First Name, Last Name, Email. We will also add a button for Proceed.
    <div class="form-group">
        <label for="name">First Name</label>
        <input type="text" class="form-control" name="name" ng-model="studentData.FirstName" />
    </div>
    
    <div class="form-group">
        <label for="name">Last Name</label>
        <input type="text" class="form-control" name="name" ng-model="studentData.LastName" />
    </div>
    
    
    <div class="form-group">
        <label for="name">Email</label>
        <input type="text" class="form-control" name="email" ng-model="studentData.email" />
    </div>
    
    
    <div class="form-group row">
        <div class="col-xs-6 col-xs-offset-3">
            <a ui-sref="student.interests" class="btn btn-block btn-info">
                Proceed <span class="glyphicon glyphicon-circle-arrow-right"></span>
            </a>
        </div>
    </div>
  15. Press F5 to see the changes.profileHtml1
  16. It looks nice isn’t it, if you notice we are able to see the model changes below proceed button, also for navigation we have added ui-sref=”student.interests”, which takes us to next view. Now lets add some data into interests page.
  17. Add the below code in your HTML file  
    <!-- form-interests.html -->
    <label>Which department you would like to enroll?</label>
    <div class="form-group">
        <div class="radio">
            <label>
                <input type="radio" ng-model="studentData.type" value="Computers" checked>
                Computers
            </label>
        </div>
        <div class="radio">
            <label>
                <input type="radio" ng-model="studentData.type" value="Electronics">
                Electronics
            </label>
        </div>
        <div class="radio">
            <label>
                <input type="radio" ng-model="studentData.type" value="Mechanical">
                Mechanical
            </label>
        </div>
    </div>
    
    <div class="form-group row">
        <div class="col-xs-6 col-xs-offset-3">
            <a ui-sref="student.payment" class="btn btn-block btn-info">
                Proceed to Payment<span class="glyphicon glyphicon-circle-arrow-right"></span>
            </a>
        </div>
    </div>
  18. Let’s move and design our payment page add below code.
    <!-- form-payment.html -->
    <div class="text-center">
        <span></span>
        <h3>Thanks For Your Money!</h3>
    
        <button type="submit" class="btn btn-danger">Submit</button>
    </div>
  19. Press F5 and fill the details, and press submit. And we are ready with our wizard.

CONCLUSION:

So we saw how we can use angular with ui-router for creating a wizard. There are many more advantages of using ui-router. You can download the code from https://github.com/santoshyadav198613/AngularWizard

You can reach out to me on santosh.yadav198613@gmail.com for any question, keep following my blog for more information. Please share the same with your friends.

Thank you for reading it, have a nice day, also don’t forget to share your valuable comments.

3 Comments


  1. I have not checked in here for a while since I thought it was getting boring, but the last several posts are great quality so I guess I’ll add you back to my daily bloglist. You deserve it my friend 🙂

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *