Last active
December 15, 2015 07:12
-
-
Save rishabhmhjn/3f9e35e9ad7ee933888c to your computer and use it in GitHub Desktop.
An extension to md-maxlength from Angular Material (https://material.angularjs.org/latest/api/directive/mdInput) to calculate a tweet's length using the twitter-text-js library. Demo http://plnkr.co/edit/UC0aHq?p=preview
This file contains 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
(function() { | |
// angular.module('TwttrMaxlengthDirectiveDemo', ['ngMaterial']) | |
// .constant('twttr', twttr) // https://github.com/twitter/twitter-text/tree/master/js | |
// .directive('twttrMaxlength', TwttrMaxlengthDirective); | |
TwttrMaxlengthDirective.$inject = ['$animate', 'twttr']; | |
function TwttrMaxlengthDirective($animate, twttr) { | |
return { | |
restrict: 'A', | |
require: ['ngModel', '^mdInputContainer'], | |
link: postLink | |
}; | |
function postLink(scope, element, attr, ctrls) { | |
var maxlength; | |
var ngModelCtrl = ctrls[0]; | |
var containerCtrl = ctrls[1]; | |
var charCountEl = angular.element('<div class="md-char-counter">'); | |
var input = angular.element(containerCtrl.element[0].querySelector('[twttr-maxlength]')); | |
// Stop model from trimming. This makes it so whitespace | |
// over the maxlength still counts as invalid. | |
attr.$set('ngTrim', 'false'); | |
var ngMessagesSelectors = [ | |
'ng-messages', | |
'data-ng-messages', | |
'x-ng-messages', | |
'[ng-messages]', | |
'[data-ng-messages]', | |
'[x-ng-messages]' | |
]; | |
var ngMessages = containerCtrl.element[0].querySelector(ngMessagesSelectors.join(',')); | |
// If we have an ngMessages container, put the counter at the top; otherwise, put it after the | |
// input so it will be positioned properly in the SCSS | |
if (ngMessages) { | |
angular.element(ngMessages).prepend(charCountEl); | |
} else { | |
input.after(charCountEl); | |
} | |
ngModelCtrl.$formatters.push(renderCharCount); | |
ngModelCtrl.$viewChangeListeners.push(renderCharCount); | |
element.on('input keydown keyup', function() { | |
renderCharCount(); //make sure it's called with no args | |
}); | |
scope.$watch(attr.twttrMaxlength, function(value) { | |
maxlength = value; | |
if (angular.isNumber(value) && value > 0) { | |
if (!charCountEl.parent().length) { | |
$animate.enter(charCountEl, containerCtrl.element, input); | |
} | |
renderCharCount(); | |
} else { | |
$animate.leave(charCountEl); | |
} | |
}); | |
ngModelCtrl.$validators['twttr-maxlength'] = function(modelValue, viewValue) { | |
if (!angular.isNumber(maxlength) || maxlength < 0) { | |
return true; | |
} | |
var valLength = twttr.txt.getTweetLength(modelValue || element.val() || viewValue || ''); | |
return valLength <= maxlength; | |
}; | |
function renderCharCount(value) { | |
// Force the value into a string since it may be a number, | |
// which does not have a length property. | |
charCountEl.text( | |
twttr.txt.getTweetLength(String(element.val() || value || '')) + '/' + maxlength | |
); | |
return value; | |
} | |
} | |
} | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment