Check out our new training course on AngularJS for Flex Developers

Use an External Component Template -- Build a Color Picker in Angular 2 - Part 1

This series of blog posts will document documents a quick little prototype I put together for a client. They wanted to be able to click on an image and get information about the color at the selected spot. It makes use of the HTML5 Canvas tag and is the most "Flash-like" thing I've done with HTML.

This first in the series will show you how to use an external template to an Angular 2 Component and how to access HTML Elements within that template.

Setup the App

The first step is to import all the Angular 2 libraries:


<script src="https://unpkg.com/core-js/client/shim.min.js"></script>
<script src="https://unpkg.com/zone.js@0.6.25?main=browser"></script>
<script src="https://unpkg.com/reflect-metadata@0.1.8"></script>
<script src="https://unpkg.com/rxjs@5.0.0-beta.12/bundles/Rx.js"></script>
<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>

Angular 2 is split into a lot of individual libraries instead of one big one like AngularJS 1.x branch. Next create the component:


(function(app) {
app.AppComponent =
ng.core.Component({
selector: 'colorpicker-app',
})
.Class({
constructor: function() {
}
});
})(window.app || (window.app = {}));

This is a typical Angular component. The name is colorpicker-app. We'll put a lot of code in the constructor later in this article. A template is not specified, but is required. We'll create that in the next section.

Next create the Angular module:


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

The module declares our custom AppComponent and also bootstraps it. Finally, boot strap the main module:


(function(app) {
document.addEventListener('DOMContentLoaded', function() {
ng.platformBrowserDynamic.platformBrowserDynamic().bootstrapModule(app.AppModule);
});
})(window.app || (window.app = {}));

In the HTML body, use the colorpicker-app directive to load the component:


<colorpicker-app>Loading...</colorpicker-app>

Run the code as is:

Not too impressive, we get an error because of the missing template. There are two ways we could add a template.

Create an in-line template

It is easy to create an in-line template. Just add the template property to the colorpicker-app component definition:


ng.core.Component({
selector: 'colorpicker-app',
template : 'something'
})

Rerun the app:

I hate dealing with in-line templates because as the HTML gets wordy they are complicated to maintain and change.

Create the external template

We can create an external template using the templateUrl property:


ng.core.Component({
selector: 'colorpicker-app',
templateUrl : '02canvas.html'
})

The templateUrl property is put on the colorpicker-app component and replaces the template property we used in the last section. The templateUrl specifies the URL location of a template, in this case I refer to a template in the same directory, canvas.html:


Something in external template

The template code is just some text. Run the code:

When building AngularJS 1 applications, the templateUrl sometimes caused a problem with relative URLs after you ran the code through a build script with minimizers. This was because the location of the final minimized code was not always the location of the original code; and the browser wouldn't find the template. The same problem exists in Angular 2 applications. It can be solved by using a path relative to the root directory of the web server; but for now I kept it simple.

What's Next

I'm going to stop this article here. The next article will go into details on how create and access the canvas inside Angular 2.

Sign up for DotComIt's Monthly Technical Newsletter

Unhandled rejection Error: Not running at Server.close (net.js:1236:11) with Karma and Jasmine

I'm writing some addendum to my LearnWith AngularJS training series. One of those will detail how to unit test an AngularJS web application. I'm setting something up with Gulp, Karma, and Jasmine.

Trying to get this running gave me a full day of this error:


