Dynamically shortened Text with “Show More” link using jQuery

Update: The plugin is now on GitHub: https://github.com/viralpatel/jquery.shorten

Facebook user updates has a great functionality. If the comment text is larger than few characters, the extra words are hide and a show more link is presented to user. This way you can keep long text out of the view to user and stop the cluttering of page. Also interested users can click on more link and see the full content.

Here is a simple tutorial to achieve this using jQuery / Javascript.

The HTML

Below is the sample text. Each text is wrapped in a DIV tag. Note that we have added a class “more” in each div. This class will decide if a text needs to be shortened and show more link showed or not.

<div class="comment more">
	Lorem ipsum dolor sit amet, consectetur adipiscing elit.
	Vestibulum laoreet, nunc eget laoreet sagittis,
	quam ligula sodales orci, congue imperdiet eros tortor ac lectus.
	Duis eget nisl orci. Aliquam mattis purus non mauris
	blandit id luctus felis convallis.
	Integer varius egestas vestibulum.
	Nullam a dolor arcu, ac tempor elit. Donec.
</div>
<div class="comment more">
	Duis nisl nibh, egestas at fermentum at, viverra et purus.
	Maecenas lobortis odio id sapien facilisis elementum.
	Curabitur et magna justo, et gravida augue.
	Sed tristique pellentesque arcu quis tempor.
</div>
<div class="comment more">
	consectetur adipiscing elit. Proin blandit nunc sed sem dictum id feugiat quam blandit.
	Donec nec sem sed arcu interdum commodo ac ac diam. Donec consequat semper rutrum.
	Vestibulum et mauris elit. Vestibulum mauris lacus, ultricies.
</div>

The CSS

Below is the CSS code for our example. Note the class “.morecontent span” is hidden. The extra text from the content is wrapped in this span and is hidden at time of page loading.

a {
	color: #0254EB
}
a:visited {
	color: #0254EB
}
a.morelink {
	text-decoration:none;
	outline: none;
}
.morecontent span {
	display: none;
}
.comment {
	width: 400px;
	background-color: #f0f0f0;
	margin: 10px;
}

The Javascript

Below is the Javascript code which iterate through each DIV tags with class “more” and split the text in two. First half is showed to user and second is made hidden with a link “more..”.

You can change the behaviour by changing following js variables.

  • showChar: Total characters to show to user. If the content is more then showChar, it will be split into two halves and first one will be showed to user.
  • ellipsestext: The text displayed before “more” link. Default is “…”
  • moretext: The text shown in more link. Default is “more”. You can change to “>>”
  • lesstext: The text shown in less link. Default is “less”. You can change to “<<"
$(document).ready(function() {
	var showChar = 100;
	var ellipsestext = "...";
	var moretext = "more";
	var lesstext = "less";
	$('.more').each(function() {
		var content = $(this).html();

		if(content.length > showChar) {

			var c = content.substr(0, showChar);
			var h = content.substr(showChar-1, content.length - showChar);

			var html = c + '<span class="moreellipses">' + ellipsestext+ '&nbsp;</span><span class="morecontent"><span>' + h + '</span>&nbsp;&nbsp;<a href="" class="morelink">' + moretext + '</a></span>';

			$(this).html(html);
		}

	});

	$(".morelink").click(function(){
		if($(this).hasClass("less")) {
			$(this).removeClass("less");
			$(this).html(moretext);
		} else {
			$(this).addClass("less");
			$(this).html(lesstext);
		}
		$(this).parent().prev().toggle();
		$(this).prev().toggle();
		return false;
	});
});

Online Demo

Click here to view demo

Update

The above code is modified into jQuery plugin. Also it has now been enhanced. HTML tags are now parsed properly within text to preserve its uniformity while shorting the text. Please check latest plugin code on GitHub. https://github.com/viralpatel/jquery.shorten

Download Source Code

Click here to download (ZIP, 2KB)

jQuery Plugin

Code

/*
 * jQuery Shorten plugin 1.0.0
 *
 * Copyright (c) 2013 Viral Patel
 * http://viralpatel.net
 *
 * Dual licensed under the MIT license:
 *   http://www.opensource.org/licenses/mit-license.php
 */

 (function($) {
	$.fn.shorten = function (settings) {
	
		var config = {
			showChars: 100,
			ellipsesText: "...",
			moreText: "more",
			lessText: "less"
		};

		if (settings) {
			$.extend(config, settings);
		}
		
		$(document).off("click", '.morelink');
		
		$(document).on({click: function () {

				var $this = $(this);
				if ($this.hasClass('less')) {
					$this.removeClass('less');
					$this.html(config.moreText);
				} else {
					$this.addClass('less');
					$this.html(config.lessText);
				}
				$this.parent().prev().toggle();
				$this.prev().toggle();
				return false;
			}
		}, '.morelink');

		return this.each(function () {
			var $this = $(this);
			if($this.hasClass("shortened")) return;
			
			$this.addClass("shortened");
			var content = $this.html();
			if (content.length > config.showChars) {
				var c = content.substr(0, config.showChars);
				var h = content.substr(config.showChars, content.length - config.showChars);
				var html = c + '<span class="moreellipses">' + config.ellipsesText + ' </span><span class="morecontent"><span>' + h + '</span> <a href="#" class="morelink">' + config.moreText + '</a></span>';
				$this.html(html);
				$(".morecontent span").hide();
			}
		});
		
	};

 })(jQuery);

Download

Click to download jQuery Shorten plugin

Usage

Step 1: Include the jQuery plugin in your HTML

<script type="text/javascript"
	src="http://viralpatel.net/blogs/demo/jquery/jquery.shorten.1.0.js"></script>

Step 2: Add the code to shorten any DIV content. In below example we are shortening DIV with class “comment”.

<div class="comment">
	This is a long comment text. 
	This is a long comment text. 
	This is a long comment text. 
	This is a long comment text. This is a long comment text.
</div>
<script type="text/javascript">
	$(document).ready(function() {
	
		$(".comment").shorten();
	
	});
</script>

You may want to pass the parameters to shorten() method and override the default ones.

$(".comment").shorten({
	"showChars" : 200
});


$(".comment").shorten({
	"showChars" : 150,
	"moreText"	: "See More",
});

$(".comment").shorten({
	"showChars" : 50,
	"moreText"	: "See More",
	"lessText"	: "Less",
});
Get our Articles via Email. Enter your email address.

You may also like...

