Last active
December 25, 2015 18:09
-
-
Save kkurni/7018564 to your computer and use it in GitHub Desktop.
Angular Placeholder for IE8/9 Support which compatible with validation attribute (e.g required)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
MyApp.directive('placeholder', function($timeout) { | |
return { | |
restrict: 'A', | |
require: 'ngModel', | |
link: function(scope, element, attr, ctrl) { | |
//check whether it support placeholder and cache it | |
scope.supportsPlaceholders = scope.supportsPlaceholders || function() { | |
return "placeholder" in document.createElement("input"); | |
}; | |
if (scope.supportsPlaceholders()) { | |
return; | |
} | |
//this function is used to move the caret to the left | |
var caretTo = function(el, index) { | |
if (el.createTextRange) { | |
var range = el.createTextRange(); | |
range.move("character", index); | |
range.select(); | |
} else if (el.selectionStart != null) { | |
el.focus(); | |
el.setSelectionRange(index, index); | |
} | |
}; | |
var setPlaceholder = function () { | |
element.val(attr.placeholder) | |
}; | |
var clearPlaceholder = function () { | |
element.val(''); | |
}; | |
element.bind('focus', function() { | |
//on focus, set the caret into 0 position | |
if (element.val() == attr.placeholder) { | |
caretTo(element[0], 0); | |
} | |
}); | |
element.bind('click', function() { | |
//on click, set the caret into 0 position | |
if (element.val() == attr.placeholder) { | |
caretTo(element[0], 0); | |
} | |
}); | |
element.bind('keydown', function(event) { | |
//disable left or right key code when there is placeholder | |
if (element.val() == attr.placeholder) { | |
if (event.keyCode == 37 || event.keyCode == 39) { | |
event.preventDefault(); | |
} | |
} | |
}); | |
element.bind('keypress', function() { | |
//on key press, clear the placeholder | |
if (element.val() == attr.placeholder) { | |
clearPlaceholder(); | |
} | |
}); | |
element.bind('blur', function () { | |
//on blur, we just set the placeholder if there is no value | |
if (element.val() == '') setPlaceholder(); | |
}); | |
//formatter is executed when the model is changed | |
ctrl.$formatters.unshift(function (val) { | |
if (!val) { | |
//this timeout is needed so that the validation can finish their binding before we put our placeholder value | |
$timeout(function(){ | |
setPlaceholder(); | |
return attr.placeholder; | |
}); | |
} | |
return val; | |
}); | |
} | |
}; | |
}); | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
describe('placeholder', function() { | |
var element, $scope, $timeout, $compile; | |
beforeEach(module('MyApp')); | |
beforeEach(angular.mock.inject(function($rootScope, _$compile_, _$timeout_) { | |
$scope = $rootScope.$new(); | |
$timeout = _$timeout_; | |
$compile = _$compile_; | |
$scope.supportsPlaceholders = function() { | |
return false; | |
}; | |
element = angular.element('<input type="text" placeholder="enter placeholder" ng-model="model" />'); | |
$compile(element)($scope); | |
$scope.$digest(); | |
$scope = element.scope(); | |
})); | |
describe('$formatter', function() { | |
it('should set element value to placeholder if model is undefined', function() { | |
$timeout.flush(); | |
expect(element.val()).toEqual('enter placeholder'); | |
}); | |
it('should set element value to model value if model is defined', function() { | |
$timeout.flush();//flush the first time out | |
$scope.model = 'some model'; | |
$compile(element)($scope); | |
$scope.$digest(); | |
expect(element.val()).toEqual('some model'); | |
}); | |
}); | |
describe('on keypress', function() { | |
it('should clear element value if it is the same as a placeholder', function() { | |
element.triggerHandler('keypress'); | |
expect(element.val()).toEqual(''); | |
}); | |
}); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment