Check out our new training course on AngularJS for Flex Developers

Hello Angular 2 - Introduction to Angular 2 with JavaScript - Part 1

Angular 2 has officially been released. A while back I wrote a short series of articles that were an introduction to Angular 2. None of that code worked on the final release; so I'm revisiting them here.

Angular 2 still seems to have a documentation problem. Angular is built to be used by TypeScript, JavaScript, or Dart. However, only the TypeScript tutorials are fleshed out. Coming from an Angular 1 background with JavaScript, I wanted to start my Angular 2 adventures using JavaScript.

I'm writing this series of blog posts to show how I created my first Hello World Angular 2 application using JavaScript.

Import the Angular 2 libraries

One difference I noticed between Angular 1 and Angular 2 is that Angular 2 code base is split up among many different libraries. I believe this was intentional so you could easily remove components of Angular that you do not need; thus making the overall load time for your application smaller.

Let's look at a bunch of these:


<!-- IE required polyfill -->
<script src="https://npmcdn.com/core-js/client/shim.min.js"></script>

The first is a polyfill library for Internet Explorerer. Polyfill is a term for implementing an API not natively supported. Internet Explorer requires this to support promises and dynamic modules loading, as defined as part of the ECMAScript 2015 specification. Other browsers support this by default. You can leave this out if IE is not required for your application.


<script src="https://unpkg.com/zone.js@0.6.25?main=browser"></script>
<script src="https://unpkg.com/reflect-metadata@0.1.8"></script>

Zone and Reflect are the Polyfills used by AngularJS.


<script src="https://unpkg.com/rxjs@5.0.0-beta.12/bundles/Rx.js"></script>

Reactive Extensions RXJS is a library for composing asynchronous and event based programs using Observable collections. Observable collections are an implementation of the Observer design pattern. It is a way for one object to notify others of state changes. Data binding is an example of this. RXJS is used in many Angular 2 applications.

Finally, import the main Angular 2 libraries:


<script src="https://unpkg.com/@angular/core/bundles/core.umd.js"></script>
<script src="https://unpkg.com/@angular/common/bundles/common.umd.js"></script>
<script src="https://unpkg.com/@angular/compiler/bundles/compiler.umd.js"></script>
<script src="https://unpkg.com/@angular/platform-browser/bundles/platform-browser.umd.js"></script>
<script src="https://unpkg.com/@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js"></script>

The official API reference contains detailed information of what each library is, but for the purposes of this article I decided not to go into details.

Create Your First Angular 2 Component

The first thing we'll do is create an Angular 2 component. The default Angular 2 method is to wrap the component around an Immediately Invoked Function Expression (IIFE) function, like this:


(function(app) {
})(window.app || (window.app = {}));

There is no Angular code in this snippet yet, but I want to point out that a variable is passed into the function. This is window.app, which is an object. Some shorthand trickery is used to define window.app as an empty object. The code could be rewritten like this:


window.app = {};
(function(app) {
})(window.app);

I find the approach of storing a pointer to the main application object curious. Global variable are sometimes considered bad practice and when building Angular 1 applications, I went out of my way to avoid creating new ones. Here we create one for the main Angular component.

Now, let's flesh out the component:


app.AppComponent = ng.core.Component({
selector: 'my-app',
template: '<h1>My First Angular 2 App</h1>'
})
.Class({
constructor: function() {}
});

Inside the empty app object, a property named AppComponent is created. This creates an Angular component using the ng.core.Component() function. In Angular 2 a component seems to be synonymous with a directive in Angular 1. The Component() function accepts an object as its argument. The object has two properties. The first is the selector, which is the component name and how it will be referenced in HTML code. The second is the template, which is the HTML Text. For the purposes of this sample, I defined the template inline.

After the Component() function, you'll see the dot notation used to call a second method named Class(). This is where we define the JavaScript behind the component, sort of like a Controller in Angular 1. For the moment this component has no JavaScript. It is an entity that includes some markup and some JavaScript code. Angular 2 purposely separates the JavaScript and markup portions of the template.

Create the Angular Module

The next step to create a running AngularJS application is to create the Angular module. After the component is defined add another IIFE:


(function(app) {
})(window.app || (window.app = {}));

Then create the module:


app.AppModule = ng.core.NgModule({
imports: [ ng.platformBrowser.BrowserModule ],
declarations: [ app.AppComponent ],
bootstrap: [ app.AppComponent ]
})
.Class({
constructor: function() {}
});

The NgModule() function is called on the ng.core library. It operates similar to the Component() function; but this time creates an Angular app instead of an Angular component. For the purposes of this article, think of an app as a collection of components. A single array argument is passed into the NgModule() function; which is a list of configuration options. Chaining off the module creation, a class is create with a constructor. We are not putting anything in the class for the purposes of this sample.

The argument list in the NgModule() contains imports, declarations, and bootstrap. The imports define the other, external, modules that are required for this app. The declaration and bootstrap both refer to our custom components made for this application. In this case, they reference the app.AppComponent variable.

This is a switch from Angular 1 development, where in most cases you would define the module first, and all components, directives, and services later.

Bootstrap the Component

In Angular 2, you initialize an Angular module by bootstrapping it. This tells Angular 2 to examine the HTML; find any tags it recognizes, and replace them with the relevant HTML and JavaScript interaction. This statement is, once again, wrapped in an IIFE:


(function(app) {
})(window.app || (window.app = {}));

The IIFE's function accepts the window.app variable, and we use the same short-hand approach to define that variable if it is not yet defined. Next, add an event listener to the DOMContentLoaded event. DOMContentLoaded is a browser event that launches whenever the page is finished loading:


document.addEventListener('DOMContentLoaded', function() {
});

Inside the DOMContentLoaded event handler function, call the bootstrapModule() method on the platformBrowserDynamic object:


ng.platformBrowserDynamic.platformBrowserDynamic().bootstrapModule(app.AppModule);

Now, the JavaScript behind your first Angular 2 app is ready to go. The last step is to add some HTML.

Use Component in HTML

Inside the body of the HTML application, create an instance of the my-app component:


<my-app>Loading...</my-app>

Then you're app should be ready. Try to run it, you should see the loading message:

This message should go away quickly, to be replaced by the actual app:

You can play with this code here.

Final Thoughts

This sample isn't all that interesting yet. But, in the next entries in this series I'll take a look at how to implement binding in the application and how to respond to button clicks.

Get our Updated Intro to Angular 2 White Paper

Announcing The Learn With Series: Angular Tutorials

I just released Learn With, the first entry in my new series of books and programming tutorials.

The first set of books I released focus on building applications with AngularJS and Bootstrap. There are currently three books. One uses mock services so you can focus on learning Angular without having to worry about a backend. Another builds out a fully functional backend with NodeJS. The third builds a fully functional backend with ColdFusion.

When creating this series, I spent a lot of time building out the infrastructure, and the plan is to expand the series to include other backend or front end choices.

You can buy a PDF direct from us; or get an ebook through Amazon.

If you're looking to jump into modern HTML5 development; then Angular is a great choice with lots of community support.

Take a look and let me know what you think.

Newsletter Subscribers got a discount on Learn With: sign up here

Modifying the Type Ahead Highlight – Angular uiSelect AutoComplete Directive - Part 4

The previous article I wrote about Angular's uiSelect AutoComplete directive showed you how to modify the drop down filter. This article will show you how to modify the drop down highlight.

Review The AutoComplete Highlight

When you start typing into the AutoComplete, the uiSelectChoices directive filters the list and the text is highlighted in the drop down:

This is the Angular code behind the highlight:


<span ng-bind-html="state.label | highlight: $select.search"></span>

A highlight filter is applied to the displayed label. If you look at the code when you start typing, you'll see something like this:


<span class="ui-select-highlight">Al</span>
aska

The uiSelect automatically places the span around the text with the style "ui-select-highlight". You can modify the highlight by either modifying the style, or using a new filter. This post will show both approaches.

Option 1: Modify the style

To modify the style, you just need to add a new style to your page, or style sheet. Here is a style that turns the color of the highlight red:


.ui-select-highlight{
color : red;
}

Reload the app and see it in action:

Play with the code here.

Option 2: Use a Filter

The second option is to write your own highlight filter. The default filter will highlight all text in the word. We can write another one that just highlights the first instance of the text. First, create the filter stub:


angular.module('uiSelectTestApp').filter('firstOnlyHighLight', function() {
return function(input, searchString) {
}
});

The filter is named firstOnlyHighlight. It is set up like a standard Angular filter. The real magic is the code inside the filter function. First, do this:


if(searchString){
// other stuff here
}
return input;

If a searchString exists, then we'll do some processing and return it. If not; return the input unprocessed. The purpose of this function is to find the first instance of searchString in the input and replace it with modified HTML. First, get the index of the searchString:


var index = input.toLowerCase().search(searchString.toLowerCase());

This puts the input and searchString into lowercase, making it a case insensitive search. Next, get the length of the searchString:


var length = searchString.length;

This will make sure that the function will work even if the user has typed multiple letters. Next, use the length and index to store the original text:


var originalText = input.substr(index, length);

Finally replace the text:


var highlightedLabel = input.replace(originalText, '<span class="ui-select-highlight">' + originalText + '</span>');

The replace() method is used on the input. It looks for the originalText, and replaces it with the HTML modified text.

Now return the modified value:


return highlightedLabel;

One final thing is needed; to change the HTML to refer to the new filter:


<span ng-bind-html="state.label | firstOnlyHighLight: $select.search"></span>

Try this here:

Final Thoughts

The use of filters make this very powerful. You could create your own approach which uses your own styles.

Sign up for DotComIt's Monthly Technical Newsletter

Creating a Custom Filter - Angular uiSelect AutoComplete Directive - Part 3

I have been working with the Angular uiSelect AutoComplete component recently. I wanted to see if I could modify how the component filters the items in the drop down. It can be done pretty easy with an Angular filter. I'm going to modify the sample I used in previous posts about the Angular UI Select box.

Create the Filter

Angular Filters are not complicated. They take an input, process it, and return the modified value for display. The filter from my original examples was this:


<ui-select-choices repeat="state in dataProvider | filter: $select.search">

It is taken directly from the original sample. This takes the value the user typed, $select.search, and looks for it in the label for each state. If the value is found, the item is put in the drop down; otherwise it is removed from the list.

We can modify this algorithm by creating our own customer filter. I'm going to create a filter that filters on the start of the label, but does not look for items in the middle of the word. First create a code stub for the filter:


angular.module('uiSelectTestApp').filter('firstOnlyFilter', function() {
return function(input, searchString) {
}
});

I named this filter firstOnlyFilter. The input to this filter will be an arrayCollection; and the second attribute is a searchString, or $select.search. Now flesh out the filter's implementation"


return input.filter(function(item){
if (item.label.toLowerCase().search(searchString.toLowerCase()) == 0){
return true;
}
return false;
})

This code uses the JavaScript filter function to modify the input array with items that only match the current criteria. The function turns the label into lowercase; then uses the JavaScript string search() method to find the text, which was also put into lowercase. If search returns 0; then the text was found at the first item, and the result should be included in the final array. Otherwise false is returned and the item is removed from the drop down.

The last step is to modify the uiSelectChoices to user the new filter:


<ui-select-choices repeat="state in dataProvider | firstOnlyFilter : $select.search">

This should complete the appropriate changes:

Play with the code here.

Final Thoughts

The use of Angular filters to restrict the items in the drop down makes the uiSelect very extensible, and you can write your own algorithm to make the component work to your specifications.

Sign up for DotComIt's Monthly Technical Newsletter

Creating an Alert with Bootstrap and Angular

One of this blog's more popular posts is about creating an Alert using Bootstrap and AngularJS. I decided to write about something similar--using Bootstrap to create an Alert. I use this a lot in one of the current applications I've built for a client and thought I'd write a little about it.

This post uses Angular, Bootstrap, and uiBootstrap.

Create a Basic Alert

The first sample will create a few basic alerts. First, import the Angular, uiBootstrap, and Bootstrap libraries:


<script src="//code.angularjs.org/1.5.8/angular.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/2.2.0/ui-bootstrap-tpls.min.js"></script>
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">

Then, create an Angular Module:


<script>
angular.module('testAlert', ['ui.bootstrap']);
</script>

