Tuesday, August 20, 2013

Sync up model with input field when setting value through Javascript in Angularjs

I was having issue with validation when using the bootstrap-datepicker.js for my angularjs app. The field has "required" text next to it initially and it supposed to go away when the user selected a date. Apparently, angularjs has problem with field being set through javascript instead of entering through the keyboard. When field is set through javascript, it doesn't get sync to the model. I found a work around by creating a directive that force the sync on change.

Here is the directive I am using as a work around.
angular.module('somemodule').directive('forcesync', [
    function () {
        return {
            restrict: 'A',
            require: '?ngModel',
            link: function ($scope, element, attrs, controller) {
                if (!attrs.type || attrs.type !== 'text' || !controller) {
                    return;
                }
                element.on('change', function () {
                    $scope.$apply(function () {
                        controller.$setViewValue(element.val());
                    });
                });
            }
        };
    }]);
Here is how you would use it.
<input forcesync id="date" name="date" ng-model="Date" ng-required="true" type="text" />