101

I'm looking for a simple script which can truncate a string with ellipsis (...)

I want to truncate something like 'this is a very long string' to 'this is a ve...'

I don't want to use CSS or PHP.

Mel
  • 5,837
  • 10
  • 37
  • 42
Dollar Friend
  • 1,019
  • 2
  • 7
  • 4
  • 5
    Do you mean to truncate something like `'this is a very long string'` to `'this is a ve...'` etc? – El Ronnoco Jan 15 '11 at 14:59
  • Can you provide and example? And what do you mean by TEXT? – jzd Jan 15 '11 at 14:59
  • @jzd please see this screenshot http://i964.photobucket.com/albums/ae123/DollarFriend/well.png – Dollar Friend Jan 16 '11 at 00:15
  • possible duplicate of [smart way to shorten long strings with javascript](http://stackoverflow.com/questions/1199352/smart-way-to-shorten-long-strings-with-javascript) – Artiom Jul 23 '15 at 11:10

11 Answers11

199
function truncate(input) {
   if (input.length > 5) {
      return input.substring(0, 5) + '...';
   }
   return input;
};

or in ES6

const truncate = (input) => input.length > 5 ? `${input.substring(0, 5)}...` : input;
Gianfranco P.
  • 10,049
  • 6
  • 51
  • 68
El Ronnoco
  • 11,753
  • 5
  • 38
  • 65
  • 5
    This (string.substr(0,5)+'...';) worked for me. – syam Mar 03 '18 at 04:29
  • 5
    If you want to please typographers you can use `…` which is a dedicated glyph for ellipsis where the space between the dots is a bit narrower. – st_phan Jun 29 '21 at 08:44
45

KooiInc has a good answer to this. To summarise:

String.prototype.trunc = 
      function(n){
          return this.substr(0,n-1)+(this.length>n?'…':'');
      };

Now you can do:

var s = 'not very long';
s.trunc(25); //=> not very long
s.trunc(5); //=> not...

And if you prefer it as a function, as per @AlienLifeForm's comment:

function truncateWithEllipses(text, max) 
{
    return text.substr(0,max-1)+(text.length>max?'…':''); 
}

Full credit goes to KooiInc for this.

Jarrod
  • 9,349
  • 5
  • 58
  • 73
  • 6
    Concise is nice. I used it as: `function truncateWithEllipses(text, max) {return text.substr(0,max-1)+(text.length>max?'…':''); }` – Alien Life Form Oct 28 '15 at 19:09
  • I like the solution from comment above @AlienLifeForm very elegant – user2709153 Apr 20 '18 at 13:46
  • This is a good one-liner but it truncates the string even when its length doesn't exceed the limit. I would add a conditional (ES6 example): `export const characterLimit = (text, limit) => text.length > limit ? (text.substr(0, limit - 1).trim() + '...') : text;` – Anton Feb 01 '19 at 13:19
  • 1
    ES6 function with ending argument: `truncateWithEllipses = (text, max, ending = '…') => text.length > max ? text.substr(0, max - ending.length) + ending : text;` – Kévin Berthommier Apr 09 '19 at 15:38
  • 2
    @KévinBerthommier Probably shouldn't be called `truncateWithEllipses` if you're also providing a `ending` param, since you can change what the `ending` is and then it is no longer `WithEllipses`. – Joshua Pinter May 13 '19 at 20:50
  • Wouldnt directly add functionalities to the prototype . – Kevin.a Jul 31 '19 at 11:21
16

This will limit it to however many lines you want it limited to and is responsive

An idea that nobody has suggested, doing it based on the height of the element and then stripping it back from there.

Fiddle - https://jsfiddle.net/hutber/u5mtLznf/ <- ES6 version

But basically you want to grab the line height of the element, loop through all the text and stop when its at a certain lines height:

'use strict';

var linesElement = 3; //it will truncate at 3 lines.
var truncateElement = document.getElementById('truncateme');
var truncateText = truncateElement.textContent;

var getLineHeight = function getLineHeight(element) {
  var lineHeight = window.getComputedStyle(truncateElement)['line-height'];
  if (lineHeight === 'normal') {
    // sucky chrome
    return 1.16 * parseFloat(window.getComputedStyle(truncateElement)['font-size']);
  } else {
    return parseFloat(lineHeight);
  }
};

linesElement.addEventListener('change', function () {
  truncateElement.innerHTML = truncateText;
  var truncateTextParts = truncateText.split(' ');
  var lineHeight = getLineHeight(truncateElement);
  var lines = parseInt(linesElement.value);

  while (lines * lineHeight < truncateElement.clientHeight) {
    console.log(truncateTextParts.length, lines * lineHeight, truncateElement.clientHeight);
    truncateTextParts.pop();
    truncateElement.innerHTML = truncateTextParts.join(' ') + '...';
  }
});

CSS

#truncateme {
   width: auto; This will be completely dynamic to the height of the element, its just restricted by how many lines you want it to clip to
}
Jamie Hutber
  • 26,790
  • 46
  • 179
  • 291
11

Something like:

var line = "foo bar lol";
line.substring(0, 5) + '...' // gives "foo b..."
  • 13
    This is not a complete solution. You need to check if the string is actually bigger than the amount you are going to truncate. If false, then the `...` should not appear. Just using `line.substring(0, max_char)` won't be a sufficient enough solution. – user1952811 May 16 '14 at 17:09
  • Upvoted for terseness. OP did not specify threshold requirement. – vhs May 07 '22 at 13:03
9

This will put the ellipsis in the center of the line:

