Skip to content

Instantly share code, notes, and snippets.

@rishabhmhjn
Last active December 15, 2015 07:12
Show Gist options
  • Save rishabhmhjn/3f9e35e9ad7ee933888c to your computer and use it in GitHub Desktop.
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
(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