Biff MaGriff
Biff MaGriff

Reputation: 8231

How do I smartly truncate an HTML string in javascript?

I have a content that a user enters in that can be any sort of text.

eg

This is some sample text. I can use special characters like <>&<>&<>&<>&<>&<>&<>&<>&<>&<>&

I then display this content in a grid where the text is truncated to 80 characters (to fit in the available space) and if the user mouse overs the text they can see the full string.

I have a function that I call to do this for me.

function GetDescriptionContent(data, type, row){            
    return 
        "<span title='" + data.replace(/'/g, '&#39;') + "'>" + 
            $('<div/>').text(data).html().substring(0, 80) + 
        "</span>";
}

However when I'm substringing html I sometimes cut up the special chars like &amp; &lt; &gt;
Also when there is a special char in the string it will cut the string off prematurely that may otherwise be OK in length.

How can I smartly truncate my HTML string in javascript?

Upvotes: 0

Views: 2529

Answers (1)

Biff MaGriff
Biff MaGriff

Reputation: 8231

I found that I can keep track of the html entities and adjust the truncation length.

function truncateToLength(
    stringToTruncate, 
    truncationLength, 
    truncationCharacter = "&hellip;")
{
    //string is too small, does not need to be truncated
    if(stringToTruncate.length <= truncationLength){
        return stringToTruncate;
    }

    //find all html entities
    var splitOnAmpersandArray = stringToTruncate.split('&');

    //first instance of html entity is beyond our truncation length
    //return what we have plus truncation character
    if(splitOnAmpersandArray[0].length > truncationLength){
        return splitOnAmpersandArray[0].substring(0, truncationLength) 
            + truncationCharacter;
    }

    //first instance of html entity is inside our truncation length
    var truncatedString = splitOnAmpersandArray[0];

    //keep adding onto truncated string until:
    // it is longer than our length or 
    // we are out of characters to add on.
    for(var i = 1; i < splitOnAmpersandArray.length; i++){
        //find end of current html entity
        var htmlEntityLength = splitOnAmpersandArray[i].indexOf(';');

        //increase truncation length to account for size of current html entity
        truncationLength += htmlEntityLength + 1;

        //add up until next html entity
        truncatedString = truncatedString + '&' + splitOnAmpersandArray[i];

        //if our new length is too long, truncate and add truncation character
        if(truncatedString.length >= truncationLength){
            return truncatedString.substring(0,truncationLength) 
                + truncationCharacter;
        }
    }

    //we ran out of characters to add onto string, return result
    return truncatedString;
}

  var content = "&nbsp;&amp;&gt;&lt;&quot;&apos;&cent;&pound;&yen;&euro;&copy;&reg;";
  $('#sample').html(truncateToLength(content, 5));
  $('#sample').prop('title', $('<div/>').html(content).text());




    function truncateToLength(
        stringToTruncate, 
        truncationLength, 
        truncationCharacter = "&hellip;")
    {
        //string is too small, does not need to be truncated
        if(stringToTruncate.length <= truncationLength){
            return stringToTruncate;
        }
        
        //find all html entities
        var splitOnAmpersandArray = stringToTruncate.split('&');

        //first instance of html entity is beyond our truncation length
        //return what we have plus truncation character
        if(splitOnAmpersandArray[0].length > truncationLength){
            return splitOnAmpersandArray[0].substring(0, truncationLength) 
                + truncationCharacter;
        }

        //first instance of html entity is inside our truncation length
        var truncatedString = splitOnAmpersandArray[0];
        
        //keep adding onto truncated string until:
        // it is longer than our length or 
        // we are out of characters to add on.
        for(var i = 1; i < splitOnAmpersandArray.length; i++){
            //find end of current html entity
            var htmlEntityLength = splitOnAmpersandArray[i].indexOf(';');

            //increase truncation length to account for size of current html entity
            truncationLength += htmlEntityLength + 1;

            //add up until next html entity
            truncatedString = truncatedString + '&' + splitOnAmpersandArray[i];

            //if our new length is too long, truncate and add truncation character
            if(truncatedString.length >= truncationLength){
                return truncatedString.substring(0,truncationLength) 
                    + truncationCharacter;
            }
        }

        //we ran out of characters to add onto string, return result
        return truncatedString;
    }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="sample"></div>

Upvotes: 4

Related Questions