Reputation: 17721
I need to (dynamically) render text inside fixed-length buttons in a ng-repeat block.
I would like to get DOM rendered text width (to be able to truncate it, and add an ellipsis entity...).
This is my html:
<span ng-repeat="(key, item) in players" limit-text-length max-len="100">
<div class="btn">
<div id="player-{{key}}">{{item.name}}</div>
</div>
</span>
This is my current directive:
app.directive('limitTextLength', function() {
return function(scope, element, attrs) {
var maxLen = attrs.maxLen;
var el = element.find("[id^=player-]"); // <-- THIS DOESN'T WORK...
if (el.width() > maxLen) { // check text is not too wide
while (el.width() > maxLen) {
var nameTruncated = el.html();
nameTruncated = nameTruncated.substring(0, nameTruncated.length - 1);
el.html(nameTruncated);
}
el.append('…');
}
};
Any suggestion?
Upvotes: 1
Views: 2204
Reputation: 48211
element.find("[id^=player-]")
won't work without jQuery, because Angular's jqLite's find()
is limited to lookups by tag name (according to the docs).
You could use the native querySelector()
method, which has good support in browsers:
//var el = element.find("[id^=player-]");
var el = angular.element(element[0].querySelector('[id^="player-"'));
Of course, without jQuery the .width()
method won't be available, but if you do use jQuery, your selector should work fine.
There is also a typo: var maxLen = attrs.len;
should be var maxLen = attrs.maxLen;
That said, the main problem is that the element's actual width is determined after being rendered (which hasn't happened at the time you check). You could make sure you check after the element has been rendered, by wrapping the relevant code inside $timeout
.
Your directive could be modified like this (assuming jQuery is included):
app.directive('limitTextLength', function ($timeout) {
return function(scope, element, attrs) {
var maxLen = attrs.maxLen;
var el = element.find("[id^=player-]");
$timeout(function () {
if (el.width() > maxLen) { // check text is not too wide
while (el.width() > maxLen) {
console.log(el.width());
var nameTruncated = el.html();
nameTruncated = nameTruncated.substring(0, nameTruncated.length - 1);
el.html(nameTruncated);
}
el.append('…');
}
});
};
});
See, also, this short demo.
BTW, if it is just for the ellipsis, you could use CSS3's text-overflow
property.
Upvotes: 3