Unhandled rejection Error: Not running
at Server.close (net.js:1236:11)
at C:\Users\jhouser\Documents\career\clients\ActiveClients\LearnWith\Development\www_codearchive\Scripts_Test\node_modules\karma\lib\server.js:388:17
at tryCatcher (C:\Users\jhouser\Documents\career\clients\ActiveClients\LearnWith\Development\www_codearchive\Scripts_Test\node_modules\karma\node_modules\bluebird\js\release\util.js:16:23)
at Promise._settlePromiseFromHandler (C:\Users\jhouser\Documents\career\clients\ActiveClients\LearnWith\Development\www_codearchive\Scripts_Test\node_modules\karma\node_modules\bluebird\js\release\promise.js:510:31)
at Promise._settlePromise (C:\Users\jhouser\Documents\career\clients\ActiveClients\LearnWith\Development\www_codearchive\Scripts_Test\node_modules\karma\node_modules\bluebird\js\release\promise.js:567:18)
at Promise._settlePromise0 (C:\Users\jhouser\Documents\career\clients\ActiveClients\LearnWith\Development\www_codearchive\Scripts_Test\node_modules\karma\node_modules\bluebird\js\release\promise.js:612:10)
at Promise._settlePromises (C:\Users\jhouser\Documents\career\clients\ActiveClients\LearnWith\Development\www_codearchive\Scripts_Test\node_modules\karma\node_modules\bluebird\js\release\promise.js:691:18)
at Async._drainQueue (C:\Users\jhouser\Documents\career\clients\ActiveClients\LearnWith\Development\www_codearchive\Scripts_Test\node_modules\karma\node_modules\bluebird\js\release\async.js:138:16)
at Async._drainQueues (C:\Users\jhouser\Documents\career\clients\ActiveClients\LearnWith\Development\www_codearchive\Scripts_Test\node_modules\karma\node_modules\bluebird\js\release\async.js:148:10)
at Async.drainQueues (C:\Users\jhouser\Documents\career\clients\ActiveClients\LearnWith\Development\www_codearchive\Scripts_Test\node_modules\karma\node_modules\bluebird\js\release\async.js:17:14)
at process._tickCallback (node.js:419:13)

There is a lot of Google hits for this error; but none actually relate to my issue, so I hope this helps someone.

After much head pounding and experimentation; I finally deciphered the cause. When creating the Karma config file, make sure that your files are put in proper dependency order. Simply put; I was listing the AngularJS library at the end of the file list instead of the beginning, so the code didn't know how to create angular modules, services, or other elements, because that Angular library wasn't defined yet.

Changing the order of dependencies solved the issue and I can run unit tests as expected.

I hope that helps someone.

Sign up for DotComIt's Monthly Technical Newsletter

Button Clicks - Introduction to Angular 2 with JavaScript - Part 3

This is the third in a series about building a simple AngularJS application. If you haven't already, check out part 1 and part 2.

Review

In part 1 we built a simple component that displayed a template to the screen. In part 2 we showed how to bind a Class variable to an input and a display. Let's review the Angular component code:


(function(app) {
app.AppComponent =
ng.core.Component({
selector: 'my-app',
template: '<h1>Hello {{helloTo}}</h1>' +
'<input type="text" [value]="helloTo" (input)="helloTo=$event.target.value" /><br/>' +
'<input type="text" [(ngModel)]="helloTo" /><br/>'
})
.Class({
constructor: function() {
this.helloTo = "World"
}
})
})(window.app || (window.app = {}));

The component is wrapped in an IIFE function; and the Angular application is stored in the window.app variable. The component is given a selector, my-app, which is in essence the name. The template includes two inputs demonstrating two different ways to bind to values in Angular 2.

The Class contains a single variable, helloTo, which is used as the source for binding.

Change the Template

Another common element required when developing applications is to run code when a button is clicked. In Angular 1 we used the ngClick event. Angular 2 uses a similar concept, but is slightly different implementation syntax. Here is the component's template as a reminder:


template: '<h1>Hello {{helloTo}}</h1>' +
'<input type="text" [value]="helloTo"
(input)="helloTo=$event.target.value" />
<br/>' +
'<input type="text" [(ngModel)]="helloTo" /><br/>'

The template consists of a header which binds to the helloTo variable. It has two inputs, both representing different methods to change the helloTo variable.

We'll add one more item to the template. Here is a button:


'<button (click)="onReset()">reset</button><br/>' +

I put the button after the header, but before the inputs. Instead of using an ngClick directive, the directive is named click, and is enclosed by parenthesis. The click statement on the button will call a method inside the component's class.

Create the Click Handler

