angularjs directive to fit text in an overflow hidden element
replace text that would be too long to fit an overflow:hidden block with an abbr and an elipse.
by mortimerpa
HTML
<script src="http://code.angularjs.org/1.1.0/angular.min.js"></script>
<div ng-app="jsf">
<div ng-controller="MyCtrl">
<div ng-repeat="name in names">
<long-name class="width" outer="strong" long-val="{{name.first}} {{name.second}}"/>
</div>
</div>
</div>
CSS
.width {
width: 106px;
border-right: 1px solid black;
overflow:hidden;
display: inline-block;
}
JavaScript
angular.module('jsf', []).directive('longName', function() {
function hasScrollbar(elm) {
var _elm = elm[0];
var oldDisplay = elm.css('display');
var oldWidth = _elm.offsetWidth;
elm.css('display', 'inline');
var newWidth = _elm.offsetWidth;
elm.css('display', oldDisplay);
if (_elm === undefined) {
return false;
}
if (oldWidth < newWidth) {
return true;
}
return false;
}
function dichotomy(low, high, name, elm, outer) {
if (low >= high) {
return;
}
if (low === 0 && high === name.length) {
elm.html('<' + outer + '>' + name.substring(0, high) + "</" + outer + ">");
} else {
elm.html('<' + outer + '><abbr title="' + name + '">' + name.substring(0, high) + "…</attr></" + outer + ">");
}
if (hasScrollbar(elm)) {
dichotomy(low, high / 2, name, elm, outer);
} else {
dichotomy(high, low + high / 2, name, elm, outer);
}
}
return {
restrict: 'E',
link: function(scope, element, attr) {
attr.$observe('longVal', function() {
var name = attr.longVal;
var maxLen = name.length;
dichotomy(0, name.length, name, element, attr.outer);
});
}
};
}).controller('MyCtrl', function($scope) {
$scope.names = [{
first: "Betty",
second: "Bushaksteinwitzskymansonescubergsen"},
{
first: "shorty",
second: "long"}];
});