19

I have paragraph which has more than 500 character. I want to get only initial 100 character and hide rest of it. Also I want to insert "More" link next to 100 character. On click of more link whole paragraph should display and edit text "More" to "Less" and on click "Less" it should toggle behavior. Paragraph is dynamically generated I cant wrap content of it using .wrap(). Here is example what I have and what I want.

This is what I have :

  <p>It is a long established fact that a reader will be distracted by the readable 
   content of a page when looking at its layout. The point of using Lorem Ipsum is that
   it has a more-or-less normal distribution of letters, as opposed to using 'Content 
  content here', making it look like readable English. Many desktop publishing packages 
   and web page editors now use Lorem Ipsum as their default model text.</p>

This is what I want when DOM loads

 <p>It is a long established fact that a reader will be distracted by ..More</p>

This is what I want when user click "More"

   <p>It is a long established fact that a reader will be distracted by the readable 
   content of a page when looking at its layout. The point of using Lorem Ipsum is that
   it has a more-or-less normal distribution of letters, as opposed to using 'Content 
  content here', making it look like readable English. Many desktop publishing packages 
   and web page editors now use Lorem Ipsum as their default model text. ..Less</p>

When we click on "Less", it should revert what on click "More" has done.

I am using jQuery to split, slice and wrap substring into span which I want to hide but that doesn't work.

var title = $("p").text();
var shortText = jQuery.trim(title).substring(100, 1000).split(" ")
    .slice(0, -1).join(" ") + "...More >>";
shortText.wrap('</span>');
Raj Mehta
  • 311
  • 2
  • 3
  • 11

6 Answers6

40

Fiddle: http://jsfiddle.net/iambriansreed/bjdSF/

jQuery:

jQuery(function(){

    var minimized_elements = $('p.minimize');
    var minimize_character_count = 100;    

    minimized_elements.each(function(){    
        var t = $(this).text();        
        if(t.length < minimize_character_count ) return;

        $(this).html(
            t.slice(0,minimize_character_count )+'<span>... </span><a href="#" class="more">More</a>'+
            '<span style="display:none;">'+ t.slice(minimize_character_count ,t.length)+' <a href="#" class="less">Less</a></span>'
        );

    }); 

    $('a.more', minimized_elements).click(function(event){
        event.preventDefault();
        $(this).hide().prev().hide();
        $(this).next().show();        
    });

    $('a.less', minimized_elements).click(function(event){
        event.preventDefault();
        $(this).parent().hide().prev().show().prev().show();    
    });

});​
iambriansreed
  • 21,935
  • 6
  • 63
  • 79
  • No problem, @RajMehta. Just make sure the content in the minimized elements has no HTML. – iambriansreed Jul 10 '12 at 16:50
  • This needs options to: (1) truncate on words, (2) not strip line/paragraph breaks. – Abela Oct 30 '13 at 00:24
  • @Yokhannan - Here's how you can change the function to truncate only on **line breaks**: See my resolution bellow (not enough place in comment...) – Noam Manos Nov 11 '13 at 11:38
  • This works fine for me. But is it possible to have html elements like links, strong inside the p.minimize element? – Hans Ullrich Feb 03 '15 at 10:49
  • @Abela If you replace (this).text with (this).html it will preserve your line breaks. – Jim Factor Oct 05 '16 at 00:36
  • @iambriansreed what if we need to close hide previous paragraph on next show button ? like we use data-parent attribute in bootstrap on accordions. on click second accordion close previous one. i need to implement that result in above senario can you please help? – Awais May 17 '22 at 07:42
4

It's not a top google result, but I've used the jQuery Expander plugin to great success. It's nice because it doesn't hide anything from search engine robots.

John Magnolia
  • 16,769
  • 36
  • 159
  • 270
Zach M.
  • 129
  • 1
  • 2
3

Thanks to @iambriansreed for his nice function, here's a slight modification to truncate paragraph on line breakes:

<script src="http://code.jquery.com/jquery-latest.min.js" type="text/javascript"></script>
<script>
jQuery(function(){

var minimized_elements = $('p.minimize');
var maxLines = 20;

minimized_elements.each(function(){    
    // var textArr = $(this).text().split(/\n/); // Not supported in IE < 9
    var textArr = $(this).html().replace(/\n?<br>/gi,"<br>").split(/<br>/);
    var countLines = textArr.length;

    if (countLines > maxLines) {
        text_less = textArr.slice(0, maxLines).join("<br>");
        text_more = textArr.slice(maxLines, countLines).join("<br>");
    }
    else return;

    $(this).html(
        text_less + '<span>... </span><a href="#" class="more">More</a>'+
        '<span style="display:none;">'+ text_more +' <a href="#" class="less">Less</a></span>'
    );
}); 

$('a.more', minimized_elements).click(function(event){
    event.preventDefault();
    $(this).hide().prev().hide();
    $(this).next().show();        
});

$('a.less', minimized_elements).click(function(event){
    event.preventDefault();
    $(this).parent().hide().prev().show().prev().show();    
});

});

</script>
Noam Manos
  • 15,216
  • 3
  • 86
  • 85
2

Have you looked at the jQuery Truncator plugin?

It pretty much does exactly what you've described.

Zentaurus
  • 758
  • 2
  • 11
  • 27
Brandon
  • 68,708
  • 30
  • 194
  • 223
  • I can't use plugin. I want it without any plugin. – Raj Mehta Jul 10 '12 at 16:21
  • @RajMehta, Then you need to show code so that we can see what you're doing and what you're having problems with. The other alternative, since the plugin is MIT licensed and does what you need is to look at their source code to see how they do it. – Brandon Jul 10 '12 at 16:22
  • I have added code above. take a look and let me know if you get any hint. – Raj Mehta Jul 10 '12 at 16:31
2

It looks like a couple other people beat me to it, but here is what I came up with.

var MORE = "... More...",
    LESS = " Less...";

$(function(){
    $("p").each(function(){
        var $ths = $(this),
            txt = $ths.text();

        //Clear the text
        $ths.text("");

        //First 100 chars
        $ths.append($("<span>").text(txt.substr(0,100)));

        //The rest
        $ths.append($("<span>").text(txt.substr(100, txt.length)).hide());

        //More link
        $ths.append(
            $("<a>").text(MORE).click(function(){
                var $ths = $(this);

                if($ths.text() == MORE){
                    $ths.prev().show();
                    $ths.text(LESS);
                }
                else{
                    $ths.prev().hide();
                    $ths.text(MORE);
                }
            })
        );
    });
});
illTyped
  • 41
  • 1
0

for everyone who has come here searching for show more... Here is another plug-in http://viralpatel.net/blogs/dynamically-shortened-text-show-more-link-jquery/

Kundan Singh
  • 83
  • 10