We want to the button to reset the helloTo variable to its default value, World. After the helloTo variable is created in the Class, add a function named onReset():


this.onReset = function(){
this.helloTo = "World";
}

Run the code, and you should see something like this:

Change one of the inputs, and click the reset button. The app should go back to its default state.

Play with the code here

Final Thoughts

I enjoyed my experiments with Angular 2 and JavaScript. Based on available documentation, I'd be cautious about jumping into Angular 2 deep at the time of this writing. If I were going to; I'd focus on TypeScript. The full documentation for JavaScript is not there yet and most of the community questions revolve around TypeScript answers, which are not always easily portable to JavaScript. Despite all this; I'm cautiously optimistic about our Angular 2 future.

Get our Intro to Angular 2 White Paper

Data Binding - Introduction to Angular 2 with JavaScript - Part 2

This is the second in a series about building a simple AngularJS application. If you haven't already, check out part 1.

This post will expand the sample from the previous article to demonstrate binding in an Angular 2 application. This sample will demonstrate how to bind user input to an Angular 2 display. To do that we only need to make a few architecture changes, and then a bunch of changes to the AppComponent.

Architecture Changes

Two architecture changes are needed. First, we need to import the Angular Forms library:


<script src="https://unpkg.com/@angular/forms@2.2.0"></script>

Angular 2 is purposely split up into multiple libraries, so you only have to import the items that you need. Next, tell your module to use the forms library. To do this, modify the imports command on the ngModule:


imports: [ ng.platformBrowser.BrowserModule, ng.forms.FormsModule ],

The imports value is an array, so adding the new import is just a matter of adding it to the end of the array. All this is so we can use the ngModel directive inside our template.

Review the Component

Next, we need to make changes to the AppComponent, which is the main component of the application. This is the component as we left it off:


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

This component consists of two parts. The first is the main Component, which includes the component's selector and template. The component's selector is its name and that does not need to change for this article. The component's Class is the JavaScript behind the component. To date the class does nothing.

Change the Class

First, make changes to the Class. Add a helloTo variable inside the constructor:


.Class({
constructor: function() {
this.helloTo = "World"
}
})

The class parallels a controller inside of an AngularJS 1 application.

Change the Template

Next, we need to modify the template inside the component. The selector does not need to change, but we will make a lot of changes to the template. First, change the header to say hello world:


template: '<h1>Hello {{helloTo}}</h1>' +

Angular 2 uses the same view binding syntax as Angular 1 does. The plus at the end of the template is the JavaScript concatenation operator. It means we're going to add more lines. Let's start with an input:


'<input type="text" [value]="helloTo"
(input)="helloTo=$event.target.value" />
<br/>' +

The input is a standard HTML input, with the type of text. The value and the input parameters are both related to Angular. The value is enclosed in square brackets. I interpret this to mean that whenever the helloTo variable changes it will also change the value of the input. This is not bidirectional. The input is surrounded by parenthesis. This is like calling a function. Whenever the input changes, the function will be executed; and the function changes the helloTo variable. The function body is defined in-line; but we could split it out into a separate function inside the component's class.

I couldn't find solid definition for the bracket or parenthesis syntax in relation to the input and AngularJS. But, my interpretation is that the parenthesis always means a method is called; and the brackets always mean a value is set.

Angular 2 also includes a parallel the ngModel directive from Angular 1:


'<input type="text" [(ngModel)]="helloTo" /><br/>'

The ngModel text is enclosed in both brackets and parenthesis. This represents two way binding in Angular 2. Behind the scenes Angular 2 changes the helloTo class variable whenever the input changes; and the text input whenever the helloTo variable changes.

Final Thoughts

Try to run this:

As you type in one of the inputs, you'll see the other input changes as well as the hello header.

Play with the code here.

There are a few other ways you could set up the input to achieve the exact same purpose, but for the purposes of this article I decided to stop at two.

The last section of this series will focus on adding a reset button to the component.

Get our Updated Intro to Angular 2 White Paper

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

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.