The angular module is named testAlert; and the uiBootstrap library is passed into the module as an argument. This means that the Angular application can use all the components defined in the uiBootstrap library.

Finally, use the HTML to create a few alerts:



<body ng-app="testAlert">

<div uib-alert class="alert-danger">Danger Alert</div>

<div uib-alert class="alert-warning">Warning Alert</div>

<div uib-alert class="alert-success">Success Alert</div>

I created three alerts here; each one with a different class which apply different colors to the alert:

Try the code here. This example isn't too complex, and does not even have an Angular controller. Let's fix that.

Dynamically Generate Alerts

Next, I'll show you how to dynamically generate alerts. First, create an Angular controller:


angular.module('testAlert').controller('ctrl',['$scope', function($scope){
$scope.alerts = [];
}]);

The controller is named ctrl. The only thing the controller contains, so far, is an array named alerts.

The UI code will look over the array to create alerts on the page:


<div ng-controller="ctrl">
<div uib-alert ng-repeat="alert in alerts" ng-class="alert.type">{{alert.msg}}</div>
</div>

The alert div loops over all the alerts. It specifies the alert class using a type property on the alert object. A msg property on the alert object contains the message to be displayed in the alert.

Now, let's add some code to create the alerts. Let's put a function in the controller:


$scope.addAlert = function(type, msg){
$scope.alerts.push({
type : type,
msg : msg
})
}

The addAlert function will accept a type and a message; then add those to the alert array.

Add some buttons to the UI to create the alerts:


<button ng-click="addAlert('alert-warning','Warning Alert')" >Add Warning Alert</button>
<button ng-click="addAlert('alert-danger','Warning Alert')" >Add danger Alert</button>
<button ng-click="addAlert('alert-success','Warning Alert')" >Add Success Alert</button>

You can play around with this here:

Close an Alert

You probably don't want alerts to stay around in your app forever, so we need a way to dismiss them. One way is to use the close method on the alert:


<div uib-alert ng-repeat="alert in alerts" ng-class="alert.type" close="closeAlert($index)">{{alert.msg}}</div>

When adding a close method an 'x' button will appear as part of the alert. When it is clicked; we can execute the closerAlert() method inside the controller. The value we pass into the closerAlert() method is the index of the alert which was clicked.

This is the closeAlert() method:


$scope.closeAlert = function(index) {
$scope.alerts.splice(index, 1);
};

Look at the finished app:

Play with the full code here!

Dismiss an Alert Automatically

There is one more alert related property I wanted to examine. You can set up the alerts to vanish automatically using dismiss-on-timeout:


<div uib-alert ng-repeat="alert in alerts" ng-class="alert.type" close="closeAlert($index)" dismiss-on-timeout="5000">{{alert.msg}}</div>

the value of the dismiss-on-timeout attribute is in milliseconds, and will hide the alert in about 5 seconds with the value of 5000.

Try out the code here.

I have mixed feelings about this approach, because I have concerns about changing the UI without user interaction. I think showing the user a message and automatically removing it could be confusing. What if the user didn't read the message yet?

Final Thoughts

The alert is a nice component that allows you to give non-intrusive feedback to your users. I like it better than a popup warning, which can interrupt the users flow. What do you think?

Sign up for DotComIt's Monthly Technical Newsletter

Themes - Angular uiSelect Directive - Part 2

I have been writing some blog posts about the Angular uiSelect component. One interesting thing about this component is that it is built to support different themes, each providing a different look and feel.

These themes are provided in the form of a CSS; then you can just change a property to modify the look and feel. The previous example of my . In my previous post, I used the bootstrap theme. In this post I wanted to demonstrate two other themes.

The examples in this post build off the examples in the previous post.

The Select2 Theme

The first theme is the Select2 theme. Select2 is a JQuery component designed to replaced select boxes. Putting it in place is pretty easy. First add the select2.css:


<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/select2/3.4.5/select2.css">

Then change the theme property on the uiSelect:


<ui-select ng-model="selectedCountry" theme="select2" title="Choose a State">
<ui-select-match placeholder="Select or search for a State in the list...">{{$select.selected.label}}</ui-select-match>
<ui-select-choices repeat="state in dataProvider | filter: $select.search">
<span ng-bind-html="state.label | highlight: $select.search"></span>
</ui-select-choices>
</ui-select>

