display a string in react

Viewed 965

I have a string as shown below which I want to truncate it after a particular character limit and display an ellipsis.

"This is a long string"

On truncation, I want the string to display something like this:

This is a long (...)

or

This is a (...)

or

This is (...)

The above examples don't cut the words. What I don't want is:

This is a lon (...)

or

This is a long s (...)

The above examples don't work.

I am using the following function in react to truncate a string. The problem with the function is that it sometimes cut the words. The value of length I am using is 175. For 175 character limit, sometimes it cut the words and sometimes it doesn't.

export const wordsTruncate = (words, length) => {
    const j = words.split('');
    let result = j.filter((z, a) => a <= (length - 1));

    return result.join("");
}

I am wondering what changes I need to make in the function above so that it doesn't cut the words as shown in the examples above.

7 Answers

You might use a dynamic pattern, where you can specify a minimum number of chars at the start of the string for which you want the ellipsis to work, and the length of the number of characters.

^(?!\s)(.{3,10}\S)(?!\S).*

Regex demo

  • ^ Start ofs tring
  • (?!\s) Assert not a whitespace char at the start
  • (.{3,10}\S) Capture group 1 (Denoted by m[1] in the example code), match 3 - 10 times any char followed by matching a non whitespace char at the end
  • (?!\S) Negative lookahead, assert a whitespace boundary to the right
  • .* Match the rest of the line

const wordsTruncate = (s, minNrOfChars, length) => {
  if (minNrOfChars > length || minNrOfChars < 1 || length < 1) return s;
  minNrOfChars--;
  length--;
  const regex = new RegExp(`^(?!\\s)(.{${minNrOfChars},${length}\}\\S)(?!\\S).*`);
  const m = s.match(regex);
  return m ? `${m[1]} (...)` : s;
}

const strings = [
  "This is a long string",
  "a b c d e f g h",
  "a b c d e       ",
  "a b",
  "this isatest",
  "thisisatesttesttest",
  "A bcdefghifkkle",
  "a",
  "ab",
  "abc",
  "abcd",
  "abcde"
];

strings.forEach(s => {
  console.log(`"${s}" --> ${wordsTruncate(s, 3, 10)}`);
});

Try this. hope this works for you.

const wordsTruncate = (words, length) => {
  words = words.trim(); //you need to decied wheather you do this or not
  length -= 6; // because ' (...)'.length === 6
  if (length >= words.length) return words;

  let oldResult = /\s/.test(words.charAt(length));
  for (let i = length - 1; i > -1; i--) {
    const currentRusult = /\s/.test(words.charAt(i))

    //check if oldresult is white space and current is not.
    //which means current character is end of word
    if (oldResult && !currentRusult) {
      return `${words.substr(0, i + 1)} (...)`;
    }
    oldResult = currentRusult;
  }
  // you need to decide whether you will just return truncated or original
  // in case you want original just return word
  return '(...)';
}

console.log(wordsTruncate('This is long text blabla blasdf test.', 32));
console.log(wordsTruncate('This is', 22));
console.log(wordsTruncate('This is', 7));
console.log(wordsTruncate('This is', 13));
console.log(wordsTruncate('This is ', 13));
console.log(wordsTruncate('Thisadsfasdfasdfasdfasdf', 22));

So length should be final length of truncated string.

eg: 'This is long text blabla (...)'.length

if you are using lodash in your react project, which most of us do, use it's truncate method like so

import truncate from 'lodash/truncate'

// ...

truncate('This is a long string', {
  'length': 20,
  'separator': ' ',
  'omission': ' ...',
})

// result: 'This is a long ...'

Try something like this:

export const wordsTruncate = (str, length) => {
  const words = str.split(' ');
  const result = words.reduce((acc, it) => {
    const parcial = acc + ' ' + it;
    return parcial.length >= length ? acc : parcial;
  }, '');

  return result + ' (...)';
};

Hope this works for you

const truncateWord = (string, length) => {
  if (string.length < length) {
    return `${string} (...)`;
  }
  return `${string.substring(0, string.substring(0, length).lastIndexOf(" "))} (...)`;
};

console.log(truncateWord("The quick brown fox jumps over the lazy dog", 10));


Result

The quick ...

[The value of length I am using is 175. For 175 character limit, sometimes it cut the words and sometimes it doesn't.]

You should check whether the 176th character is a space (" ") or not.

I hope this works for you.

function truncateWords(string, maxLen) {
    if (maxLen >= string.length) return string;
    if (string[maxLen - 6] == ' ') {
        return string.slice(0, maxLen - 5).split(' ').join(' ') + ' (...)';
    }
    return string.slice(0, maxLen - 5).split(' ').slice(0, -1).join(' ') + ' (...)';
}
const strings = [
  "abcdefghijklmno",
  "This is a long string",
  "a b c d e f g h",
  "a b c d e f g h i",
  "a b c d e       ",
  "a b",
  "this isatest",
  "thisisatesttesttest",
  "A bcdefghifkkle",
  "a",
  "ab",
  "abc",
  "abcd",
  "abcde"
];
strings.forEach(function(string) {
  console.log(truncateWords(string, 15));
});

/* result
abcdefghijklmno
This is a  (...)
a b c d e f g h
a b c d e  (...)
a b c d e  (...)
a b
this isatest
 (...)
A bcdefghifkkle
a
ab
abc
abcd
abcde
*/

Related