4.2. Exploring the Source Code
The user interface of the kitchensink-angularjs-bootstrap example is built with two main frameworks: AngularJS and Bootstrap. These create the look and functionality of the application.
This section explains the roles Bootstrap and AngularJS play in the kitchensink-angularjs-bootstrap example. The user interface source code of the example is located primarily in
src/webapp/index.html. The user interface is generated with CSS and JavaScript, the libraries for which are located in kitchensink-angularjs-bootstrap/src/main/webapp/css and kitchensink-angularjs-bootstrap/src/main/webapp/js/libs respectively.
4.2.1. Bootstrap
4.2.1.1. About Bootstrap
Bootstrap is a framework used to create responsive design applications. In this example, it is used for its function that changes the size of the user interface, so that the user interface fits on the screen of the target device. Mobile screens come in various sizes, and bootstrap ensures that your application is delivered to each in a format appropriate to the device.
You need only to create the primary application, and Bootstrap will ensure that it fits the resolution of the target screen. This makes it unnecessary to write a version of the application for each device you intend to deliver the application to. It removes problems that arise when attempting to create a standard-sized layout when there is no standard screen size across all mobile device models.
The Bootstrap framework consists of JavaScript and CSS file libraries that used in mobile applications. These libraries are inserted in the header. Because the libraries are pre-loaded, users do not have to wait for website information to download from the server.
Bootstrap uses a grid system that automatically scales webpages to the size of the screen. User-interface objects are contained in the rows of columns that make up the grid. These columns fix to the size of the screen, changing the position of the objects where necessary to create a consistent layout. A maximum of twelve columns is allowed, which will stretch or skew to the size of the screen. The default is three columns of equal size. This ensures that they do not overlap or distort, no matter the screen size.
4.2.1.2. The Bootstrap Declarations
The file libraries necessary to invoke this example are declared in the
index.html file, located in WEB-INF. These library declarations occur in the <head> section. The CSS and JavaScript libraries are declared:
<head> ... <link rel="stylesheet" href="css/bootstrap.css" type="text/css" /> <link rel="stylesheet" href="css/bootstrap-theme.css" type="text/css" /> ... <!-- Load Bootstrap JS components --> <script src="js/libs/bootstrap.js"></script> ... </head>
The contents of these libraries are briefly described in the table below.
Table 4.1. Bootstrap Declarations
| Name | Description |
|---|---|
bootstrap.css | Contains the columns and rows that Bootstrap requires to create a grid. Also contains information on margin sizes, coloring, and fonts. index.html uses the bootstrap.css stylesheet to generate columns (<col-*>) in the container section of the body. |
bootstrap-theme.css | Contains graphical and theme elements for the user interface, such as text shadows, buttons, and navigation bars. index.html uses this to generate the appearance of the buttons. (For example, class="btn btn-default".) |
bootstrap.js | Contains all the Bootstrap JavaScript plugins. This includes transition effects, button functions, and pop-up text. In this example, JavaScript implementations are performed by AngularJS. |
4.2.1.3. The Layout
The layout of the application provides an interface which objects can be added to. It contains several items:
- A header that displays a JBoss EAP graphic and welcome message
- A footer that displays the text “This project was generated from a Maven archetype from JBoss.”
- Space to insert the form
The content of the layout changes position depending on the size of the screen. When opened in a desktop browser, the application displays horizontally. The side panel sits on the right of the page next to the form, with the JBoss EAP graphic aligned to the right. When opened on a mobile device, the application displays vertically. The objects are stacked to preserve the layout, preventing overlapping and clutter. The JBoss EAP graphic is pushed to the top of the screen with the form directly under it, followed by the side panel. Bootstrap defines the aspect ratio of application elements using a grid system. The information that is used to produce columns and rows comes from the Bootstrap.css file.
The following code in the index.html file is used to correctly position the graphic and welcome message:
<section id="container" class="container"> <div class="col-xs-12 col-sm-12 col-md-12"> <div class="dualbrand img-responsive pull-right"> <img src="gfx/rhjb_eap_logo.png" /> </div>
Table 4.2. Layout Attributes
| Name | Description |
|---|---|
| section id | A unique identifier given to refer to the object. (In this case, “container”.) |
| class | Defines what sort of object is being inserted. In this case, it is a container. The container is used to nest columns and rows. |
| <div class="col-xs-12 col-sm-12 col-md-12"> | Defines the size of the container. This is determined by columns, referenced to as col-xs (extra small devices), col-sm (small devices), and col-md (medium devices). All these columns are followed by a 12, indicating that they are 12 columns wide. Depending on the size of the screen (extra small, small or medium), the container scales the columns to fit. |
| <div class="dualbrand img-responsive pull-right"> | Makes the layout responsive to the device it is being viewed on. The dualbrand variable is a style class. The img-responsive variable scales the image (in this case, rhjb_eap_logo.png) to fit the size of the screen. The pull-right variable ensures the container floats to the right of the screen. This prevents it from distorting the layout when the user views and moves about the application. |
4.2.1.4. The Content
The page content consists of a web form generated by AngularJS. Bootstrap provides a section for it in
index.html:
<div id="content" class="col-xs-12 col-sm-12 col-md-8" ng-view> <!-- This div will be templated by AngularJS --> [Template content will be inserted here] </div>
Table 4.3. Content Attributes
| Name | Description |
|---|---|
| id="content" | A unique identifier given to refer to the object. (In this case, "content".) |
| class="col-xs-12 col-sm-12 col-md-8" | Determines the scaling of the content. In this case, the web form is the content. Screens defined as "extra small" and "small" display the web form over the width of 12 columns. A "medium-sized" screen displays the web form over 8 columns. In a desktop browser, the web form displays horizontally. On a mobile device, the web form displays vertically. |
4.2.1.5. The Side Bar
The side bar contains links to the JBoss EAP documentation. The side bar displays in a gray box that changes position depending upon the size of the screen.
<aside id="aside" class="col-xs-12 col-sm-12 col-md-4"> <div class="row"> ... </div> </aside>
Table 4.4. Side Bar Attributes
| Name | Description |
|---|---|
| aside | Creates the side bar. In a web browser, this bar displays on the top right of the homepage. When scaled down to adhere to a mobile device screen, the bar moves to the bottom of the homepage. |
| id | A unique identifier that refers to the object. (In this case, “aside”.) |
| class | Defines the size of the side bar on extra small, small, and medium screens (12, 12, and 4 columns wide respectively). This data is drawn from Bootstrap.css. The col-xs and col-sm variables in this example display content over 12 columns, so as to take up the whole width of the layout on a mobile device. The col-md variable displays information over 4 columns, which exhausts the layout width unconsumed by content on medium-sized screens. |
| <div class="row"> | Creates a row for the panel's content. Each row contains a group of columns and is nested inside a container. Adding another row adds another group of columns to which content may be added. |
4.2.2. AngularJS
4.2.2.1. About AngularJS
The AngularJS framework is used in the creation of single-page applications. All input and validation processes on one screen, and content updates dynamically. AngularJS can be used as a standalone framework or added to the body of a HTML document. Because of its instant response time, it is useful in creating mobile applications.
As all the information in the application displays on one page, users do not have to navigate between different tabs and sections. This decreases loading time and ensures that data is easily accessible. Everything loads on launch. If a user makes an error when typing information, a warning displays immediately. The application does not spend time validating the input before producing an error message. This ensures that information is not lost when switching between forms and validation pages.
The AngularJS framework uses JavaScript libraries that are declared in the header of the
index.html file. These libraries load when the application launches. The libraries do not wait for a response from the server before loading. AngularJS objects are defined with <ng> tags.
AngularJS uses directives to dictate the behavior of Document Object Model (DOM) elements. This is achieved through data-binding, which automatically updates the application when changes are made. Forms are instantly validated. AngularJS objects can be embedded in other frameworks to create multi-technology mobile applications.
4.2.2.2. The AngularJS Declarations
The necessary JavaScript libraries are declared in the
index.html file. The folders are located in src/main/webapp/js/libs. These library declarations occur in the "<head>" section of the example and apply to the entire application:
<head>
...
<!-- Load angularjs -->
<script src="js/libs/angular.js"></script>
<!-- Load angularjs-route, which allows us to use multiple views displayed through application routes -->
<script src="js/libs/angular-route.js"></script>
<!-- Load angularjs-resource, which allows us to interact with REST resources as high level services -->
<script src="js/libs/angular-resource.js"></script>
...
</head>
The contents of these libraries are briefly described in the table below.
Table 4.5. AngularJS Declarations
| Name | Description |
|---|---|
angular.js | Contains the AngularJS JavaScript plugins and directives (attributes). In this example, it contains the elements needed to generate the form. This is the primary library. |
angular-resource.js | Contains JavaScript for implementing RESTful data sources. In this example, it is used when generating the list of contacts displayed at the bottom of the web form. |
angular-route.js | Contains the JavaScript elements used to respond to input by directly updating the layout. It implements the ngView directive that renders the layout. |
4.2.2.3. The Member Registration Form
When the application opens, a webform, the "member registration form", displays. The user enters the contact details of the person they wish to register as a member. When submitted, these contact details are saved in the application and given RESTful URLs. The member registration form provides a simple method of adding and monitoring contact details and can be modified on the fly.
The form contains text fields, buttons, and a validation option that are generated by AngularJS. These objects are contained in the AngularJS libraries and appear in the body of the
home.html file. They are responsive to user input and have been designed with mobile devices in mind. The properties and functions of these elements are discussed in detail in this section.
4.2.2.3.1. Form Statement
The webform is a standard HTML form which uses an AngularJS template. It is contained in the
home.html file in src/main/webapp/partials. This file loads the form, which is inserted in the body of the application:
<!-- This is a partial, and is templated by AngularJS -->
<div>
<!-- Standard HTML form, with the submit function bound to the register() function defined in the the controller -->
<form name="regForm" class="form-horizontal" ng-submit="register()">
<h2>Member Registration</h2>
<fieldset>
...
</fieldset>
</form>
....
</div>
Table 4.6. Form Attributes
| Name | Description |
|---|---|
| name="regForm" | Identifies the object is a form. A unique name is entered to identify the form in the layout. In this case, it is named regForm. |
| class="form-horizontal" | Ensures that the form fills the entire width of the layout and that the form uses all available space. A "form-vertical" attribute would ensure that the form takes up the entire length of the available space. |
| ng-submit="register()" | Reloads the form using AngularJS when a member is registered. It refreshes instantly instead of pulling data from the server. |
All of the form fields, buttons, and validation are nested within the <form> element.
4.2.2.3.2. Form Fields
The form has three text fields: "Name", "Email", and "Phone #". They must all be completed before the form is submitted. These fields are declared in the <fieldset> of the form. Each field shares several common attributes, but also contains unique attributes.
<fieldset>
<legend>Register a member:</legend>
<!-- Each input is bound to a property on the prototype newMember object -->
<div class="form-group">
<label for="name" class="col-sm-2 control-label">Name:</label>
<div class="col-sm-10">
<input type="text" name="name" id="name" ng-model="newMember.name" placeholder="Your Name" required autofocus/>
<span class="error help-block" ng-show="regForm.name.$error.required">required</span>
<span class="error help-block" ng-show="errors.name">{{errors.name}}</span>
</div>
</div>
<div class="form-group">
<label for="email" class="col-sm-2 control-label">Email:</label>
<div class="col-sm-10">
<input type="email" name="email" id="email" ng-model="newMember.email" placeholder="Your Email" required />
<span class="error help-block" ng-show="regForm.email.$error.required">required</span>
<span class="error help-block" ng-show="regForm.email.$error.email">not a valid email</span>
<span class="error help-block" ng-show="errors.email">{{errors.email}}</span>
</div>
</div>
<div class="form-group">
<label for="phoneNumber" class="col-sm-2 control-label">Phone #:</label>
<div class="col-sm-10">
<input type="tel" name="phoneNumber" id="phoneNumber" ng-model="newMember.phoneNumber" ng-pattern="/^[0-9]{10,12}$/" placeholder="Your Phone #" required />
<span class="error help-block" ng-show="regForm.phoneNumber.$error.required">required</span>
<span class="error help-block" ng-show="regForm.phoneNumber.$error.pattern">must be between 10 and 12 digits</span>
<span class="error help-block" ng-show="errors.phoneNumber">{{errors.phoneNumber}}</span>
</div>
</div>
....
</fieldset>
Table 4.7. Common Attributes
| Name | Description |
|---|---|
| input type | Specifies the kind of data that can be added to the form, in this case, text. |
| name | Where the title of the field is specified. These fields are names name, email, and phoneNumber respectively. |
| ng-model | Creates a two-way binding process model. It is triggered by the input, in this case, when a user enters text. When the input is invalid, it alerts the user with a warning that displays beneath the name field. |
| placeholder | Adds grayed-out text to indicate the field required input, for example, Your Name. The text disappears when the user starts typing. |
| ng-show | Displays events when triggered. In this example, it is triggered when the required input is missing, resulting in a red error message displaying beneath the field. |
| required | Requires the field to contain input before it is submitted. The form will not validate if the field is left blank. |
Table 4.8. Unique Attributes
| Name | Description |
|---|---|
| autofocus | The Name field contains an autofocus attribute. This activates the field when the application deploys. In this example, it adds a flashing text cursor to the first field of the form to prompt the user to add input. |
| ng-pattern | The Phone # field contains the ng-pattern directive. This defines which characters are allowed. In this example, it allows only umerical characters ([0-9]) that are 10-12 numbers long ({10,12}). |
4.2.2.3.3. Form Buttons
After filling out the form, users can choose to either submit it or cancel. This is done with two buttons labeled "Register" and "Cancel". They are located at the bottom of the form and are specified after the validation messages in the
home.html file:
<fieldset>
...
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<input type="submit" ng-disabled="regForm.$invalid" id="register" value="Register" class="btn btn-primary" />
<input type="button" ng-click="reset()" name="cancel" id="cancel" value="Cancel" class="btn btn-default" />
</div>
</div>
</fieldset>
Table 4.9. Button Attributes
| Name | Description |
|---|---|
| input type | Defines which of the elements displays. In this example, both elements are buttons: the first is used to submit the form and the second is used to cancel it. |
| ng-disabled | Stops the browser from submitting the form if the input is incorrect. In this case, it disables the validation button if the registration form is invalid. |
| ng-click | Specifies which action the button takes when it is clicked. In this case, it contains a reset command. Clicking the Cancel button resets the form to its default state. |
4.2.2.3.4. Form Validation
The validation messages are inserted after the form fields in the home.html file and display underneath the Phone # field in the application. When the user submits the form, either a success or an error message displays.
<fieldset>
...
<!-- We output a list of success messages (appropriately styled!) for the form. -->
<ul ng-hide="!successMessages" class="success">
<li ng-repeat="message in successMessages">{{message}}</li>
</ul>
<!-- Output the list of error messages if any. -->
<ul ng-hide="!errorMessages" class="error">
<li ng-repeat="message in errorMessages">{{message}}</li>
</ul>
...
</fieldset>
Table 4.10. Validation Attributes
| Name | Description |
|---|---|
| ng-hide | Hides data where specified. If there is no error message, the error message dialogue is hidden and not appear on screen. |
| ng-repeat | Repeats a set of data from a specified location. In this case, it replicates the list of the messages in the defined attribute (successMessages or errorMessages). |
4.2.2.4. The Members List
The members list contains contact details for every member that has been registered using the form. In the application, the members list displays in a box beneath the form with the title “Members”. When a new name is submitted, it is instantly added to this list which generates an ID and REST URL for it. Beneath the list is a REST URL that contains the details of all the members in the list. These URLs do not point to a link on the web. These URLs link to the location within the application where the details are stored. AngularJS adds new entries to this list automatically. Click the refresh button under the table to manually reload the entries.
4.2.2.4.1. List Statement
After a new member is added, the details of that member display in the members list below the form. The members list is the second heading in the
home.html file:
<!-- This is a partial, and is templated by AngularJS -->
<div>
...
<!-- A list of registered members -->
<h2>Members</h2>
<!-- If there are no members registered, instead of showing the table, we show a simple message. -->
<em ng-show="members.length == 0">No registered members.</em>
<div class="table-responsive">
<table ng-hide="members.length == 0" class="table table-striped">
<thead>
<tr>
<th>Id</th>
<th>Name</th>
<th>Email</th>
<th>Phone #</th>
<th>REST URL</th>
</tr>
</thead>
<!-- The table is built using the AngularJS repeat function, iterating over the members variable, and ordering by the property specified in the orderBy variable -->
<tr ng-repeat="member in members | orderBy:orderBy">
<td>{{member.id}}</td>
<td>{{member.name}}</td>
<td>{{member.email}}</td>
<td>{{member.phoneNumber}}</td>
<td><a href="rest/members/{{member.id}}">/rest/members/{{member.id}}</a>
</td>
</table>
</div>
...
</div>
Table 4.11. List Attributes
| Name | Description |
|---|---|
| ng-show | Displays a message when triggered. In this case it has been defined to display a “No registered members” message when no members have been added. |
| ng-hide | Does not display the specified data if certain requirements have not been met. If there are no registered members, it hides the members list so it does not appear on screen. |
| ng-repeat | Reiterates the list of members that have been submitted so they display in the list. It contains a orderBy attribute, which lists the members in alphabetical order by default. |
4.2.2.4.2. Refresh Button
The refresh button is located under the list. Click the refresh button to manually reload the members list. The design of the button is rendered with CSS.
<!-- This is a partial, and is templated by AngularJS -->
<div>
...
<div>
<!-- The table has a button to manually refresh the values, in case, for example, someone else adds a member -->
<input type="button" ng-click="refresh()" name="refresh"
id="refresh" value="Refresh" class="btn btn-default" />
</div>
</div>
Table 4.12. Refresh Button Attributes
| Name | Description |
|---|---|
| ng-click | Specifies which action the button takes when it is clicked. In this case it contains a refresh command. Clicking the refresh button reloads the values dynamically in the members list. |


