DotNetCurry Logo

ASP.NET Web API application with Angularjs Forms and Bootstrap

Posted by: Mahesh Sabnis , on 1/31/2015, in Category ASP.NET
Views: 62973
Abstract: Use Angular.js forms with Bootstrap for creating responsive layout web applications with DataBinding. Compliment this application with ASP.NET Web API to post the form data to the database.

Web Application development has reached new heights with its UI that is feature rich and responsive across multiple platforms. A blend of client-server side technologies allows us to create the next-gen apps on the web.

Angularjs, a relatively new and popular JavaScript framework can be used for DataBinding, Routing and Dependency Injection, whereas BootStrap.js, a widely used front-end framework can be used for styling and creating responsive, mobile-first web applications. ASP.NET MVC on the other hand is a nice server-side framework for developing web applications using the Model, Views and Controllers (MVC) pattern. One major release with the MVC (version 4 onwards) is ASP.NET WEB API. Web API’s allow us to create Http action based methods which can be called using JavaScript with Ajax (e.g. jQuery Ajax method and Angular.js $http methods).

 

In this article, we will be using Angular.js forms with Bootstrap for creating high responsive layout web applications with DataBinding. We will create UI form using custom Angular Directive and also will make use of the Angular UI Bootstrap for elements like DatePicker. ASP.NET Web API will be used to post the form data to the database.

Step 1: Open the free Visual Studio 2013 Community Edition or any other VS 2013 edition with Update 4 installed. Create a new Empty MVC application with the name ‘A1_NG_Boot_MVC5’. In this project, in the App_Data folder, add a new Sql Server Database with the name ‘ApplicationEDMX.mdf’. In this database, add the following PersonInformation table:

table

Step 2: In the Models folder, add a new ADO.NET Entity Data Model of the name ApplicationEDMX. In the wizard, select Database First and the ApplicationEDMX.mdf as the name of the database. Select the PersonInformation table in the wizard. After completing the wizard, the mapping will be displayed as follows:

tablemapping

Step 3: In the Controllers folder, add a new WEB API Controller based on Entity Framework of the name PersonInformationAPICntroller. This will generate the necessary methods for performing Http Operations.

Step 4: To use the Angular.js, Bootstrap and Angular UI Bootstrap in the current project, use NuGet Package Manager as shown here:

angular-ngpackage

This will add the following references:

references

Step 5: It’s time to add client-side logic in the project. In the project, add a new folder named ‘MyScripts’. In this folder add the following files:

pModule.js

var app;
(function () {
    app = angular.module("personInfoModule", ["ui.bootstrap"]);
})();

The above module will be an entry point for using Angular logic on client side.

pService.js

app.service("personInfoService", function ($http) {

    this.getInfo = function (id) {
        var req = $http.get('/api/PersonInformationAPI/' + id);
        return req;
    };

    this.getAppInfo = function () {
        var req = $http.get('/api/PersonInformationAPI');
        return req;
    }

    this.postInfo = function (personInfo) {
        var req = $http.post('/api/PersonInformationAPI', personInfo);
        return req;
    };

});

The above service encapsulates calls to WEB API.

pController.js