121 Comments

  1. Vijay Bharwani says:

    Hi,

    Nice tutorial. There is a problem in your script, that when you are splitting the full content in 2, when we clicking on more, the last letter of the first sub string is getting double.
    I mean before clicking on more, if ‘i’ is the last character , then if we click on more, it is showing 2 ‘i’. Please the 2 sub strings that u have made.
    The suggested behavior is

     var c = content.substr(0, showChar); 
                var h = content.substr(showChar, content.length - showChar); 

    insted of

     var c = content.substr(0, showChar); 
                var h = content.substr(showChar-1, content.length - showChar); 
  2. pradeep says:

    Hi, Nice code but not working in internet explorer version 9

  3. Vali Hutchison says:

    Similar problem for me as reported by others. If I have text in the shortener DIV with paragraph tags then it doesn’t work. It shows the less link with all the text first and then when you click the less link all the text disappears. Removing the tags makes it work – but be good to fix so can have paragraph tags.

  4. Luke says:

    Regarding your latest GitHub plugin, please don’t use off() and on() methods as these don’t work with the HTML5

    <article>

    tags ?

    • Luke says:

      Apologies, the plugin works fine with jQuery 1.8.3, but not v1.3 ;)

  5. Jen says:

    Hi,
    I’m getting some weird behavior with the jquery-1.9.1.min.js. The button appears and then is labeled display:none. Anyone else seen this?

    thanks
    Jen

    • Asd says:

      Yes I am facing the same issue. weird behaviour

  6. Ritu says:

    Hi

    The code is working but I have a problem that it is not working for label declared inside form view. Can any body help me?

    Thanks

  7. Sathish says:

    What if I have some html inside the div. If I have some tags, is it going to cut off. (lets say my 99th character is so as per your example is this going to cut off <i … more?)

  8. shaz says:

    Hi, nice plugin, I want to ask how to add jquery easing effect on clicking ‘more’ ‘less’ Thanx

  9. Chockolate says:

    Yes, nice plugin and good tutorial, but as soon as there’s any markup in the div, it falls apart.

    • JustAGuy says:

      I added a quick hack to only break after a closing tag.

      Something like this: (to only break after a tag)

      poffset = content.substr(config.showChars, content.length – config.showChars).indexOf(“”) + 4;
      var c = content.substr(0, config.showChars + poffset);
      var h = content.substr(config.showChars + poffset, content.length – (config.showChars + poffset));

      • JustAGuy says:

        Trying again with formatting..

        poffset = content.substr(config.showChars, content.length - config.showChars).indexOf("</p>") + 4;
        var c = content.substr(0, config.showChars + poffset);
        var h = content.substr(config.showChars + poffset, content.length - (config.showChars + poffset));
        
  10. Jacques says:

    Too bad this doesn’t work with dynamic data (text) from a database

    • pyretta says:

      Hello Jacques,
      it’s not true, that it doesn’t work with dynamic text taken from a database. If you use a serverside language like php to dynamically create content, the text you want to shorten would be created before any JS is loaded. So it would be no problem to shorten your dynamic text. But I think, if you use clientside language in a synchronous way, it won’t work, because the text you want to shorten can’t be find from the shorten script when it loads. Maybe it works with an asynchronous script, but I didn’t test it. Sorry for my possibly poor English, it’s not my native language, but I hope you can understand it anyway.

      @Viral Patel: Many, many, many thanks for this great script & tutorial!! It is awesome!

  11. heidi says:

    Very nice plugin, but could you add a speed control to this plugin?

  12. Rudy says:

    For me, this plugin only works in IE, not in Mozilla firefox or Chrome
    my jquery version is V1.7.1

    added var J = noconflict()

    any suggestions?

  13. bibil says:

    Hello, Thx for the tutorial!!
    Is it possible to add some animation to the text ? i struggled but couldnt find how…

    Many thx!!

    • Kelvin says:

      Yes. Search for hide() and show() and add “slow” in the brackets. e.g. hide(“slow”)…

  14. How i can shrink entire previous div if i am clicking on more link of
    next div or any div i.e div that is not selected for now should get
    shirked ..
    Thanks in advance

  15. Shawn says:

    I was looking for it since long time as i want to show not full content, since my page has long content. Thanks for sharing this useful resource with us.

  16. Hoffman says:

    Hi,
    I wanted to use the plugin on a wordpress website but it turn out the plugin is not working can you please help me on how i can integrate in to work with wordpress.
    Best regards

  17. Anitha Krishana says:

    I have been trying to develop this as part of my php jquery training assignment with no success. but this tutorial helped me to get the assignment in few minutes. Just to note, i am new to php and jquery. thank you so much for detailed explanation.

    -Anitha

  18. Neil says:

    nice plugin !!!
    but how to change more and less text into image..
    thankx in advance…….

  19. fyeth says:

    Hi there, thanks for a nice plugin. Its working but don’t know how to align “more” to the same line as the elipses like your samples. Mine looks like this.

    some text…
    more

    What I want is

    some text … more

    • SyberKnight says:

      agreed!
      this code is awesome, but i’d really like to figure out a way to have the break occur between words rather than only have one or two characters of the next word show before the ellipse.

      i found this on his/your github site that showed promise…
      https://github.com/lucian-lcr/jquery.shorten/commit/ff76f02ce75bcc122084c0db0745e5319f4b12f4?diff=unified
      …but unfortunately, it does not provide an appropriate fix (for us).

      i’m not very knowledgeable in javascript but will try to play with it & see what i can do. BUT would totally appreciate somebody who is knowledgeable to provide a solution.

      additionally, i was hoping for some jquery animation too, and found the post to change all the…
      show(); and hide();’s to show(“slow”); and hide(“slow”);
      …but when my block is at the bottom of a page, it does something funky & undesirable.

      .peace.

    • SyberKnight says:

      to the moderator… why did you delete my post?
      i replied here just trying to be helpful as well as post my questions.

  20. mohamed says:

    HI there it is possible to make us a video tutorial about Shortened Text With “Show More” Link Using JQuery and html and olso to use asp.net sory for

  21. Sandeep says:

    if there is link in the text, it’s showing the link path

  22. pyretta says:

    Hi there,
    again: Many thanks to Viral Patel for this awesome Plugin!
    If someone wants to use this plugin with more than one HTML-Element to show/hide and don’t want to click on a little button or something, here is my work around.
    The HTML structure:

     <div class="showmore">
        <div class="left_img">
            <img src="someimage.jpg" alt="someimage" title="someimage" />
        </div>
        <div class="shorten_txt">
        	<h1>Lorem ipsum dolor sit amet</h1>
            <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies.</p>
            <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies.</p>
            <ul>
                <li>Lorem ipsum dolor sit amet</li>
                <li>consectetuer adipiscing elit</li>
            </ul>
        </div>
    </div> 

    The jQuery JS:

    var showChar=50;
    	var ellipsestext="[...]";	
    	$('.showmore').each(function(){		
    		$(this).find('.shorten_txt p').addClass('more_p').hide();
    		$(this).find('.shorten_txt p:first').removeClass('more_p').show();
    		$(this).find('.shorten_txt ul').addClass('more_p').hide();
    //you can do this above with every other element
    		var teaser = $(this).find('.shorten_txt p:first').html();
    		var con_length = parseInt(teaser.length);
    		var c = teaser.substr(0, showChar);		
    		var h = teaser.substr(showChar, con_length - showChar);
    		var html = '<span class="teaser_txt">'+c+'<span class="moreelipses">'+ellipsestext+
    		'</span></span><span class="morecontent_txt">'+h
    		+'</span>';				
    		if(con_length > showChar){			
    			$(this).find(".shorten_txt p:first").html(html);
    			$(this).find(".shorten_txt p:first span.morecontent_txt").toggle();			
    		}		
    	});	
    	$(".showmore").click(function(){
    		if($(this).hasClass("less")){
    			$(this).removeClass("less");
    		}else{
    			$(this).addClass("less");
    			}
    		$(this).find('.shorten_txt p:first span.moreelipses').toggle();
    		$(this).find('.shorten_txt p:first span.morecontent_txt').toggle();
    		$(this).find('.shorten_txt .more_p').toggle();
    		return false;
    	});
     

    Now you just have to click on anywhere inside the “showmore” div and the teasertext will be shortened or will be enlarged. This is useful if you want it to use with mobile phones and touchscreens.

    best regards,
    pyretta

    • andy says:

      Pyretta, can you then style the “[…]” so it’s say bold and a colour?

      • andy says:

        Sorry, sorted.
        .moreelipses {
        font-weight:bold;
        color:#FF0000;
        }

  23. Manuel says:

    I´ve just modified your code becuase i had problems with html contents.

    Now instead of cutting and adding what function have cutted, function now cuts and shows this content at first and then when clicking “more” button it shows whole content.

    $(function(){
    $.fn.shorten = function (settings) {

    var config = {
    showChars: 100,
    ellipsesText: &quot;…&quot;,
    moreText: &quot;more&quot;,
    lessText: &quot;less&quot;
    };

    if (settings) {
    $.extend(config, settings);
    }

    $(document).on({click: function (){

    var $this = $(this);
    if ($this.hasClass(‘less’)) {
    $this.removeClass(‘less’);
    $this.html(config.moreText);
    $(‘.morecontent’).fadeOut(function(){
    $(‘.lesscontent’).fadeIn();
    $(‘.moreellipses’).show();
    });
    }else{
    $this.addClass(‘less’);
    $this.html(config.lessText);
    $(‘.lesscontent’).fadeOut(function() {
    $(‘.morecontent’).fadeIn();
    $(‘.moreellipses’).hide();
    });
    }
    }
    }, ‘.morelink’);

    return this.each(function () {
    var $this = $(this);
    if($this.hasClass(&quot;shortened&quot;)) return;

    $this.addClass(&quot;shortened&quot;);
    var content = $this.html();
    if (content.length &gt; config.showChars) {
    var c = content.substr(0, config.showChars);
    var html = ‘&lt;span class=&quot;lesscontent&quot;&gt;’+ c + ‘&lt;/span&gt;&lt;span class=&quot;moreellipses&quot;&gt;’ + config.ellipsesText + ‘ &lt;/span&gt;&lt;span class=&quot;morecontent&quot;&gt;’ + content + ‘&lt;/span&gt; &lt;a href=&quot;#&quot; class=&quot;morelink&quot;&gt;’ + config.moreText + ‘&lt;/a&gt;’;
    $this.html(html);
    $(&quot;.morecontent&quot;).hide();
    }
    });

    };

    });

  24. Manuel says:

    IM SORRY didn´t modified the post source code tag XD

    $(function(){
    	$.fn.shorten = function (settings) {
    	
    		var config = {
    			showChars: 100,
    			ellipsesText: &quot;...&quot;,
    			moreText: &quot;more&quot;,
    			lessText: &quot;less&quot;
    		};
    
    		if (settings) {
    			$.extend(config, settings);
    		}
    		
    		 $(document).on({click: function (){
    		 
    			var $this = $(this);
    				if ($this.hasClass('less')) {
    					$this.removeClass('less');
    					$this.html(config.moreText);
    					$('.morecontent').fadeOut(function(){
    						$('.lesscontent').fadeIn();
    						$('.moreellipses').show();
    					});
    				}else{
    					$this.addClass('less');
    					$this.html(config.lessText);
    					$('.lesscontent').fadeOut(function() {
    						$('.morecontent').fadeIn();
    						$('.moreellipses').hide();
    					});
    				}
    			}
    		}, '.morelink');
    
    		return this.each(function () {
    			var $this = $(this);
    			if($this.hasClass(&quot;shortened&quot;)) return;
    			
    			$this.addClass(&quot;shortened&quot;);
    			var content = $this.html();
    			if (content.length &gt; config.showChars) {
    				var c = content.substr(0, config.showChars);
    				var html = '&lt;span class=&quot;lesscontent&quot;&gt;'+ c + '&lt;/span&gt;&lt;span class=&quot;moreellipses&quot;&gt;' + config.ellipsesText + ' &lt;/span&gt;&lt;span class=&quot;morecontent&quot;&gt;' + content + '&lt;/span&gt; &lt;a href=&quot;#&quot; class=&quot;morelink&quot;&gt;' + config.moreText + '&lt;/a&gt;';
    				$this.html(html);
    				$(&quot;.morecontent&quot;).hide();
    			}
    		});
    		
    	};
    
     });
    
    
  25. Krishnakant Bhadoria says:

    Hi ,

    I am using shorten.js in my application for read more feature.However,I want to change the color of ‘Read More’ link after being visited.I tried changing the color for this link using ‘morelink’ class ,but it is not working fine.Can anyone please suggest a solution for this..

  26. Louis says:

    I want to display all the text but have the option of shortening it. How do I call that?

  27. Rhys says:

    I’m having the same issue as another poster where the “Read more” link is showing up on a different line rather than at the end of the text as displayed in the samples.

    Current:
    Lorem ipsum dolor sit amet…
    Read more

    Desired
    Lorem ipsum dolor sit amet… Read more

  28. Natty says:

    This doesn’t work for nested elements. Any fix on that.

  29. Rob says:

    It seems to miss numbered lists from the hidden section.

    It works ok with bulleted lists but not numbered lists.

    Please advice.

  30. bm says:

    it’s not working

  31. imesh says:

    this doesn’t work for any browser.

  32. Roman says:

    It will be better to store separate config for each element, because I use different more and less words on one page, and after expanding/collapsing the more/less text is being override by last configured text

  33. Shravan says:

    This is not working when the text contains anchor tags .please verify the same by adding some anchor tags ,coz apsn tags are been added in anchor tag ,hence making the function not working

  34. Sangram Desai says:

    Need to set height:auto in jquery.shorton.js like below that is height:’0’+’%’ not working properly.so i done like
    $this.parent().prev().animate({‘height’:’auto’}, function () { $this.parent().prev().prev().show(); }).hide(‘fast’);

  35. Sangram Desai says:

    $this.parent().prev().animate({‘height’:’auto’}, function () { $this.parent().prev().prev().show(); }).hide(‘fast’);

  36. Laura says:

    Is there any way to modify the code so that the ‘more’ button shows at the end of a word as apposed to the amount of characters? I can’t have the words being broken up. Any ideas what I would need to change this code to? {var showChar=200;

    Thanks

Leave a Reply

Your email address will not be published. Required fields are marked *