Introduction
AngularJS provides various features. One of them is 2-way data binding. In this article, I will explain how to create Grid dynamically using Angular.
Download the requred JavaScript and css files from the below links
Get Started
- Open Visual Studio and create a new MVC web application.
- Copy the downloaded AngularJS file in "Scripts" folder of the solution.
- Create a JavaScript file and name it as Module.js.
- Then, write the following code in it.
- var app = angular.module("myApp",[]);
- Create another JavaScript file and name it as Controller.js.
- Start writing code as given below.
- app.controller("gridController", function($scope, $rootScope) {
- var data = [];
- var columns = [];
- columns.push({
- "key": "Status",
- "width": "5%",
- "dataType": "status",
- "showTags": "false",
- "showColumns": "true"
- });
- columns.push({
- "key": "ID",
- "width": "1%",
- "dataType": "string",
- "showTags": "false",
- "showColumns": "true"
- });
- columns.push({
- "key": "Critical",
- "width": "1%",
- "dataType": "bool",
- "showTags": "true",
- "showColumns": "false"
- });
- columns.push({
- "key": "CSM",
- "width": "1%",
- "dataType": "bool",
- "showTags": "true",
- "showColumns": "false"
- });
- columns.push({
- "key": "E0/EC0",
- "width": "1%",
- "dataType": "bool",
- "showTags": "true",
- "showColumns": "true"
- });
- columns.push({
- "key": "MT2",
- "width": "5%",
- "dataType": "bool",
- "showTags": "true",
- "showColumns": "false"
- });
- columns.push({
- "key": "MT3",
- "width": "5%",
- "dataType": "bool",
- "showTags": "true",
- "showColumns": "false"
- });
- columns.push({
- "key": "Component",
- "width": "9%",
- "dataType": "string",
- "showTags": "false",
- "showColumns": "true"
- });
- columns.push({
- "key": "Class Code",
- "width": "3%",
- "dataType": "string",
- "showTags": "false",
- "showColumns": "true"
- });
- columns.push({
- "key": "Caption",
- "width": "13%",
- "dataType": "string",
- "showTags": "false",
- "showColumns": "true"
- });
- columns.push({
- "key": "Dept",
- "width": "1%",
- "dataType": "string",
- "showTags": "false",
- "showColumns": "true"
- });
- columns.push({
- "key": "Rank",
- "width": "1%",
- "dataType": "string",
- "showTags": "false",
- "showColumns": "true"
- });
- columns.push({
- "key": "Interval",
- "width": "3%",
- "dataType": "string",
- "showTags": "false",
- "showColumns": "true"
- });
- columns.push({
- "key": "Start Date",
- "width": "4%",
- "dataType": "date",
- "showTags": "false",
- "showColumns": "false"
- });
- columns.push({
- "key": "End Date",
- "width": "4%",
- "dataType": "date",
- "showTags": "false",
- "showColumns": "false"
- });
- columns.push({
- "key": "Date/ Hours",
- "width": "3%",
- "dataType": "date",
- "showTags": "false",
- "showColumns": "true"
- });
- columns.push({
- "key": "Action",
- "width": "4%",
- "dataType": "commands",
- "showTags": "false",
- "showColumns": "true"
- });
- $rootScope.columns = eval(columns);
- data.push({
- "Status": [{
- "val": "Overdue",
- "color": "label label-danger"
- }],
- "Start Date": "2017-05-11",
- "End Date": "2017-05-11",
- "Critical": "true",
- "CSM": "true",
- "E0/EC0": "false",
- "MT2": "CRI",
- "Component": "Me Cyl. Head [6]",
- "Class Code": "MDECYA",
- "Caption": "OVH, TST, CLN OF Me Cyl. Head [6]",
- "Dept": "ENG",
- "Rank": "2E",
- "ID": "00006",
- "Interval": "6000 R/Hs",
- "Date/ Hours": "6129 R/Hs",
- "Action": ""
- });
- data.push({
- "Status": [{
- "val": "Overdue",
- "color": "label label-danger"
- }, {
- "val": "P",
- "color": "label label-info",
- "title": "Planned"
- }],
- "Start Date": "2017-05-09",
- "End Date": "2017-05-11",
- "Critical": "false",
- "CSM": "false",
- "E0/EC0": "false",
- "Component": "Me Injector Valves W/Pipes [3]",
- "Class Code": "MDECYA",
- "Caption": "TST, INSP OF Me Injector Valves W/Pipes [3]",
- "Dept": "ENG",
- "Rank": "CE",
- "ID": "00011",
- "Interval": "500 R/Hs",
- "Date/ Hours": "2812 R/Hs",
- "Action": ""
- });
- data.push({
- "Status": [{
- "val": "Due",
- "color": "label label-success"
- }],
- "Start Date": "2017-05-01",
- "End Date": "2017-05-01",
- "Critical": "true",
- "CSM": "true",
- "E0/EC0": "true",
- "Component": "Me Fo Pre-Heater",
- "Class Code": "",
- "Caption": "TST, CLN, INSP OF Me Fo Pre-Heater",
- "Dept": "ENG",
- "Rank": "2E",
- "ID": "00150",
- "Interval": "30 M",
- "Date/ Hours": "5/20/2017",
- "Action": ""
- });
- data.push({
- "Status": [{
- "val": "Overdue",
- "color": "label label-danger"
- }],
- "Start Date": "2017-05-04",
- "End Date": "2017-05-04",
- "Critical": "false",
- "CSM": "false",
- "E0/EC0": "true",
- "Component": "Me Flowmeter",
- "Class Code": "",
- "Caption": "INSP, CLN OF Me Flowmeter",
- "Dept": "ENG",
- "Rank": "2E",
- "ID": "00151",
- "Interval": "30 M",
- "Date/ Hours": "5/19/2017",
- "Action": ""
- });
- data.push({
- "Status": [{
- "val": "Due",
- "color": "label label-success"
- }],
- "Start Date": "2017-05-04",
- "End Date": "2017-05-04",
- "Critical": "true",
- "CSM": "true",
- "E0/EC0": "true",
- "Component": "Ae Cyl. Head [1] [3]",
- "Class Code": "MDECYA",
- "Caption": "OVH, INSP OF Ae Cyl. Head [1] [3]",
- "Dept": "ENG",
- "Rank": "3E",
- "ID": "00164",
- "Interval": "1500 R/Hs",
- "Date/ Hours": "3845 R/Hs",
- "Action": ""
- });
- data.push({
- "Status": [{
- "val": "Due",
- "color": "label label-success"
- }],
- "Start Date": "2017-05-01",
- "End Date": "2017-05-02",
- "Critical": "false",
- "CSM": "false",
- "E0/EC0": "true",
- "Component": "D/E Frequency Low [1]",
- "Class Code": "",
- "Caption": "TST, INSP OF D/E Frequency Low [1]",
- "Dept": "ENG",
- "Rank": "ETO",
- "ID": "00922",
- "Interval": "6 M",
- "Date/ Hours": "11/14/2016",
- "Action": ""
- });
- data.push({
- "Status": [{
- "val": "Overdue",
- "color": "label label-danger"
- }],
- "Start Date": "2017-05-24",
- "End Date": "2017-05-26",
- "Critical": "true",
- "CSM": "false",
- "E0/EC0": "true",
- "Component": "Boiler Fo Booster Pump Stbd",
- "Class Code": "",
- "Caption": "OVH, INSP OF Boiler Fo Booster Pump Stbd",
- "Dept": "ENG",
- "Rank": "2E",
- "ID": "00470",
- "Interval": "30 M",
- "Date/ Hours": "5/6/2017",
- "Action": ""
- });
- data.push({
- "Status": [{
- "val": "Overdue",
- "color": "label label-danger"
- }],
- "Start Date": "2017-05-14",
- "End Date": "2017-05-26",
- "Critical": "false",
- "CSM": "false",
- "E0/EC0": "true",
- "Component": "Boiler Safety Valve",
- "Class Code": "",
- "Caption": "OVH, INSP OF Boiler Safety Valve",
- "Dept": "ENG",
- "Rank": "3E",
- "ID": "00473",
- "Interval": "12 M",
- "Date/ Hours": "9/23/2016",
- "Action": ""
- });
- data.push({
- "Status": [{
- "val": "Due",
- "color": "label label-success"
- }],
- "Start Date": "2017-05-29",
- "End Date": "2017-05-14",
- "Critical": "false",
- "CSM": "false",
- "E0/EC0": "true",
- "Component": "Air Condition Condenser",
- "Class Code": "",
- "Caption": "TST, INSP OF Air Condition Condenser",
- "Dept": "ENG",
- "Rank": "2E",
- "ID": "00554",
- "Interval": "30 M",
- "Date/ Hours": "6/1/2017",
- "Action": ""
- });
- data.push({
- "Status": [{
- "val": "Overdue",
- "color": "label label-danger"
- }],
- "Start Date": "2017-05-11",
- "End Date": "2017-05-29",
- "Critical": "false",
- "CSM": "false",
- "E0/EC0": "true",
- "Component": "Sludge Pump",
- "Class Code": "",
- "Caption": "OVH, INSP OF Sludge Pump",
- "Dept": "ENG",
- "Rank": "2E",
- "ID": "00588",
- "Interval": "30 M",
- "Date/ Hours": "5/22/2017",
- "Action": ""
- });
- data.push({
- "Status": [{
- "val": "Overdue",
- "color": "label label-danger"
- }],
- "Start Date": "2017-05-13",
- "End Date": "2017-05-11",
- "Critical": "false",
- "CSM": "false",
- "E0/EC0": "true",
- "Component": "Bilge Filters",
- "Class Code": "",
- "Caption": "CLN, INSP OF Bilge Filters",
- "Dept": "ENG",
- "Rank": "2E",
- "ID": "00589",
- "Interval": "1 M",
- "Date/ Hours": "9/5/2016",
- "Action": ""
- });
- data.push({
- "Status": [{
- "val": "Overdue",
- "color": "label label-danger"
- }],
- "Start Date": "2017-05-11",
- "End Date": "2017-05-14",
- "Critical": "false",
- "CSM": "false",
- "E0/EC0": "true",
- "Component": "Emergency Bilge Suction - Er",
- "Class Code": "",
- "Caption": "TST, INSP OF Emergency Bilge Suction - Er",
- "Dept": "ENG",
- "Rank": "2E",
- "ID": "00591",
- "Interval": "1 M",
- "Date/ Hours": "9/5/2016",
- "Action": ""
- });
- data.push({
- "Status": [{
- "val": "Overdue",
- "color": "label label-danger"
- }],
- "Start Date": "2017-05-14",
- "End Date": "2017-05-13",
- "Critical": "false",
- "CSM": "false",
- "E0/EC0": "true",
- "Component": "Hydraulic For Operating Valve System",
- "Class Code": "",
- "Caption": "ANL, INSP OF Hydraulic For Operating Valve System",
- "Dept": "ENG",
- "Rank": "2E",
- "ID": "00594",
- "Interval": "6 M",
- "Date/ Hours": "12/2/2016",
- "Action": ""
- });
- $rootScope.gridData = eval(data);
- });
- Here, we have static JSON data in the same way you do with the db data.
- Data is in the form of array objects.
- In every column object, we have multiple key value pairs.
- In the object showTags, the key is used to merge multiple boolean columns into one column as tags.
- showColumns is used for show and hide of columns.
- Other keys serve the same purpose as the name given to them.
- $rootScope is available globally in the whole application that is we can set rootscope in 1 controller and access the value in other controller with rootscope.
- we store the array of columns in $scope.columns and array of data in $rootScope.gridData.
- We are going to access these in View for binding of data.
In the Index view of home controller, start writing the following code.
- <html ng-app = "myApp">
- <body>
- <div class="table-responsive" ng-controller="gridController">
- <table class="table table-striped table-bordered table-hover dataTables-example">
- <thead>
- <tr>
- <th ng-repeat="column in columns" width="{{column.width}}" ng-if="column.showColumns == 'true' && column.dataType != 'commands' && column.dataType != 'bool'">
- <b>{{column.key}}</b>
- </th>
- <th ng-repeat="column in columns" ng-if="column.dataType == 'bool' && column.showColumns=='true'" width="5%">Tags</th>
- <th aria-sort="descending" ng-repeat="column in columns" width="{{column.width}}" ng-if="column.showColumns == 'true' && column.dataType == 'commands'">{{column.key}}</th>
- </tr>
- </thead>
- <tbody>
- <tr ng-class="{'primaryRow':rowIndex===key}" data-ng-repeat="(key,val) in gridData">
- <td ng-repeat="column in columns" class="project-status" ng-if="column.dataType== 'status' && column.showColumns == 'true'">
- <span ng-repeat="col in column" ng-class="val[col][0].color">{{val[col][0].val}}</span>
- </td>
- <td ng-repeat="column in columns" class="project-title" ng-if="column.dataType == 'string' && column.showColumns == 'true'">{{val[column.key]}}
- </td>
- <td ng-repeat="column in columns" class="project-title" ng-if="column.dataType == 'date' && column.showColumns == 'true'" style="text-align: right;">{{val[column.key]}}
- </td>
- <td ng-repeat="column in columns" class="project-title" ng-if="column.dataType == 'check' && column.showColumns == 'true'">
- <input type="checkbox" ng-checked="{{val[column.key]}}" disabled />
- </td>
- <td class="project-title">
- <span id="tagSpan" ng-if="column.showTags == 'true' && val[column.key] == 'true'" ng-repeat="column in columns" class="label label-default">{{column.key}}</span>
- <span ng-hide="true">{{val[column.key]}}</span>
- </td>
- <td ng-repeat="column in columns" ng-if="column.key == 'Action'">
- <a>@Html.ActionLink("View", "ActionName", "ControllerName", new { @class = "btn btn-xs btn-success" })</a>
- </td>
- </tr>
- </tbody>
- </table>
- </div>
- </body>
- </html>
- Put ng-app directive on html tag and ng-controller on div tag.
- Here in the view we created key value pairs.
- We automized the entire grid without hardcoding the name of single column in grid.
- We use ng-repeat for automizing the entire json.
- Columns are created by putting ng-repeat on th. Example : <th ng-repeat = "column in Columns">column.key</th>.
- Show and hide the columns by putting column.showColumns key on tags.
- We also put multiple conditions and set different styles by iterating.
- It iterates as many times as number of keys in $scope.columns.
- Similarly row data are created by iterating $scope.gridData with column key.Example : <tr ng-repeat="(key,val) in gridData"><td ng-repeat="column in Columns"> val[column.key]</td></tr>.
- Include scripts in bundle config.cs.
- bundles.Add(new ScriptBundle("~/bundles/angular").Include(
- "~/Scripts/angular1.5.5.min.js",
- "~/Scripts/Module.js",
- "~/Scripts/Controller.js"));
- Add this bundle in RegisterBundle method in BundleConfig.cs file.
- Include bundle on layout page as given below.
- @Scripts.Render("~/bundles/jquery")
- @Scripts.Render("~/bundles/bootstrap")
- @Scripts.Render("~/bundles/angular")
Now, run the application and get the result.