app.controller('personInfoController', function ($scope,personInfoService) {
    //The Gender Object
    $scope.selectedGender = "Male";
    $scope.gender = ["Male", "Female"];

    //The Title object
    $scope.selectedtitle = "Mr.";
    $scope.title = ["Mr.", "Mrs.", "Ms.", "Master"];

    $scope.IsSameAddress = false;

    //Function to Reset Scope variables
    function initialize() {
        $scope.PersonId = 0;
        $scope.FirstName = "";
        $scope.MiddleName = "";
        $scope.LastName = "";
        $scope.BirthDate = "";
        $scope.Age = 0;
        $scope.CurrentAddress = "";
        $scope.PermanentAddress = "";
        $scope.Occupation = "";
        $scope.Email = "";
        $scope.MobileNo = "";
        $scope.DisablesPermanentAddress = false;
    }

    //The function to specify the Current and Permanent Address as Same
    $scope.SameAddress = function () {
        if ($scope.IsSameAddress) {
            $scope.PermanentAddress = $scope.CurrentAddress;
            $scope.DisablesPermanentAddress = true;
        }
        else {
            $scope.PermanentAddress = "";
            $scope.DisablesPermanentAddress = false;
        }
    };

    //Function to Calculate Age
    function calculateAge(dateString) {
        var currentday = new Date();
        var bDate = new Date(dateString);
        var age = currentday.getFullYear() - bDate.getFullYear();
        var mt = currentday.getMonth() - bDate.getMonth();
        if (mt < 0 || (mt === 0 && currentday.getDate() < bDate.getDate())) {
            age--;
        }
        return age;
    }

    $scope.getAge = function () {
        $scope.Age = calculateAge($scope.BirthDate);
    }

    //Function to Submit the form
    $scope.submitForm = function () {
        var Person = {};
        Person.Title = $scope.selectedtitle;
        Person.FirstName = $scope.FirstName;
        Person.MiddleName=$scope.MiddleName;
        Person.LastName = $scope.LastName;
        Person.Gender = $scope.selectedGender;
        Person.BirthDate=$scope.BirthDate;
        Person.Age = calculateAge($scope.BirthDate);
        Person.CurrentAddress=$scope.CurrentAddress;
        Person.PermanentAddress=$scope.PermanentAddress;
        Person.Occupation=$scope.Occupation;
        Person.Email=$scope.Email;
        Person.MobileNo=$scope.MobileNo;

        var promisePost = personInfoService.postInfo(Person);
        promisePost.then(function (d) {
            $scope.PersonId = d.data.PersonId;
        }, function (err) {
            alert("Some Error Occured ");
        });
    };
    //Function to Cancel Form
    $scope.cancelForm = function () {
        $scope.selectedGender = "Male";
        initialize();
    };
});

The above controller contains logic for:

· Submitting the form data to WEB API using submitForm() function.

· Calculates Age of the person using calculateAge() function.

· Sets the Current and Permanent address using SameAddress() function.

· Reset all Scope objects using initialize() function. This function is called using cancelForm() function.

· The controller defines arrays for Gender and Title of the registering person.

pTemplate.html

