Thursday 5 October 2017

AngularJS Routing Using UI-Router ($stateProvider)

AngularJS Routing
In This Article, I would Like To Know You About The Routing In AngularJS. For Routing Concept, We Have stateProvider And routeProvider Providers, As routeProvider Is By Default In AngularJS, But stateProvider Is Third Party Provider. To Use routeProvider, We have To Use ‘ngRoute’ In Module Declaration, And For stateProvider, We Have To Use ‘ui-router’.
The stateProvider Is Having More Features Than routeProvider, As Using routeProvider, The Page
Is Having Only Single View, Like <div ng-view></div>.
But By Using stateProvider, The Page Is Having Multiple Views Like
<div ui-view>
    <div ui-view='header'></div>
    <div ui-view='content'></div>
    <div ui-view='footer'></div>
 </div>
And Also It Supports Nested Views
In This Article I Used stateProvider, As It Is Having More Features Than routeProvider.

The Below Code Illustrates About The Routing In AngularJS

Index.html

<!DOCTYPE html>
<html>
<head>

    <!-- The Below CSS Is To Load Bootstrap -->
    <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">
    <style>
        .navbar {
            border-radius: 0;
        }
    </style>

    <!-- The Below JS Is For Anuglar -->
    <script src="http://code.angularjs.org/1.2.13/angular.js"></script>
    <!-- The Below JS Is For ui-router -->
    <script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.8/angular-ui-router.min.js"></script>
    <!-- The Below app.js File Is To Define The Angular Application And Routings -->
    <script src="app.js"></script>
    <!-- The Below js Files Are The Content That We Inject In Single Page Application -->
    <script src="Controllers/Search.js"></script>
    <script src="Controllers/AddRemove.js"></script>
</head>

<!-- Applying Root Element Of AngularJS To HTML Body -->
<body ng-app="AngularRoutingApplication">

    <!-- Navigation Menubar -->
    <nav class="navbar navbar-inverse" role="navigation">
        <ul class="nav navbar-nav">
            <li><a ui-sref="home" ui-sref-active="active">Home</a></li>
            <li><a ui-sref="search" ui-sref-active="active">Search</a></li>
            <li><a ui-sref="addremove" ui-sref-active="active">AddRemove</a></li>
        </ul>
    </nav>

    <!-- Main Content -->
    <div class="container">

        <!-- The Content Will Inject Here -->
        <div ui-view></div>

    </div>

</body>
</html>


In The app.js File The Routings Will Defined

App.js
var angpp = angular.module("AngularRoutingApplication", ['ui.router']);
angpp.config(function ($stateProvider, $urlRouterProvider, $locationProvider) {
   // $locationProvider.hashPrefix('!');//To Add ! After # in URL
   // $locationProvider.html5Mode(true); //To Remove # from URL
    $urlRouterProvider.otherwise("/home");  //default display page (default routing)
    $stateProvider
    var homeState = {
        name: 'home',
        url: '/home',
        templateUrl: 'Views/home.html',
       // controller: 'HomeController'
    }
    $stateProvider.state(homeState);
    var searchState = {
        name: 'search',
        url: '/search',
        templateUrl: 'Views/Search.html',
        controller: 'SearchController'
    }
    $stateProvider.state(searchState);
    var addremoveState = {
        name: 'addremove',
        url: '/addremove',
        templateUrl: 'Views/AddRemove.html',
        controller: 'AddRemoveController'
    }
    $stateProvider.state(addremoveState);
   
})

Now The Other Pages That We have To Inject Is Also Defined As Below And The Folder Structure Is As Below :


Home.html
<div>
    <h2> I am The Home Page</h2>
</div>

Now The Below HTML Code Is For Search Functionality Which We Are Injecting In The Index.html Page:

Search.html
<div class="form-group container">
    <div class="row">
        <h3>AngularJS - Search Record From List</h3>
    </div>
    <div class="row" style="position:relative">
        <div class="col-md-3">
            <label>Item Code</label>
            <input type="text" name="itemcode" class="form-control" id="itemcode" ng-model="searchItemCode" />
        </div>
        <div class="col-md-3">
            <label>Item Name</label>
            <input type="text" name="itemname" class="form-control" id="itemname" ng-model="searchItemName" />
        </div>
        <div class="col-md-3">
            <label>Item Price</label>
            <input type="text" name="itemprice" class="form-control" id="itemprice" ng-model="searchItemPrice" />
        </div>
        <!--Here I am using style also, because the alignment of button control is displaying horizontally along with labels of Item Code, Item Name, Item Price,
        but what we need is it has to display along with input text boxes, so applying style="position:absolute;bottom:0;right:0;", the button controls display along with textbox controls horizontally-->
        <div class="col-md-3" style="position:absolute;bottom:0;right:0;">
            <button type="button" name="search" class="btn btn-primary" id="search" ng-click="SearchItems()">Search</button>
            <button type="button" name="clear" class="btn btn-danger" id="clear" ng-click="ClearTextBoxes()">Clear</button>
        </div>
    </div>
    <div class="row">
        <div class="table-responsive">
            <table class="table">
                <thead>
                    <tr>
                        <th>Item Code</th>
                        <th>Item Name</th>
                        <th>Item Price</th>
                    </tr>
                </thead>
                <tr ng-show="filteredItems.length!=0" ng-repeat="item in filteredItems">
                    <td>{{ item.ItemCode}}</td>
                    <td>{{ item.ItemName}}</td>
                    <td>{{ item.ItemPrice}}</td>
                </tr>
                <tr ng-show="filteredItems.length==0" style="text-align:center;font-size:xx-large;color:lightgrey;font:bold 400% arial, verdana;">
                    <td>
                        No Records Found
                    </td>
                </tr>
            </table>
        </div>
    </div>
</div>

Now Search.html Related JS Code Is Also Added As Below :

angpp.controller('SearchController', function ($scope, $window) {
    $scope.ItemDetails = [
        {
            ItemCode: "KB384", ItemName: "KeyBoard",
            ItemPrice: "500"
        },
    {
        ItemCode: "MU932",
        ItemName: "Mouse",
        ItemPrice: "200"
    },
    {
        ItemCode: "PD843",
        ItemName: "Pendrive",
        ItemPrice: "400"
    },
    {
        ItemCode: "DV0495",
        ItemName: "DVD Drive",
        ItemPrice: "1000"
    }]; //To Declare List
    $scope.filteredItems = $scope.ItemDetails;
    $scope.ClearTextBoxes = function () {
        $window.location.reload();
        //$scope.searchItemCode = '';
        //$scope.searchItemName = '';
        //$scope.searchItemPrice = '';
    }
    $scope.SearchItems = function () {
        $scope.filteredItems = [];
        $scope.ItemDetails.forEach(function (item) {
            if (!$scope.searchItemCode && !$scope.searchItemName && !$scope.searchItemPrice) {

                $scope.filteredItems = $scope.ItemDetails;

            }
            else {
                var result = searchTable(item, $scope.searchItemCode, $scope.searchItemName, $scope.searchItemPrice);
                if (result)
                    $scope.filteredItems.push(item);
            }
        })

    }

    function searchTable(item, searchItemCode, searchItemName, searchItemPrice) {

        return ((searchItemCode ? item.ItemCode.toLowerCase().indexOf(searchItemCode.toLowerCase()) : -1) > -1 || (searchItemName ? item.ItemName.toLowerCase().indexOf(searchItemName.toLowerCase()) : -1) > -1 || item.ItemPrice == searchItemPrice) ? true : false;

    }
});

Now  Another HTML Code To Inject Another Page To Index.html To Display When Navigate i.e., AddRemove Functionality :

