sprugman
sprugman

Reputation: 19831

truncate a string in the middle with javascript

anyone have a handy method to truncate a string in the middle? Something like:

truncate ('abcdefghi', 8);

would result in

'abc...hi'

UPDATE:

to be a bit more complete

Upvotes: 21

Views: 19190

Answers (9)

Abdennour TOUMI
Abdennour TOUMI

Reputation: 93203

function truncateString(str, maxLength) {
  if (str.length <= maxLength) {
    return str;
  }

  var ellipsis = '...';
  var truncatedLength = maxLength - ellipsis.length;

  var leftLength = Math.ceil(truncatedLength / 2);
  var rightLength = Math.floor(truncatedLength / 2);

  var leftSubstring = str.substring(0, leftLength);
  var rightSubstring = str.substring(str.length - rightLength);

  return leftSubstring + ellipsis + rightSubstring;
}

EXPLAINED:

The truncateString function takes two parameters: str, which is the original string to be truncated, and maxLength, which is the maximum length of the truncated string (including the ellipsis). If the length of the original string is less than or equal to the maxLength, the function simply returns the original string.

If the length of the original string is greater than the maxLength, the function calculates the lengths of the left and right substrings to be included in the truncated string. The lengths are calculated to be roughly equal, with the left substring potentially having one extra character if the truncatedLength is an odd number.

The function then uses the substring method to extract the appropriate substrings from the original string, and concatenates them with the ellipsis in the middle.

Finally, the truncated string is returned.

Upvotes: 1

Thunder Cat King
Thunder Cat King

Reputation: 662

I personally found this approach to be nice and easy to use.

    export function truncate(str: string, maxLength: number, location = 'middle') {
      if (str.length <= maxLength) {
        return str;
      }
    
      let partLength = Math.ceil((maxLength - 3) / 2);
      let startStr, endStr;
    
      switch (location) {
        case 'start':
          endStr = str.substring(str.length - maxLength + 3);
          return '...' + endStr;
        case 'end':
          startStr = str.substring(0, maxLength - 3);
          return startStr + '...';
        case 'middle':
        default:
          startStr = str.substring(0, partLength);
          endStr = str.substring(str.length - partLength);
          return startStr + '...' + endStr;
      }
    }
console.log(truncate('abcdefghi', 8, 'start')); // Output: '...defghi'
console.log(truncate('abcdefghi', 8, 'end')); // Output: 'abcdef...'
console.log(truncate('abcdefghi', 8)); // Output: 'abc...hi'

Upvotes: 1

prakhar tomar
prakhar tomar

Reputation: 1125

Here is how I did it:

function truncate(
  fullStr,
  strLen = 8,
  separator = "...",
  frontChars = 3,
  backChars = 4
) {
  if (fullStr.length <= strLen) return fullStr;

  return (
    fullStr.substr(0, frontChars) +
    separator +
    fullStr.substr(fullStr.length - backChars)
  );
}

Upvotes: 2

Christophe Chevalier
Christophe Chevalier

Reputation: 180

By relying on the @mvChr solution, I propose to use a @pipe with Typescript.
First, You need to create a @pipe helper where you will described the function of truncate.

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'truncateString',
})
export class TreeHelperPipe implements PipeTransform {
  transform(fullStr: string, strLen: number, separator: string): any {
    if (fullStr.length < strLen) {
      return fullStr;
    }

    separator = separator || '...';

    const sepLen = separator.length,
      charsToShow = strLen - sepLen,
      frontChars = Math.ceil(charsToShow / 2),
      backChars = Math.floor(charsToShow / 2);

    return (
      fullStr.substr(0, frontChars) +
      separator +
      fullStr.substr(fullStr.length - backChars)
    );
  }
}

After that, you will be able to use your @pipe helper on your template like that :

<span
  class="item-name"
  [text]="item.name | truncateString: 60"
  [title]="item.name"
></span>

I only apply the @pipe to the text and not the title attribute (which displays the text in a flyover window).

Upvotes: 0

Steve Walker
Steve Walker

Reputation: 3

If you are playing in PHP you can call this, works fine and could be adjusted to JS well I assume.

function middle_dots($crumb, $max=30){
  if(strlen($crumb) > $max)
  $crumb = substr_replace($crumb, '...', $max/2, round(-$max/2));
  return $crumb;
}

echo middle_dots('Some long text here would if longer than 30 chars get some ...');

Enjoy

Steve

Upvotes: -5

meleyal
meleyal

Reputation: 33300

CoffeeScript version based on mVChr's answer:

truncate = (str, length, separator = '...') ->
  return '' if str is null
  return str if str.length <= length

  pad = Math.round (length - separator.length) / 2
  start = str.substr(0, pad)
  end = str.substr(str.length - pad)

  [start, separator, end].join('')

Upvotes: -1

Dustin Laine
Dustin Laine

Reputation: 38503

Something like this...

function truncate(text, startChars, endChars, maxLength) {
    if (text.length > maxLength) {
        var start = text.substring(0, startChars);
        var end = text.substring(text.length - endChars, text.length);
        while ((start.length + end.length) < maxLength)
        {
            start = start + '.';
        }
        return start + end;
    }
    return text;
}
alert(truncate('abcdefghi',2,2,8));

Or to limit to true ellipsis:

function truncate(text, startChars, endChars, maxLength) {
    if (text.length > maxLength) {
        var start = text.substring(0, startChars);
        var end = text.substring(text.length - endChars, text.length);
        return start + '...' + end;
    }
    return text;
}
alert(truncate('abcdefghi',2,2,8));

jsFiddle

Upvotes: 1

Chris W.
Chris W.

Reputation: 39219

This may be a bit 'heavy' for what you're looking for but there's a jQuery plugin that does this sort of thing.

The "Three Dots" plugin

Upvotes: 0

mVChr
mVChr

Reputation: 50185

Here's one way to do it chopping up the string with substr:

var truncate = function (fullStr, strLen, separator) {
    if (fullStr.length <= strLen) return fullStr;

    separator = separator || '...';

    var sepLen = separator.length,
        charsToShow = strLen - sepLen,
        frontChars = Math.ceil(charsToShow/2),
        backChars = Math.floor(charsToShow/2);

    return fullStr.substr(0, frontChars) + 
           separator + 
           fullStr.substr(fullStr.length - backChars);
};

See example →

Upvotes: 40

Related Questions