<form class="form-horizontal" role="form">
    <fieldset>
        <legend>Person Basic Info</legend>
        <div class="form-group">
           
            <label for="personId" class="col-sm-3 control-label">Person Id</label>
            <div class="col-sm-9">
                <input type="text" id="personId" name="personId"
                       ng-model="PersonId" class="form-control" readonly="readonly" />
            </div>
            <label for="title" class="col-sm-3 control-label">Person Id</label>
            <div class="col-sm-9">
                <select id="title" name="title" class="form-control"
                        ng-model="selectedtitle"
                        ng-options="t for t in title"></select>
            </div>

            <label for="firstName" class="col-sm-3 control-label">First Name</label>
            <div class="col-sm-9">
                <input type="text" id="firstName" name="firstName"
                       ng-model="FirstName" class="form-control" />
            </div>
            <label for="middleName" class="col-sm-3 control-label">Middle Name</label>
            <div class="col-sm-9">
                <input type="text" id="middleName" name="middleName"
                       ng-model="MiddleName" class="form-control" />
            </div>
            <label for="lastName" class="col-sm-3 control-label">Last Name</label>
            <div class="col-sm-9">
                <input type="text" id="lastName" name="lastName"
                       ng-model="LastName" class="form-control" />
            </div>

            <label for="gender" class="col-sm-3 control-label">Gender</label>
            <div class="col-sm-9">
                <select id="gender" name="gender" class="form-control"
                        ng-model="selectedGender"
                        ng-options="g for g in gender"></select>
            </div>

            <label for="birthdate" class="col-sm-3 control-label">Birth Date</label>
            <div class="col-sm-9">
              
                <input type="text" class="form-control"
                       datepicker-popup="dd/mm/yyyy"
                       ng-model="BirthDate" is-open="opened"
                       close-text="Close"
                       />
            </div>
        </div>
    </fieldset>
    <fieldset>
        <legend>Address Information :</legend>
        <div class="form-group">
            <label for="currentaddress" class="col-sm-3 control-label">Current Address</label>
            <div class="col-sm-9">
                <textarea id="currentaddress" name="currentaddress"
                          ng-model="CurrentAddress" class="form-control"></textarea>
            </div>

            <label for="issameaddress" class="col-sm-3 control-label">Check is Same Address:</label>
            <div class="col-sm-9">
                <input type="checkbox" id="issameaddress"
                       name="issameaddress" ng-model="IsSameAddress"
                       class="form-control"
                       ng-change="SameAddress()" />
            </div>
            <label for="permanentaddress" class="col-sm-3 control-label">Permanent Address</label>
            <div class="col-sm-9">
                <textarea id="permanentaddress" name="permanentaddress"
                          ng-model="PermanentAddress" class="form-control"
                          ng-disabled="DisablesPermanentAddress"></textarea>
            </div>
        </div>
    </fieldset>
    <fieldset>
        <legend>Professional Information </legend>
        <div class="form-group">
            <div class="col-sm-3">
            </div>
            <div class="col-sm-9">

                <div class="radio">
                    <label>
                        <input type="radio" id="employeed" value="Employeed"
                               name="jobtype"
                               ng-model="Occupation" />Employeed
                    </label>
                </div>
                <div class="radio">
                    <label>
                        <input type="radio" id="selfemployeed"
                               ng-model="Occupation" name="jobtype" value="Self-Employeed" />Self-Employeed
                    </label>
                </div>
            </div>
        </div>
    </fieldset>
    <fieldset>
        <legend>Contact Infromation</legend>
        <div class="form-group">

            <label for="email" class="col-sm-3 control-label">Email</label>
            <div class="col-sm-9">
                <input type="text" id="email" name="email"
                       ng-model="Email" class="form-control" />
            </div>
            <label for="mobileno" class="col-sm-3 control-label">Mobile No.</label>
            <div class="col-sm-9">
                <input type="text" id="mobileno" name="mobileno"
                       ng-model="MobileNo" class="form-control" />
            </div>
        </div>
    </fieldset>

    <div class="col-sm-offset-3 col-sm-9">
        <input type="button" class="btn btn-default" value="Cancel"
               ng-click="cancelForm()" />
        <input type="button" class="btn btn-primary" value="Submit"
               ng-click="submitForm()" />
    </div>

</form>

The above html file defines the form containing UI elements for accepting PersonInformation. The UI is designed using HTML and the following Bootstrap classes:

· form-control

· col-sm-3

· col-sm-9

· control-label

The form also contains Angular UI Bootstrap element type using <input type=’text’ for DatePicker:

<input type="text" class="form-control"
                       datepicker-popup="dd/mm/yyyy"
                       ng-model="BirthDate" is-open="opened"
                       close-text="Close"
                       />

The DatePicker will be displayed as a popup with the date format as dd/mm/yyyy.

Now we have to use this form to display UI in our Index page. To do so, we can use the Custom Directive creation feature of Angular.js. In the MyScripts folder, add the following JavaScript file of the name pDirective.js.

pDirective.js

app.directive('personForm',
    function () {

        return {
            restrict: 'E',
            templateUrl: '/MyScripts/pTemplate.html'
        }

    });

The directive of name personForm is defined above. Angular will represent this as <person-form> in our view. The expression restrict: ‘E’ represents the directive to be used as Html element. The Html UI we created will be read using templateUrl property.

