jQuery Placeholder Library on AngularJS
This is for anyone who has to build an AngularJS application that needs to support IE9 and below. Older IE browsers do not support the input placeholder attribute. To support this functionality with older IE browsers, javascript is used. Mathias created a very useful jQuery plugin to solve this issue. You will just need to execute this statement on ready:
$('input, textarea').placeholder()
However, this may not work in certain scenarios with AngularJS due to its asynchronous nature on loading HTML templates through ng-include, directives templateUrl properties. If you crawl through the source code of the placeholder plugin, you can see the event handlers “binding” to HTML components that already exist on the page. So any HTML components that are loaded after the ready event has already triggered will not have the placeholder event handlers attached to them.
One way to go about it is to modify the jQuery plugin. But if you want to keep the plugin unchanged (where you downloaded the code through bower), another way is to create a simple AngularJS directive called ‘placeholder’.
[code language=”javascript”]
directives.directive(‘placeholder’, function () {
return {
restrict: ‘A’,
scope: {
placeholder: ‘@’
},
link: function (scope, element, attrs) {
scope.$watch(‘placeholder’, function () {
if (scope.placeholder) {
$(element).placeholder();
}
});
}
};
});
[/code]
Note: The reason for the $scope.$watch on the ‘placeholder’ attribute is due to a data bind of the String (ie. supporting localization). You may not need the scope.$watch if your placeholder attribute contains a hard-coded String.
Update (8/7/2013):
The above solution has its drawbacks if one is using the ng-model attribute on an input element due to a new isolated scope created. If you are using ng-model on your input element, then one can define a placeholder directive as:
[code language=”javascript”]
directives.directive(‘placeholder’, function () {
return {
restrict: ‘A’,
link: function (scope, element, attrs) {
var placeholder = attrs.placeholder;
if (placeholder) {
$(element).placeholder();
}
}
};
})
[/code]
Note: The caveat to this solution is that the placeholder may need to be a hard-coded String. There may be a potential issue if the data in the placeholder attribute is a scope property value.
6 Comments