Sunday, September 20, 2015

AngularJS HTML5 Date Range Controller

When dealing with date input fields, we often rely on the use of JavaScripts date pickers to control how the user can enter the data.  These date pickers in most cases take away from the native experience especially on mobile devices.  

With the support of HTML5 in modern devices, we could eliminate the use of JavaScript date pickers and instead make use of the native date type support (more information here).  As an example,  Let’s take a look at how we can build a date range simple app with AngularJS and HTML5. 


In this implementation of a date range app, we bind our dateRange model properties (startDate, endDate) to two input fields (from,to). The idea is that based on the start date selection, we define the constraints for our end date. In this example, our constraints are set to a future date and no more than seven days.

To enable the native date picker control, we set both input fields to “type=date”. This enables the device to render a native control for the date selection as well as the limit on what can be typed in the control.

As we change the start date, the on-change event is raised.  In the handler for this event, we set the min and max HTML5 properties which help us on set the edge input constraints for the end date field. In our case, we set the min to one day more than the start date and max to seven days more.  This is done by binding the model properties (minDate,maxDate) to the input field properties (min,max) respectively. We should also note that we must use the ISO date format (yyyy-MM-dd) otherwise our constraints would not be enforced.

The result of settings these edge constraints are reflected on the date picker as only the dates with-in the constraints are enabled. All other dates are disabled (grayed-out) and can’t be selected.

As devices adapt the HTML5 standards, our apps can leverage their native support which enables our apps with a much better user experience.

Thanks for reading.

Saturday, September 12, 2015

AngularJS Autocomplete Directive with Label and Value Model Properties

With AngularJS, we can use the JQuery UI Autocomplete widget (details here) to convert any text box to an autocomplete control which can either call a web service or use an object array as data source.  The limitation with this widget is that it only knows of the one control associated to the directive which means that we can only set either the label or value.

To illustrate this limitation, let’s look at a simple customer search with autocomplete implementation in which we just type names starting with the letter O.

Problem Description:

As we type the client information, we can see that the widget automatically shows a list of names matching what has been entered. When a name is selected from the list, it is assigned to the autocomplete text box which is bound to a model property (, but for more practical purposes, we would also like to get the id.  We can also note the header label only shows the information that was typed, but not the selected name. There is also a problem with updating the view.


Since for most common cases we need the behavior to be similar to a Select control which has both a Label and Option value properties, we need to add a hidden input field and set the ng-model attribute to the model property, We are now set to capture the client name and id in two different fields. The problem still remains that we need to extend the autocomplete functionality, so that we are able to set the property on the form.

To address this challenge in a simple approach, we can add a callback on the controller scope which can be used by the directive to callback and set any additional properties.  Let’s take a look at a simple implementation of this approach:

The controller has a new scope function (setCliendData) which is available to the directive via the injected scope variable.  This function just sets the controller model with the selected option. The change on the directive is to implement the select event handler which is raised after every selection from the list. We should note that we need to call the controller function using scope.$apply to force a digest cycle which updates the view with the new model value.  If this is not done, the view would not get updated, and our header would not display the client id and name properly.

What to Note:

The autocomplete widget by default uses the properties value or label to build the list. If those properties are not found, a list with empty names is displayed. To address this, on the directive autocomplete source handler, we map the name property to the value (or label) property that is expected by the autocomplete widget.

We should note that this approach works by sharing the controller scope with the directive. When using isolated scope on the directive, the calls to the dataSource and setCliendData would not be available on the directive, and this would need to be implemented differently.  

I hope this provides some help on how to address some of the limitations when building autocomplete functionality on your apps.

Saturday, August 29, 2015

AngularJS Sharing Data Across Controllers with a Service

An AngularJS controller manages the data that is used with its associated HTML views. In some cases, there is a need for several controllers to share some common data. The common data can be user, security or settings that are needed to enable some access or configuration to elements on the view. For other cases, we may need to share data in different controllers to complete a process.

To see this in action, we can create a simple order system which works like a wizard and collects customer and food information. Each view on this demo is managed by a different controller.


Controllers are stateless and the data that is used by the controller is initialized every time it is loaded. To address this, we need a service that can be injected into the different controllers and can maintain the information. In AngularJS, a service is a singleton which only gets instantiated one time during the life cycle of the module. This allows us to maintain and share information across the initialization of different controllers.

In our demo, the svcAppData services persists the data that is captured from the user in each view.

Service Model:

this.detail = { name: '', dish: '', drink: '' };

Each controller accesses this information via the service detail model. This is done by the following statement:

ctrl.order = svcAppData.detail;

The views bind to the information by using the ng-model directive as shown below:

<input class="form-control" ng-model="" placeholder="enter name" type="text">

As the user enters the information, the data field in the model (detail) gets updated with the new information.

I hope this article is able to provide some clarity on how to use services and share data across controllers.