Christian Droulers

Agile and flexible programmer

AngularJS Bootstrap Datepicker

Posted on 2015-03-18

The Twitter bootstrap framework is a great tool to quick-start applications and continue building them in the long term. They even built an AngularJS library to easily integrate the two.

I wanted to integrate the Datepicker since we have a birth date field in our forms. The problem was that according to the example, we had to declare a boolean openedproperty AND an open function on the scope to set opened to true. (Read the example linked previously to see what I mean)

This is a bit annoying. I really don’t want to pollute my controller code with multiple boolean values and functions just to open a datepicker when clicking on the add-on button.

The solution I found while researching is the following:

Modify the global scope to have a globally available function for opening date pickers:

1
2
3
4
5
6
7
8
9
10
11
12
13
angular.module("shared.ui").config(($provide) => {
    $provide.decorator("$rootScope",($delegate) => {
        $delegate.__proto__.OpenDatePicker = function ($event) {
            $event.preventDefault();
            $event.stopPropagation();

            var fieldName = $($event.target).parents(".input-group:first")
                .find(":input[datepicker-options]").attr("name");
            this["datePickerOpenedFor" + fieldName] = true;
        };
        return $delegate;
    });
})

And then, when creating the datepicker, this method can be used automatically:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<div class="input-group has-addon">
    <input 
        class="form-control" 
        datepicker-options="{ }" 
        datepicker-popup=""
        id="dateOfBirth"
        is-open="datePickerOpenedFordateOfBirth"
        name="dateOfBirth"
        ng-click="OpenDatePicker($event)"
        ng-model="DateOfBirth">
    <span class="input-group-btn">
        <button type="button" class="btn btn-default" ng-click="OpenDatePicker($event)">
            <i class="glyphicon glyphicon-calendar"></i>
        </button>
    </span>
</div>

As you can see, the OpenDatePicker function is available on every scope. It basically just looks for the input’s name to modify the datePickerOpenedFor{name} boolean property.

Now I can easily add new Datepickers anywhere I want without worrying about setting it up manually.

comments powered by Disqus