function truncate( str, max, sep ) {

    // Default to 10 characters
    max = max || 10;

    var len = str.length;
    if(len > max){

        // Default to elipsis
        sep = sep || "...";

        var seplen = sep.length;

        // If seperator is larger than character limit,
        // well then we don't want to just show the seperator,
        // so just show right hand side of the string.
        if(seplen > max) {
            return str.substr(len - max);
        }

        // Half the difference between max and string length.
        // Multiply negative because small minus big.
        // Must account for length of separator too.
        var n = -0.5 * (max - len - seplen);

        // This gives us the centerline.
        var center = len/2;

        var front = str.substr(0, center - n);
        var back = str.substr(len - center + n); // without second arg, will automatically go to end of line.

        return front + sep + back;

    }

    return str;
}

console.log( truncate("123456789abcde") ); // 123...bcde (using built-in defaults) 
console.log( truncate("123456789abcde", 8) ); // 12...cde (max of 8 characters) 
console.log( truncate("123456789abcde", 12, "_") ); // 12345_9abcde (customize the separator) 

For example:

1234567890 --> 1234...8910

And:

A really long string --> A real...string

Not perfect, but functional. Forgive the over-commenting... for the noobs.

bob
  • 7,539
  • 2
  • 46
  • 42
  • 1
    Some other similar functions: http://stackoverflow.com/questions/831552/ellipsis-in-the-middle-of-a-text-mac-style/30613599#30613599 – bob Jun 03 '15 at 07:32
8

For preventing the dots in the middle of a word or after a punctuation symbol.

let parseText = function(text, limit){
  if (text.length > limit){
      for (let i = limit; i > 0; i--){
          if(text.charAt(i) === ' ' && (text.charAt(i-1) != ','||text.charAt(i-1) != '.'||text.charAt(i-1) != ';')) {
              return text.substring(0, i) + '...';
          }
      }
       return text.substring(0, limit) + '...';
  }
  else
      return text;
};
    
    
console.log(parseText("1234567 890",5))  // >> 12345...
console.log(parseText("1234567 890",8))  // >> 1234567...
console.log(parseText("1234567 890",15)) // >> 1234567 890
Ramin Bateni
  • 16,499
  • 9
  • 69
  • 98
David Ortiz
  • 997
  • 1
  • 14
  • 22
  • 1
    I liked your solution but your function had a bug without `return text.substring(0, limit) + '...';`. I edited your answer and added that line to your code + some other micro changes. Without that line, `parseText("1234567 890",5)` return `undefined` but now it works well. – Ramin Bateni Jun 06 '19 at 13:05
5

Easiest and flexible way: JSnippet DEMO

Function style:

function truncString(str, max, add){
   add = add || '...';
   return (typeof str === 'string' && str.length > max ? str.substring(0,max)+add : str);
};

Prototype:

String.prototype.truncString = function(max, add){
   add = add || '...';
   return (this.length > max ? this.substring(0,max)+add : this);
};

Usage:

str = "testing with some string see console output";

//By prototype:
console.log(  str.truncString(15,'...')  );

//By function call:
console.log(  truncString(str,15,'...')  );
Shlomi Hassid
  • 6,500
  • 3
  • 27
  • 48
2

Try this

function shorten(text, maxLength, delimiter, overflow) {
  delimiter = delimiter || "&hellip;";
  overflow = overflow || false;
  var ret = text;
  if (ret.length > maxLength) {
    var breakpoint = overflow ? maxLength + ret.substr(maxLength).indexOf(" ") : ret.substr(0, maxLength).lastIndexOf(" ");
    ret = ret.substr(0, breakpoint) + delimiter;
  }
  return ret;
}

$(document).ready(function() {
  var $editedText = $("#edited_text");
  var text = $editedText.text();
  $editedText.text(shorten(text, 33, "...", false));
});

Checkout a working sample on Codepen http://codepen.io/Izaias/pen/QbBwwE

Izaias
  • 389
  • 3
  • 15
2
function truncate(string, length, delimiter) {
   delimiter = delimiter || "&hellip;";
   return string.length > length ? string.substr(0, length) + delimiter : string;
};

var long = "Very long text here and here",
    short = "Short";

truncate(long, 10); // -> "Very long ..."
truncate(long, 10, ">>"); // -> "Very long >>"
truncate(short, 10); // -> "Short"
polarblau
  • 17,649
  • 7
  • 63
  • 84
0

HTML with JavaScript:

<p id="myid">My long long looooong text cut cut cut cut cut</p>

<script type="text/javascript">
var myid=document.getElementById('myid');
myid.innerHTML=myid.innerHTML.substring(0,10)+'...';
</script>

The result will be:

My long lo...

Cheers

G.

Greg
  • 1,401
  • 11
  • 11
0

If you want to cut a string for a specifited length and add dots use

// Length to cut
var lengthToCut = 20;

// Sample text
var text = "The quick brown fox jumps over the lazy dog";

// We are getting 50 letters (0-50) from sample text
var cutted = text.substr(0, lengthToCut );
document.write(cutted+"...");

Or if you want to cut not by length but with words count use:

// Number of words to cut
var wordsToCut = 3;

// Sample text
var text = "The quick brown fox jumps over the lazy dog";

// We are splitting sample text in array of words
var wordsArray = text.split(" ");

// This will keep our generated text
var cutted = "";
for(i = 0; i < wordsToCut; i++)
 cutted += wordsArray[i] + " "; // Add to cutted word with space

document.write(cutted+"...");

Good luck...

Robik
  • 6,047
  • 4
  • 31
  • 41