This will show the uiSelect in the new theme:

The main difference with the select2 theme is that it adds a filter box in the drop down instead of as part of the main label display.

Play with the code here.

The Selectize Theme

A third theme is provided as part of the uiSelect directive; named selectize. This theme is my preferred approach because it reminds me of my days as a Flex Developer. The approach to use this theme is similar to the select2 theme. First, load the style sheet:


<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/selectize.js/0.8.5/css/selectize.default.css">

Then add the theme property on the uiSelect:


<ui-select ng-model="selectedCountry" theme="selectize" title="Choose a State">
<ui-select-match placeholder="Select or search for a State in the list...">{{$select.selected.label}}</ui-select-match>
<ui-select-choices repeat="state in dataProvider | filter: $select.search">
<span ng-bind-html="state.label | highlight: $select.search"></span>
</ui-select-choices>
</ui-select>

Run the code, and you'll see the third theme:

Play with the code here.

This theme is my preferred theme and the one I used on a client project. It reminds most of the work I did with Flex AutoComplete components.

Theming the uiSelect component is very easy; because the directive developers did all the hard work for us.

Sign up for DotComIt's Monthly Technical Newsletter

Where can I find an Angular AutoComplete Component?

I have extensive experience with creating AutoComplete components in the Flex Space. When it came time to use one in an Angular project; I was lost. The client wanted something similar to the Flextras AutoCompleteComboBox, which supported type ahead filtering of the drop down list and a drop down button.

However, every JavaScript AutoComplete component I could find was either missing the down arrow or didn't work. My Google-Fu was failing me.

UI Bootstrap has both a drop down and a type ahead component. I was working on combining them into a single component when a Facebook friend turned me onto the Angular uiSelect component. It was exactly what we were after.

Basic Setup

The first thing we need to do is load the JavaScript libraries:


<script src="//code.angularjs.org/1.5.8/angular.js">
</script>
<script src="//code.angularjs.org/1.5.8/angular-sanitize.js">
</script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-select/0.19.4/select.min.js">
</script>

This loads the Angular library, the uiSelect library, and the angular sanitize library. Angular Sanitize is an Angular library used to parse HTML into Tokens. It is required as part of uiSelect.

Some Style sheets are needed too:


<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/angular-ui-select/0.19.4/select.min.css">
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.css">

These are a custom style sheet for the uiSelect directive and the style sheet for Bootstrap. The uiSelect has multiple themes that can apply to it. For the moment, I'm only using the bootstrap theme.

All the libraries and CSS sheets are loaded from remote CDNs instead of being hosted locally.

Create the Angular Code

The next step is to create the Angular code. First, create the Angular module:


angular.module('uiSelectTestApp', ['ngSanitize', 'ui.select']);

The uiSelect and ngSantitize directives are passed as configuration arguments into our main module. Next, create a controller:


angular.module('uiSelectTestApp').controller('ctrl', ['$scope',function($scope){
$scope.dataProvider = [
{id:1, label:'Alabama'},
{id:2, label:'Alaska'},
. . .
{id:50, label:'Wyoming'},
]
}]);

The controller is named ctrl. It contains a single $scope variable, which is an array. The array contains a list of US states, and will be used to populate the uiSelect component. That is enough for the JavaScript code.

Create the HTML

The last step is to add the uiSelect component to the page. First, create the Angular app and controller to the page:


<body ng-app="uiSelectTestApp">
<div ng-controller="ctrl">
</div>
</body>

This code adds the ngApp attribute on the body tag and the ngController attribute on a div tag inside of it. Inside the div, the uiSelect component is implemented:


<ui-select ng-model="selectedCountry" theme="bootstrap" title="Choose a State">
<ui-select-match placeholder="Select or search for a State in the list...">{{$select.selected.label}}</ui-select-match>
<ui-select-choices repeat="state in dataProvider | filter: $select.search">
<span ng-bind-html="state.label | highlight: $select.search"></span>
</ui-select-choices>
</ui-select>

There is lots going on here, so let's dissect it one piece at a time. First the main uiSelect:


<ui-select ng-model="selectedCountry" theme="bootstrap" title="Choose a State">
</ui-select>

