Angular.js Grid Example
We all know that Angular is the most famous JavaScript framework, at this time and one of the main reasons that lead it to the top is that it provides many modules, ready to ease your development effort. So, what about tables? Is there any angular module, in order to avoid using the old-stylish HTML markup?
1. Introduction
Obviously, there are many more-specific modules around the market, so table-related exist for sure, too.
2. A Basic Example
First of all, let’s take a look on a very basic table creation with Angular, without using any external module. This will contain two rows for the first and last name, an auto-updated field for representing the full name of the customer, according to the input provided and some ratings of the customer, according to a predefined set of cars. The above describe a situation as the following screenshot depicts:
A small parenthesis before delving deeper in the javascript explanation of the above snippet: There is a common case that one may want his table to be displayed in a zebra-stylish format. According to a clean Angular app (without using any table modules), this is feasible by using the CSS3 :nth-child() Selector.
<html> <head> <title>Angular.js Table</title> <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js"></script> <style> table, th , td { border: 1px solid grey; border-collapse: collapse; padding: 5px; } table tr:nth-child(odd) { background-color: #f2f2f2; } table tr:nth-child(even) { background-color: #ffffff; } </style> </head> <body> <h2>Angular.js Simple Table</h2> <div ng-app="mainApp" ng-controller="customerController"> <table border="0"> <tr> <td>First name:</td><td><input type="text" ng-model="customer.firstName"></td> </tr> <tr> <td>Last name: </td><td><input type="text" ng-model="customer.lastName"></td> </tr> <tr> <td>Full name: </td><td>{{customer.fullName()}}</td> </tr> <tr><td>Expectations:</td><td> <table> <tr> <th>Car</th> <th>Rating</th> </tr> <tr ng-repeat="rating in customer.ratings"> <td>{{ rating.car }}</td> <td>{{ rating.mark }}</td> </tr> </table> </td></tr> </table> </div> <script> var mainApp = angular.module("mainApp", []); mainApp.controller('customerController', function($scope) { $scope.customer = { firstName: "", lastName: "", ratings:[ {car:'BMW 316 E46', mark:77}, {car:'BMW 316 E92', mark:89}, {car:'BMW M3 E92', mark:94}, {car:'BMW M3 e46', mark:90}, {car:'BMW X6', mark:85} ], fullName: function() { var customerObject; customerObject = $scope.customer; return customerObject.firstName + " " + customerObject.lastName; } }; }); </script> </body> </html>
Having read the fore-mentioned parenthesis, everything according to the style of this example should be clear enough, so let’s get into the table instance.
Lines 24 and 27 bind the user’s input for first and last name to the controller (in our case, it is named as “customerController”), by using a $scope
object. This is done using the ng-model
directive, which indeed has many features, but the one that is helpful here is that it binds the view into the model, which other directives such as input, textarea or select require.
Here are the rest features for the ng-bind
directive:
- Provides validation behavior (i.e. required, number, email, url)..
- Keeps the state of the control (valid/invalid, dirty/pristine, touched/untouched, validation errors).
- Sets related css classes on the element (ng-valid, ng-invalid, ng-dirty, ng-pristine, ng-touched, ng-untouched) including animations.
- Registers the control with its parent form.
What is also important to take into account, is that ngModel
will try to bind to the property given by evaluating the expression on the current scope. This means that if the property doesn’t already exist on this scope, it will be created implicitly and added to the scope.
Line 30 uses the double curly brace notation {{ }}
to bind expressions to elements . You can imagine it as a quick way to write variable elements to the HTML part of your app. Specifically, what it implements in our case, is binding in HTML the fullName variable’s value from the customer object, which is taken from the controller’s fullName
function (lines 60-64).
The fore-mentioned function takes the customer object and according to the binded input from the first and last name text fields, produces the full name of the customer, by injecting the $scope
object. The rest of customer’s attributes first/last name (defining them with empty value in the controller means that on page load, no value will appear on them and only on an input event in the corresponding text fields, the full name will be updated.
Finally, lines 38-41 iterate over the ratings array of the customer object, using the ng-repeat
directive, in order to display the customer’s expectations according to each car that he drove.
3. Table Example with ng-table
In any case, the default HTML-ish representation of tables seems to be somehow old fashioned, regarding the evolution of the Bootstrap framework and web development, in overall.
For this reason, a lot of table initiatives have started, in order to provide a better Angular.js table implementation. Some of them are SmartTable, ng-table and ui-grid.
Here we ‘ll go for ng-table, as it’s very easy to setup.
3.1 Configure ng-table
Just like in any other external module, we have to include its JavaScript and CSS references. This is translated to the following two lines:
<script src="https://www.webcodegeeks.com/wp-content/litespeed/localres/aHR0cHM6Ly9jZG4uanNkZWxpdnIubmV0Lw==angular.ngtable/1.0.0-alpha.5/ng-table.js"></script> <link rel="stylesheet" href="https://www.webcodegeeks.com/wp-content/litespeed/localres/aHR0cHM6Ly9jZG4uanNkZWxpdnIubmV0Lw==angular.ngtable/1.0.0-alpha.5/ng-table.css">
3.2 Use ng-table
Let’s now display a table similar to the one used int the fore-mentioned example: two columns for name and age, with some data into it.
<div ng-controller="DemoCtrl"> <table ng-table class="table"> <tr ng-repeat="user in users"> <td title="'Name'"> {{user.name}} </td> <td title="'Age'"> {{user.age}} </td> </tr> </table> <script> var app = angular.module('main', ['ngTable']). controller('DemoCtrl', function($scope) { $scope.users = [{name: "Moroni", age: 50}, {name: "Tiancum", age: 43}, {name: "Jacob", age: 27}, {name: "Nephi", age: 29}, {name: "Enos", age: 34}]; }) </script> </div>
In line 1, an ng-controller
is attached to the table, which means that a controller class is attached to the table’s view.
In our case, we want the model part of the controller to only contain the dummy data that will be displayed to the view, through this controller. Assuming that we want these data to be save in a $scope
variable (let’s say “users”), lines 15-19 provide this implementation. Moreover, we also have to add ng-table
to our app module definition (line 13).
Finally, in order to display the existing users, provided from the model, we have to iterate over the users collection, using ng-repeat
. The ng-repeat
directive instantiates a template once per item from a collection. Each template instance gets its own scope, where the given loop vriable is set to the current location item, and $index is set to the item index or key.
According to the above statements, line 3 stores in variable user
each item of the $scope.users
collection. Keeping that in mind, we provide each user’s name and age attributes, by accessing them respectively (lines 5, 8).
4. Demo
Let’s run this in a local server.
5. Download
This was an example of Angular.js Table.
You can download the full source code of this example here : ng-table-example.zip
Nice simple examples povided, but can you please illustrate an example with mutiple header rows using ng-grid? I have spent much time trying to implement this and have not found a suitable example online. I referring specifically to the case where the headers are fixed and only the data rows are scrollable.