Step 6: In the project, add a new Empty MVC Controller of the name PersonInfoMVC. Scaffold the Index View from the Index action method of the controller class.

Step 7: In the Index.cshtml add the following html markup:

<html ng-app="personInfoModule">
<head>
    <title></title>
    <link href="~/Content/bootstrap.min.css" rel="stylesheet" />
    <script src="~/Scripts/angular.min.js"></script>
    <script src="~/Scripts/angular-ui/ui-bootstrap-tpls.min.js"></script>

    <script src="~/MyScripts/pModule.js"></script>
    <script src="~/MyScripts/pService.js"></script>
    <script src="~/MyScripts/pController.js"></script>

    <script src="~/MyScripts/pDirective.js"></script>
</head>
<body  class="container" ng-controller="personInfoController">
    <h1>
        Person Information Portal
    </h1>
    <person-form></person-form>
</body>
</html>

The above View contains the references for:

- bootstrap.min.css - bootstrap framework for high responsive UI

- angular.min.js - Angular Framework

- Ui-bootstrap-tpls-min.js - Angular UI Bootstrap for DataPicker.

- JavaScript files we have created in the previous steps.

The View has the HTML element <person-form> which we created in the previous steps with DataBinding.

Run the Application, the following UI will be displayed:

angular-ui

The above UI shows the DatePicker used using Angular UI bootstrap. Enter data in the fields and click on ‘Submit’. The data will be saved and the PersonId will be generated as shown here:

submit

Since we have used the Bootstrap, the page looks sleek and intuitive. The advantage of Bootstrap here is that if we resize the browser or browse the page in a Mobile/Tablet device, the UI will be automatically adjusted and displayed. Here’s a snapshot on a smaller screen size:

responsive-resize

Conclusion: Angular.js with Angular Bootstrap UI and Bootstrap.js helps us to design RICH and Responsive web applications. Using the custom directive feature provided by Angular, we can create reusable HTML UI and use it across Views.

In the next article, we will validate the form using Angular Validation Directives.

Download the entire source code of this article (Github)

Was this article worth reading? Share it with fellow developers too. Thanks!
Share on LinkedIn
Share on Google+
Further Reading - Articles You May Like!
Author
Mahesh Sabnis is a DotNetCurry author and Microsoft MVP having over 17 years of experience in IT education and development. He is a Microsoft Certified Trainer (MCT) since 2005 and has conducted various Corporate Training programs for .NET Technologies (all versions). Follow him on twitter @maheshdotnet


Page copy protected against web site content infringement 	by Copyscape




Feedback - Leave us some adulation, criticism and everything in between!
Comment posted by Saurabh Agrawal on Monday, February 2, 2015 10:51 PM
Thanks for the good article.

As a good practice, instead of having all properties such FirstName, LastName etc on $scope object directly, shouldn't we have an object such as "person" on $scope and set the properties for the same? eg for $scope.person.FirstName? This would help in the prototypal inheritance as well.
Comment posted by Sunil Kandi on Tuesday, February 3, 2015 11:51 PM
Good article. Thank you!

Instead of declaring each and every variable, we can include a ng-moodel="person.firstname", "person.lastname" on HTML inputs and send object "Person" to web api. That would eliminate lot of code.
Comment posted by MAhesh Sabnis on Wednesday, February 4, 2015 12:08 AM
Hi Saurabh and Suni
Thanks a lot for suggestions. I will follow this as a practice.
Thanks
Regards
Mahesh Sabnis

Comment posted by mohammad gho on Wednesday, February 4, 2015 7:33 AM
thanks - im reading your post evry day .
Comment posted by mohammad gho on Wednesday, February 4, 2015 7:34 AM
thanks - im reading your post evry day . and some time im translating to persian language and share in my web site int : http://tablokar.ir

Comment posted by SRIRAM on Friday, March 6, 2015 3:03 PM
The date picker idnt fired.. as like iin ur solution.