The main uiSelect component contains an ngModel, which acts just like the ngModel on every other angular component you've used. The theme specifies the theme, in this case I specified it to bootstrap. I'm not going to explore themes in this post, but I hope to do so in more detail later. The last attribute is title, which acts like a tooltip when mousing over the component.

Next look at the match:


<ui-select-match placeholder="Select or search for a State in the list...">{{$select.selected.label}}</ui-select-match>

The uiSelectMatch directive is used to display a label. If an item is selected in the drop down; it will display to the user. If no item is selected the placeholder will display as a prompt. The $select is a service specific to the uiSelect component. We are using it to drill into the selected object and display its label.

The uiSelectChoices is used to populate the items that appear in the drop down:


<ui-select-choices repeat="state in dataProvider | filter: $select.search">
<span ng-bind-html="state.label | highlight: $select.search"></span>
</ui-select-choices>

The repeat attribute is a loop. It looks over all the items in the dataProvider--which was defined in the controller's $scope. It applies a filter onto those items; using a default one from the uiSelect's $select directive. The default filter searches for any string typed into the uiSelectMatch entry and restricts the display list as such.

The span inside the uiSelectChoices determines what is displayed inside the drop down. For my purposes, I just put the label; but you could expand this to include images or other items. The highlight filter is applied to the label, which will highlight the search items in the filtered drop down.

Test The App

Try the app.

This is the app in its default state:

This is the app with nothing typed in:

This is the app with some filtering:

Final Thoughts

I was surprised that I had time finding this component when searching through Google for Angular AutoComplete or TypeAhead directives. That is what made me want to write a few blog posts about this component. More are coming, and in the next article I'll talk about skinning of this component.

Sign up for DotComIt's Monthly Technical Newsletter

Using an Angular HTTP Interceptor

I was working on a client project. Two separate AngularJS applications were using the same set of services. The services were using cookies to keep track of server side session data. A small subset of users used both applications and both applications were hosted on the same domain. Did you guess why this is a problem?

For users who used both applications, the services could not tell which application the user was using, as such service requests from one app were sometimes being run based on login privileges of the second. This was causing all sorts of problems.

The services team decided the best way to accommodate this was to force an argument onto every service request for one of the applications. The server would use this argument to keep the sessions straight. I don't know all the specifics of how the services were implemented, so can't comment on that. But, I can tell you how we modified the Angular code to address this issue. We used an AngularJS HTTP Intercepter .

What is an Interceptor?

The purpose of an AngularJS HTTP Interceptor is to modify all HTTP requests performed by AngularJS. Y This will affect all requests including REST operations, loading ngInclude files, or loading directive templates. You can set up an interceptor to modify requests before they are sent to the server. You can use it to modify responses before the response is sent back to the result method. An interceptor can also handle request and response errors.

When you need to change every service request the application makes to add a new URL argument, this is a great way to do that.

Creating the Interceptor

A request interceptor must be created in an Angular config block, so here is a config block:


angular.module('testModule').config([''$httpProvider", function($httpProvider){
}]);

The $httpProvider service is passed into the config function using Angular's dependency injection syntax. The interceptor must be created on the $httpProvider service; which will affect all http requests coming from the app:


