2

I need to truncate strings in a side menu to make them fit into a div without a linebreak. The divs have a fixed width. I'm looking for a library to do that for me. If a string is too long to fit into the div, it should be truncated like this:

<div>This string is too long</div> ==> <div>This string is...ong</div>

As you can see, the string is not only truncated by an ellipsis but the last three letters are also visible. This is meant to increase readability. The truncation should not care about spaces.

Does anyone know of a library that includes such functionality? We're mainly using jQuery throughout the project.

Thanks in advance!

dda
  • 6,030
  • 2
  • 25
  • 34
j0ker
  • 4,069
  • 4
  • 43
  • 65

3 Answers3

2

I don't know of a library per se that does that, but using an HTML5 Canvas and Canvas text metrics, you could determine whether the string would fit in, and if not, how much you'd have to cut it out.

var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');
context.font = '12pt Arial';
var metrics = context.measureText('measure me!');
var width=metrics.width;
dda
  • 6,030
  • 2
  • 25
  • 34
2

Once I used jQuery.dotdotdot.

Consider your html as

<div class="longtext">This string is too long</div>

Just use this javascript after using dotdotdot

$(document).ready(function() {
    $(".longtext").dotdotdot();
});

Visit their website for more configurable options.

Abdul Munim
  • 18,869
  • 8
  • 52
  • 61
  • Looks nice. But it seems that this library doesn't work right if the div with the overlong text isn't displayed at document.ready. Since this is the case, it doesn't work for me. – j0ker Nov 15 '12 at 12:09
  • @j0ker - no but you would call .dotdotdot(); after you have loaded the text in. – Eddie Aug 12 '13 at 09:23
1

This JSFiddle shows a simple solution:

/**
 * Uses canvas.measureText to compute and return the width of the given text of given font.
 * 
 * @param text The text to be rendered.
 * @param {String=} fontStyle The style of the font (e.g. "bold 12pt verdana").
 * @param {Element=} canvas An optional canvas element to improve performance. If not given, the function will create a new temporary canvas element.
 * 
 * @see http://stackoverflow.com/questions/118241/calculate-text-width-with-javascript/21015393#21015393
 */
function getTextWidth(text, fontStyle, canvas) {
    // if given, use cached canvas for better performance
    // else, create new canvas
    canvas = canvas || document.createElement("canvas");
    var context = canvas.getContext("2d");
    context.font = fontStyle;
    var metrics = context.measureText(text);
    return metrics.width;
}


/**
 * Returns text whose display width does not exceed the given maxWidth.
 * If the given text is too wide, it will be truncated so that text + ellipsis
 * is still less than maxWidth wide.
 * 
 * @param text The text to be truncated.
 * @param {String} fontStyle The font style that the string is to be rendered with.
 * @param maxWidth Max display width of string.
 * @param {String=} ellipsis Set to "..." by default.
 * @param {Element=} canvas Optional canvas object to improve performance.
 * 
 */
function truncateText(text, fontStyle, maxWidth, ellipsis, canvas) {
    var width;
    var len = text.length;
    ellipsis = ellipsis || "...";
    while ((width = getTextWidth(text, fontStyle, canvas)) > maxWidth) {
        --len;
        text = text.substring(0, len) + ellipsis;
    }
    return text;
}

The example:

var maxWidth = 200;
var fontStyle = "bold 12pt arial";
var text = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.";
var truncatedText = truncateText(text, fontStyle, maxWidth)
console.log(truncatedText);

Generates: "Lorem ipsum dolor sit a..."

Domi
  • 22,151
  • 15
  • 92
  • 122