AddRemove.html
<div class="form-group container">
    <div class="row">
        <h3>AngularJS - Add And Remove/Delete Item From List</h3>
    </div>
    <div class="row" style="position:relative;">
        <div class="col-md-3">
            <label>Item Code</label>
            <input type="text" name="itemcode" class="form-control" id="itemcode" ng-model="ItemCode" />
        </div>
        <div class="col-md-3">
            <label>Item Name</label>
            <input type="text" name="itemname" class="form-control" id="itemname" ng-model="ItemName" />
        </div>
        <div class="col-md-3">
            <label>Item Description</label>
            <input type="text" name="itemdescription" class="form-control" id="itemdescription" ng-model="ItemDescription" />
        </div>
        <div class="col-md-3" style="position:absolute;right:0;bottom:0;">
            <button type="button" name="addtolist" class="btn btn-primary" id="addtolist" ng-click="AddToList()">Add To List</button>
        </div>
    </div>
    <span ng-show="showspan" style="font-size:medium;color:red">{{warningmsg}}</span>
    <div class="row">
        <div class="table-responsive">
            <table class="table">
                <thead>
                    <tr>
                        <th>Item Code</th>
                        <th>Item Name</th>
                        <th>Item Description</th>
                        <th>Action</th>
                    </tr>
                </thead>
                <tr ng-repeat="item in ItemDetails">
                    <td>{{ item.ItemCode}}</td>
                    <td>{{ item.ItemName}}</td>
                    <td>{{ item.ItemDescription}}</td>
                    <td><button type="button" name="delete" class="btn btn-danger" ng-click="DeleteItem(item)">Delete</button></td>
                </tr>
            </table>
        </div>
    </div>
</div>

Now AddRemove.html Related JS File Is Added :

AddRemove.js

angpp.controller('AddRemoveController', function ($scope) {
    $scope.ItemDetails = []; //To Declare List
    $scope.showspan = false; // false is to hide the scope
    $scope.AddToList = function () {
        $scope.AlreadyExistsInList = false;
        if ($scope.ItemCode && $scope.ItemName && $scope.ItemDescription) // this condition is to not allow the empty or undefined or false or 0 in to the braces
        {
            if ($scope.ItemDetails.length > 0)
                $scope.ItemDetails.forEach(function (item) { // To check whether the newly adding item is exists or not
                    if (item.ItemCode.toLowerCase() == $scope.ItemCode.toLowerCase() && item.ItemName.toLowerCase() == $scope.ItemName.toLowerCase() && item.ItemDescription.toLowerCase() == $scope.ItemDescription.toLowerCase()) {
                        $scope.AlreadyExistsInList = true;
                    }
                });

            if (!$scope.AlreadyExistsInList) { // If not added, then it should added to the list, otherwise it should go to else condition and show warning message
                $scope.showspan = false;
                $scope.ItemDetails.push({ ItemCode: $scope.ItemCode, ItemName: $scope.ItemName, ItemDescription: $scope.ItemDescription }); // this is used to push i.e., add the data in the list
                //to clear textboxes after add item to list
                $scope.ItemCode = "";
                $scope.ItemName = "";
                $scope.ItemDescription = "";
            }
            else {
                $scope.warningmsg = "This Record Is Already Exists";
                $scope.showspan = true;
            }
            if (!$scope.ItemDetails.length)  // this condition is to insert first record when List ItemDetails Is Empty
            {
                $scope.ItemDetails.push({ ItemCode: $scope.ItemCode, ItemName: $scope.ItemName, ItemDescription: $scope.ItemDescription });
                //to clear textboxes after add item to list
                $scope.ItemCode = "";
                $scope.ItemName = "";
                $scope.ItemDescription = "";

            }
        }
        else {
            $scope.warningmsg = "Please Enter All Input TextBox Details";
            $scope.showspan = true;
        }
    }
    $scope.DeleteItem = function (item) {
        var index = $scope.ItemDetails.indexOf(item); //this is to read the index value of the list
        if (index != -1)
            $scope.ItemDetails.splice(index, 1); // splice is used to remove the given index value
        // '1' is used to remove only 1 index value, if it is two , two index values will be removed from the specified index
    }
});

The Output Will Be As Below :


The Home Page Is Displayed As Below :


    After Navigate To Search Page Is Displayed As Below :


     After Navigate To AddRemove Page Is Displayed As Below :


No comments:

Post a Comment

Note: only a member of this blog may post a comment.