Introduction
In this article, we will be creating a responsive collapsible child grid using Angular js, bootstrap and jQuery. This tip provides only the source code for implementing master child grid.
Background
Basic knowledge of Angular JS and bootstrap is required.
Start With HTML
Create a home.html file into your application or project and add Bootstrap stylesheet into your HTML file. So here I'm adding bootstrap CSS file from CDN source.
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css"
rel="stylesheet" type="text/css" />
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<!--
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css"
rel="stylesheet" type="text/css" />
</head>
<body>
</body>
</html>
Initializing Angular
We need to setup Angular module and controller first, here is the code snippet. We will create a "homeController.js" JavaScript file and add the below code which initializes angular module and "homeController
" for us.
angular.module('app',[])
.controller('homeController', ['$scope', function ($scope) { }]);
Note: There is no dependency required, so I did not include any.
Setting Up $scope in JS Controller
In this "homeController
", I will be creating JSON object to bind a grid. But in the real time scenario will be calling WebAPI which returns JSON.
Now, I'm adding products JSON object with the following sample data inside the controller. This JSON object contains product and items data. We will use this for creating product master grid and items child grid creation.
angular.module('app',[])
.controller('homeController', ['$scope', function ($scope) {
$scope.products = [{
"productid": 1001456,
"productname": "Spring Season Gift",
"amount": 250,
"orderDate": "2015-02-15T00:00:00Z",
"availablity":1,
"items": [
{"prodDetailId": 17890,
"prodDetailDesc": "PS 3",
"amount": "150",
"qty":1
},{"prodDetailId": 17891,
"prodDetailDesc": "Heart shape Ring",
"amount": "100",
"qty": 1
},]
},{"productid": 1001457,
"productname": "Christmas Season Gift",
"amount": 349,
"orderDate": "2015-04-15T00:00:00Z",
"availablity": 1,
"items": [{
"prodDetailId": 17900,
"prodDetailDesc": "Choclate Giftbox",
"amount": "150",
"qty": 1
},{
"prodDetailId": 17901,
"prodDetailDesc": "Xbox 360",
"amount": "199",
"qty": 1
},]
},{
"productid": 1001458,
"productname": "Birthday Gift",
"availablity": "N/A",
"amount": 200
}];
}]);
Adding Script Files in HTML
We should add all the dependency JavaScript files below <body>
tag, here I'm adding Angular js , bootstrap and jQuery files from CDN source.
<script type="text/javascript"
src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.js"></script>
Now, we should add our "homeController.js" file into the home.html file.
<script type="text/javascript" src="homeController.js"></script>
Binding Angular in HTML
We will associate our angular module "app
" into home.html file, for this will use "data-ng-app
" directive in the <html>
tag.
For e.g.,
<html xmlns="http://www.w3.org/1999/xhtml" data-ng-app="app">
Finally, we will bind our "homeController
" against the div
tag.
For e.g.,
<div data-ng-controller="homeController">
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" data-ng-app="app">
<head>
<title></title>
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css"
rel="stylesheet" type="text/css" />
<link href="../css/customizedbs.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div data-ng-controller="homeController">
<!--
</div>
<!--
<script type="text/javascript"
src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.js"></script>
<script src="https://code.angularjs.org/1.3.11/angular-route.min.js"></script>
</body>
</html>
Adding Header
Let's add the header for the master grid called "Product
", I have used bootstrap CSS class to achieve responsive design "col-sm-1 col-xs-12
".
Note: I'm wrapping my grid with a container div
.
<div class="container">
<div class="row panel-heading bgOrg">
<div class="col-sm-1 col-xs-12 pull-left">#</div>
<div class="col-sm-2 col-xs-12">Product ID</div>
<div class="col-sm-3 col-xs-12">Product Name</div>
<div class="col-sm-2 col-xs-12">Amount</div>
<div class="col-sm-2 col-xs-12">Order Date</div>
<div class="col-sm-2 col-xs-12">#Avail</div>
</div>
<!--
</div>
Populate Grid
We will bind our master grid called "Product
" by using "data-ng-repeat
" directive to populate the grid. Here, I'm using bootstrap collapse, so I need to specify my child grid id, which is not ready yet. We will discuss this in the below section.
<div ng-repeat="product in products">
<div class="row panel panel-body">
<div class="col-xs-1">
<div class="handpointer glyphicon glyphicon-chevron-right"
data-ng-click="collapse($event)" data-target="#view_{{product.productid}}"
data-toggle="collapse" aria-expanded="false"
aria-controls="view_{{product.productid}}"
data-ng-if="product.items!=null">
</div>
</div>
<div class="col-sm-2 col-xs-12" data-ng-bind="product.productid"></div>
<div class="col-sm-3 col-xs-12" data-ng-bind="product.productname"></div>
<div class="col-sm-2 col-xs-12" data-ng-bind="product.amount | currency"></div>
<div class="col-sm-2 col-xs-12" data-ng-bind="product.orderDate |
date: 'MM/dd/yyyy'"></div>
<div class="col-xs-2 col-xs-1" data-ng-bind="product.availablity"></div>
</div>
</div>
Note: Below div tag is our "expand icon", our goal is on click show child grid.
<div class="handpointer glyphicon glyphicon-chevron-right"
data-ng-click="collapse($event)" data-toggle="collapse"
?aria-expanded="false" aria-controls="view_{{product.productid}}">
Our child grid data is called "Items
" inside the Product
JSON, we should show expand icon only if child record exists. So I have added "data-ng-if
" directive inside the div
tag to do this check.
For e.g.,
data-ng-if="product.items!=null
We should show a different icon ("glyphicon-chevron-down
") on collapse, this is handled using "collapse
" function inside the controller. Now we will add "data-ng-click
" directive in expand icon div
tag to invoke "collapse($event)
". To change the CSS against div
, we are passing $event
to the collapse
function.
Now add the below code in the homeController.js file:
$scope.collapse = function (event) {
$(event.target).toggleClass("glyphicon-chevron-down");
};
Child Grid and Collapse
Here I'm binding the child grid called "Items
", now we need a unique id to address the child grid. This is needed to show child grid on click of the parent grid record. So, we will add unique product id against the child grid.
Decorate child grid with collapse
class, so that it will be collapsed on page load.
<div class="collapse" id="view_{{product.productid}}" data-ng-if="product.items!=null">
<div class="col-sm-offset-1">
<table class="table-condensed responsive-table">
<tr class="row">
<th>#ID</th>
<th>Item</th>
<th>Amount</th>
<th>Qty</th>
</tr>
<tr class="row" ng-repeat="item in product.items">
<td data-ng-bind="item.prodDetailId"></td>
<td data-ng-bind="item.prodDetailDesc"></td>
<td data-ng-bind="item.amount | currency"></td>
<td data-ng-bind="item.qty"></td>
</tr>
</table>
</div>
</div>
Our goal is, on "expand icon" click show child grid. In order to map this, we have to specify the child grid target id against the parent grid "expand icon" div.
This is accomplished by specifying "data-target
" attribute with "#view_{{product.productid}}
" child grid id , so this is required for mapping "product
" master and "items
" child grid.
<div class="handpointer glyphicon glyphicon-chevron-right"
data-ng-click="collapse($event)" data-target="#view_{{product.productid}}"
?data-toggle="collapse" aria-expanded="false" >
Note: data-target="#id" - # represents selector
Custom Stylesheet
Here, I have added my custom stylehseet to decorate the grid, used handpointer class to show hand icon against "product
" grid expand click icon.
.handpointer {
cursor:pointer;
}
.responsive-table {
color: #000;
overflow: hidden;
width:100%;
border-radius: 5px;
background-color:#eaebee;
}
.responsive-table tr {
border-bottom: 1px solid #dcdfe5;
}
.responsive-table th,.responsive-table td {
padding-left: 15px !important;
}
.responsive-table tr:last-child {
border-bottom: 0px;
}
a:focus {
-moz-outline-style: none;
}
a, a:active, a:focus {
outline: none;
}
.bgOrg {
background-color:#fa902b;
color:#fff;
}
Note
This article just provides the source code for implementing master child grid using Angular JS.