Show/Hide with Ellipsis

Hi all,

I have a show/hide script running on a site and it is working perfectly. The problem I am having is I need to add ellipsis after a certain amount of characters, lets say 100. The content that is being displayed is being pulled from a database so I was thinking the best way to go about it would be to add a span tag after a certain amount of characters and add the ellipsis that way.

Is there any way I can add a span tag after a certain amount of characters?

Cheers.

Hi Allan,

You sure can:

<p class="truncated">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<a href="#">Show</a>

<p class="truncated">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<a href="#">Show</a>
var charLimit = 50;

function truncate(el) {
    var text = el.text();
    el.attr("data-originalText", text);
    el.text(text.substring(0, charLimit) + "...");
}

function reveal(el) {
    el.text(el.attr("data-originalText"));
}

$(".truncated").each(function () {
    truncate($(this));
});

$("a").on("click", function (e) {
    e.preventDefault();
    if ($(this).text() === "Show") {
        $(this).text("Hide");
        reveal($(this).prev(".truncated"));
    } else {
        $(this).text("Show");
        truncate($(this).prev(".truncated"));
    }
});

Demo

Great Pullo, thanks very for that!

Hi Pullo,

I am working with this code currently

var slideHeight = 52;
$(".events-left-col").each(function() {
    var $this = $(this);
    var $wrap = $this.children(".wrap");
    var defHeight = $wrap.height();
    if (defHeight >= slideHeight) {
        var $readMore = $this.find(".read-more");
        $wrap.css("height", slideHeight + "px");
        $readMore.append("<a href='#' class='more'>Read More</a>");
        $readMore.children("a").bind("click", function(event) {
            var curHeight = $wrap.height();
            if (curHeight == slideHeight) {
                $wrap.animate({
                    height: defHeight
                }, "normal");
				$(this).removeClass('more');
                $(this).addClass('less');
				$(this).text("Read Less");
            } else {
                $wrap.animate({
                    height: slideHeight
                }, "normal");
                $(this).removeClass('less');
                $(this).addClass('more');
				$(this).text("Read More");
            }
            return false;
        });
    }
});

Would it be hard to integrate the method you used above for the character limit and ellipsis to what I have here.

Cheers,
Al.

Hi Allan,

Sure. Should be possible.
Could you post the HTML that that code is operating on.

Hi sorry Pullo, I had just thought you might need the HTML too.


<div class="container">
	<div class="events-left-col">
   		<h2>Heading 2</h2>
                <div class="wrap">
        	       <div>
            	       <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.</p>
                       </div>
                 </div><!-- /.wrap -->
                 <div class="read-more"></div>
        </div><!-- /.events-left-col -->
</div><!-- /.container -->

Hi Allan,

I’ve updated the code to use your HTML :slight_smile:

var charLimit = 50;

function truncate(el) {
    var text = el.text();
    el.attr("data-originalText", text);
    el.text(text.substring(0, charLimit) + "...");
}

function reveal(el) {
    el.text(el.attr("data-originalText"));
}

$(".truncated").each(function () {
    truncate($(this));
});

$("a").on("click", function (e) {
    e.preventDefault();
    if ($(this).text() === "Show") {
        $(this).text("Hide");
        reveal($(this).prev().find(".truncated"));
    } else {
        $(this).text("Show");
        truncate($(this).prev().find(".truncated"));
    }
});

new fiddle

Hi Pullo,

I can’t seem to get the code you have above to work with the code I originally had. I like the sliding animation which is why I want to keep my original code.

I can get the text in the first paragraph to truncate but can not get it to display when the Read More link is clicked.

I’m not great with jQuery so go easy on me.

Here’s a link to what I have at the moment - jsfiddle

Hi,

So, you’ve got a bunch of HTML and obviously that can’t change, as that is how your page is laid out:

<div class="container">
    <div class="events-left-col">
        <h2 class="eventTitle">Event Title</h2>
        <div class="wrap">
            <div>
                <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. 
                Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum 
                iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto 
                odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.</p>

                <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. 
                Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum 
                iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto 
                odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.</p>
            </div>
        </div>
        <div class="read-more"></div>
    </div>
</div>

However, I need to understand what it is you are trying to do after that.

Do you want to show the first 122 characters of the first paragraph inside <div class=“wrap”>, then toggle the rest of that paragraph and the following paragraph?
Is there any reason you are doing this:

$readMore.append("<a href='#' class='more'>Read More</a>");

and not hard-coding the link into the page?

Anyways, here’s what I came up with:

var charLimit = 122;

function truncate(el) {
  var clone = el.find(":first-child"),
      originalContent = el.html(),
      text = clone.text();
  el.attr("data-originalContent", originalContent);
  
  clone.text(text.substring(0, charLimit) + "...")
  el.empty().append(clone);
}

function reveal(el) {
  el.html(el.attr("data-originalContent"));
}

$("a").on("click", function (e) {
  e.preventDefault();
  var truncateElement = $(this).parent().prev().find(".truncate");
  if ($(this).text() === "Read More") {
      $(this).text("Read Less");
      reveal(truncateElement);
  } else {
      $(this).text("Read More");
      truncate(truncateElement);
  }
});

$(".truncate").each(function () {
    truncate($(this));
});

Does this work for you?

Updated fiddle

Hi Pullo,

Thanks for the reply.

The original code I had I found online and it worked quite well, I just needed to add the ellipsis after a certain amount of characters and then display the remaining text when the Read More link was clicked.

I have no preference about adding the Read More link through jQuery or hardcoding it, the main thing I want to keep from the original code is the animation when the Read More link is clicked, I also need the class to change when it is clicked so I can change styling.

The code you pasted above is working great, although I am experiencing a slight problem. The page I am working on has about 25 posts and on only 2 posts is the first paragraph repeated… I can send you a link to the page I am working on if you like (image attached of what it currently looks like - highlighted in red). I have added a list of about 8 posts to this fiddle to see if any are repeated but none are - fiddle.

The jQuery in that fiddle is what I am using at the moment, just added classes to the Read More/Less links and added p to :first-child, didn’t seem to work without that.

Yeah, that would be good, along with instructions on how to reproduce the error.

Sent you a message Pullo.

I just had a try at editing the fiddle and was able to duplicate the problem.

It seems if there is a div within the div.truncate it duplicates the first paragraph - fiddle - look at the last container div.

Hi,

for some reason, this line:

var clone = el.find(":first-child),

was returning both <p> tags when an empty <div> element was present, as in your example.

I changed it to this:

var clone = el.children().first(),

and it worked as expected.

Updated fiddle

Does that help?

That’s prefect Pullo, working great!

There is just one more thing I hope you can help with, which is the animation, instead of an instant reveal of the hidden text, how can I add an animation to the link.

I tried with .animate() but can’t get it working properly.

Cheers,
Al.

It’s not very elegant, but if the jump doesn’t bother you, you can do it like this:

function truncate(el) {
  var clone = el.children().first(),
      originalContent = el.html(),
      text = clone.text();
  el.attr("data-originalContent", originalContent);
  clone.text(text.substring(0, charLimit) + "...")
  el.slideUp(function(){
      $(this).empty().append(clone).show();
  });
}

function reveal(el) {
  el.hide();
  el.html(el.attr("data-originalContent"));
  el.slideDown();
}

New fiddle

Thanks for that Pullo!