views:

607

answers:

3

Hello!

I need to implement a certain kind of string truncation where a string splits in the middle and its left part becomes resizable. Here is what it might look like:

"Lorem ipsum dolor sit amet. Ut ornare dignissim ligula sed commodo."

becomes

"Lorem ipsum dolor sit amet ... commodo."

I am open to solutions using pure CSS or with some help of JavaScript/jQuery. So far I have tried CSS, but it did not give me the exact result I wanted. For one, I would like a string, once stretched out fully [in a table cell], so there's no need for truncation anymore, to lose the omission points ("...") in the middle and display normally.

Here is a pic to demonstrate how it's done in OS X: http://i40.tinypic.com/29yqslf.jpg

Thanks.

+1  A: 

The following Javascript function will do a middle truncation, like OS X:

function smartTrim(string, maxLength) {
    if (!string) return string;
    if (maxLength < 1) return string;
    if (string.length <= maxLength) return string;
    if (maxLength == 1) return string.substring(0,1) + '...';

    var midpoint = Math.ceil(string.length / 2);
    var toremove = string.length - maxLength;
    var lstrip = Math.ceil(toremove/2);
    var rstrip = toremove - lstrip;
    return string.substring(0, midpoint-lstrip) + '...' + string.substring(midpoint+rstrip);

It will replace characters in the middle with ellipsis. My unit tests show:

var s = '1234567890';
assertEquals(smartTrim(s, -1), '1234567890');
assertEquals(smartTrim(s, 0), '1234567890');
assertEquals(smartTrim(s, 1), '1...');
assertEquals(smartTrim(s, 2), '1...0');
assertEquals(smartTrim(s, 3), '1...90');
assertEquals(smartTrim(s, 4), '12...90');
assertEquals(smartTrim(s, 5), '12...890');
assertEquals(smartTrim(s, 6), '123...890');
assertEquals(smartTrim(s, 7), '123...7890');
assertEquals(smartTrim(s, 8), '1234...7890');
assertEquals(smartTrim(s, 9), '1234...67890');
assertEquals(smartTrim(s, 10), '1234567890');
assertEquals(smartTrim(s, 11), '1234567890');
johnvey
This is great and works as described, however I have a need to make the output string "stretchable", so that the truncation is determined based on one's viewport size. Huge screen—no truncation, narrow screen—string is truncated using a dynamically calculated number of characters for best fit.
Vasily
You'll have to attach an event handler to its container, which will then calculate the appropriate maxLength in relation to the container width property. If your font-family is monospaced, this will be easy; if proportional, then you'll need to experiment to get the right heuristic.
johnvey
+1  A: 

You can't do that with CSS. The problem is that HTML and CSS are supposed to work in a variety of browsers and fonts and it is almost impossible to calculate the width of a string in a consistent way. This is an idea that might help you. However, you would need to do that a number of times, until you find the string with the appropriate width.

kgiannakakis
+1  A: 

In the template engine put the real value in an custom tag like

<span original="your string here"></span>

Then put an onload and an onresize events to a javascript function which will read the original attribute and place it in the innerHTML of your span tag. Here is an example of the truncation function:

function start_and_end(str) {
  if (str.length > 35) {
    return str.substr(0, 20) + '...' + str.substr(str.length-10, str.length);
  }
  return str;
}

Adjust the values or possible make them dynamic if necessary for different objects. If you have users from different browsers you can steal a reference width from a text by the same font and size elsewhere in your dom. Then interpolate to an appropriate amount of characters to use.

A tip is also to have an abbr-tag on the ... or who message to make the user be able to get a tooltip with the full string.

<abbr title="simple tool tip">something</abbr>
Stefan Lundström
This ended up being the best basis for my final solution. With a few extra lines of JavaScript code it does exactly what I wanted it to do.I have decided to use "title" instead of the custom tag so now it provides accessibility naturally.Thanks Stefan, John, and Kgiannakakis!
Vasily