$httpProvider.interceptors.push(function(){
return {
"request" : function(config){
return config
}
}
}

This is a basic request interceptor, which performs no functionality yet. $httpProvider.interceptors is an array; and a function is pushed onto it. The function returns an object, which contains properties for each type of interceptor--request, response, requestError, responseError. In this case I only defined a request interceptor.

The value of the request is another function. This function accepts a single argument, config that contains configuration data of the request. Then it returns that configuration object. We have not written code to modify the argument yet, but will next.

Modify the HTTP Request

How you modify the HTTP Requests depends on what you want to do. For my purposes, I wanted to append a query string argument to the request. Without knowing the nature of the request, I won't know if existing arguments already exist or not. My first order of business is to determine if I need to add a question mark to the URL--to start a query string--or an ampersand to add to an existing query string:


var queryStringPrepend = "?";
if(config.url.search('\\?') != -1){
var queryStringPrepend = "&"
}

This creates an argument named queryStringPrepend. This is the value to place before our special query string variable that must be added to all service calls. I default the argument to a question mark for creating a brand new query string. Then I perform a regex search on the config's url to see if it already contains a question mark or not. If the question mark exists then change the queryStringPrepend value to an ampersand. The next step is to add the query string to the configuration's URL:


Config.url += queryStringPRepend + "SpecialVariable=SpecialValue"

This uses simple string concatenation. Next return the config argument:


return config

I found this worked for exactly what I wanted.

After some experimentation I realized the new URL parameter was being added to all the templates loaded, not just service calls. It wasn't needed there, so I decided to use another regex to fix it. Check to see if the page being loaded is an html page by looking for .html in the url:


If(config.url.search('\\.html') != -1){
return config;
}

If it is, return request without any modification. Put this code first in the method.

Final Thoughts

Since this deals with service calls, I wasn't sure the best way to put a live sample together; so I did not do that for this post. Overall, I feel like I implemented a kludge in the UI in order to accommodate for what I perceive as a failing on the services. But, in application development there are a lot of moving parts beyond your control and you have to choose the best solution from given options.

Sign up for DotComIt's Monthly Technical Newsletter

Aligning Left Text, Center Text, and Right Text with CSS

I was building out an application for a client who wanted pagination on some tabled data. I needed to create a pagination bar that included a previous button on the left, a next button on the right, and a message in the center. In the old days I could implement something like this using tables, however I wanted to see if there was a CSS way to get the same layout. I found two separate, but great, implementations of this. This blog post will explain both of them.

Aligning Text with Float

My first attempt to implement this was to use the CSS float property. The float means that text moves out of its normal place in the container, usually moving to the left or right of the container. I could float some text to the right, some text to the left and keep some in the middle. Here is the CSS Style for left aligned text:


.leftAligned {
float : left;
}

This puts left aligned text to the left side of the div to contain our pagination header. Right aligned text is similar:


.rightAligned{
float : right;
text-align : right;
}

The float argument is specified as right so the rightAligned block will move to the right of the container. I also specified a text-align property to move the text all the way over to the right within the rightAligned container.

Finally, we need centered text:


.centeredText {
margin: 0 auto;
text-align : center;
}

This margin property is used to make sure that the centeredText can align right up against the right and left segments.

Use these in HTML:


<div>
<div class="leftAligned">Previous/div>

<div class="rightAligned">Next</div>
<div class="centeredText">Displaying 10-20 of 50</div>
</div>

Reviewing the code, you need to put the left and right aligned divs first, and the centered text last. This bugged a bit of my OCD, but worked almost perfectly.

Play with the code here. The Plunker sample uses some Angular code to simulate the forward and next navigation for sample purposes.

As the user was paginating through the data the previous and next links might disappear. When that happened the centered text would change spots. This wouldn't do. We could fix that by adding explicit widths to each div, which worked for the sample application. However my real world app was having problems with that, I believe due to other CSS conflicts. So, I went searching for a second way to accomplish this layout.

Aligning Text with CSS Tables

My second approach to was to use CSS Tables. You can use the display property in CSS to specify table, or table row or table cell.

First, create a table:


.table {
display:table;
width : 100%;
}

The table CSS style specifies the display type as table and width of 100%. This parallels the HTML table tag.

Next, create a table row:


.tr {
display:table-row;
width : 100%;
}

The table row specifies the display type as table-row. This parallels the HTML tr tag.

Now, the left-aligned text:


.leftAligned {
display:table-cell;
width : 25%;
}

The left aligned text specifies table-cell as the display type. The width is given as 25%. Next, the right aligned cell:


.rightAligned {
display:table-cell;
text-align : right;
width : 25%;
}

The right aligned table cell specifies table-cell as the display. It also right aligns the text with the text-align property and specifies the cell width as 25%.

Finally, create the centered text:


.centeredText {
display:table-cell;
text-align : center;
width : 50%;
}

The centered text also has a table-cell type. It also specifies the text-align to center the text; and the width is 50%. The three table cells have a combined width of 100%.

Finally, we need to create the table in the HTML. We'll use divs as the controllers. First, create the table div:


<div class="table">
</div>

Inside of that, put a table row:


<div class="tr">
</div>

Now put the main content inside the table row:

Previous
Displaying 11-20 of 50
Next

Play with the Code Here. As with the previous sample, this uses some AngularJS magic to make the forward and next buttons work.

Final Thoughts

I was surprised at how hard it was to find resources to explain how to do this, so hopefully this helps someone. Both approaches work well, depending what you're doing. The limitation of the second approach--which is specifying table widths--is that if you have text that is expanding or contracting to unknown widths you may have odd layouts as the text grows beyond their containers. But, I'm sure that can be worked around if you run into the problem.

Sign up for DotComIt's Monthly Technical Newsletter

Passing Parameters to a State - AngularJS UI Router - Part 7

This is part of a series of posts about the AngularJS UI Router. Check out part 1, part 2, part 3, Part 4, Part 5, and Part 6.

This is the last entry in this series. I'm going to modify the sample from the previous section to show you how to pass parameters to a state. We'll pass parameters to a headerController and use it to hide the link to the active state.

Resolve the Parameter

First, we'll need to modify the state definitions in the $stateProvider to pass a value to the views controller. In this case, we'll pass a hard coded string representing the name of the state. Here is the state definition for state1:


.state('state1', {
url: '/state1',
views : {
"header" : {templateUrl : 'states/08header.html',
controller:'headerController',
resolve : {
selectedNav : function(){
return "state1"
}
}
},
"mainContent" : {
templateUrl : 'states/07state1.html',
controller : 'state1Controller'
},
"footer" : {templateUrl : 'states/07footer.html'}
}
})

The header view definition is the one that changed the most. First, a controller, headerController, was added. We'll look at headerController shortly. Then a resolve property was added. The resolve property defines services, on demand, that will be passed to the view's controller. The new services are defined by a function, which returns the value of the service. Whenever the state is activated, the service functions are executed, and once all the service functions are activated the controller is initialized.

The definition for state2 is almost identical to state1:


.state('state2', {
url: '/state2',
views : {
"header" : {templateUrl : 'states/08header.html',
controller:'headerController',
resolve : {
selectedNav : function(){
return "state2"
}
}
},
"mainContent" : {
templateUrl : 'states/07state2.html',
controller : 'state2Controller'
},
"footer" : {templateUrl : 'states/07footer.html'}
}
})

The header view of state2 uses the same controller. It also passes in the same selectedNav service. The main difference is the value of that service. For the state1, the value of selectedNav is state1. For state2 the value of the selectedNav is state2.

Let's look at the headerController:


angular.module('routerTestApp').controller('headerController',
['$scope','selectedNav',function($scope,selectedNav){
$scope.selectedNav = selectedNav;
}]
);

The headerController is a simple controller. It accepts two arguments, the $scope and the selectedNav. All the code does is copy the selectedNav simple value into a $scope variable so it can be accessed inside the view template.

Remove the link to the Active State

To remove the link to the active state, open up the header.html file. You should see two links, similar to this:


<a ui-sref="state1" >State 1</a>
<a ui-sref="state2" >State 2</a>

To remove the states, the ng-hide will be used. We'll just put together a condition that compares the selectedNav controller variable to the actual selected state:


<a ui-sref="state1" ng-hide="selectedNav == 'state1'">State 1</a>
<a ui-sref="state2" ng-hide="selectedNav == 'state2'">State 2</a>

This will make things work.

Test the App

Load the app:

The app loads in the default state, state1. You'll see that the link to open state1 is hidden while state1 is displayed. Then click the State 2 link:

Once the app enters State2 the State2 link is hidden, and there is only a link to move back to state1.

Play with the App here!

Resolve can be a very powerful tool and is not limited to simple values. Objects, functions, promise objects, or other services can all be passed as values to a view controller using resolve.

Final Thoughts

The uiRouter is a great tool for Angular developers who want flexibility when piecing their applications together. As this white paper has shown, the complexity easily scales up and down depending upon your needs. I wish I had discovered it earlier than I did.

We wrote 20 pages on the Angular uiRouter, sign up to get it!

More Entries

All Content Copyright 2005, 2006, 2007, 2008, 2009 Jeffry Houser. May not be reused without permission
BlogCFC was created by Raymond Camden. This blog is running version 5.9.2.002.