├── MIT-LICENSE.txt ├── src ├── jquery.shorten.min.js └── jquery.shorten.js ├── samples └── index.html └── README.md /MIT-LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright 2013 Viral Patel and other contributors 2 | http://viralpatel.net 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining 5 | a copy of this software and associated documentation files (the 6 | "Software"), to deal in the Software without restriction, including 7 | without limitation the rights to use, copy, modify, merge, publish, 8 | distribute, sublicense, and/or sell copies of the Software, and to 9 | permit persons to whom the Software is furnished to do so, subject to 10 | the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 19 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 20 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 21 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /src/jquery.shorten.min.js: -------------------------------------------------------------------------------- 1 | !function(e){e.fn.shorten=function(s){"use strict";var t={showChars:100,minHideChars:10,ellipsesText:"...",moreText:"more",lessText:"less",onLess:function(){},onMore:function(){},errMsg:null,force:!1};return s&&e.extend(t,s),e(this).data("jquery.shorten")&&!t.force?!1:(e(this).data("jquery.shorten",!0),e(document).off("click",".morelink"),e(document).on({click:function(){var s=e(this);return s.hasClass("less")?(s.removeClass("less"),s.html(t.moreText),s.parent().prev().animate({height:"0%"},function(){s.parent().prev().prev().show()}).hide("fast",function(){t.onLess()})):(s.addClass("less"),s.html(t.lessText),s.parent().prev().animate({height:"100%"},function(){s.parent().prev().prev().hide()}).show("fast",function(){t.onMore()})),!1}},".morelink"),this.each(function(){var s=e(this),n=s.html(),r=s.text().length;if(r>t.showChars+t.minHideChars){var o=n.substr(0,t.showChars);if(o.indexOf("<")>=0){for(var a=!1,i="",h=0,l=[],c=null,f=0,u=0;u<=t.showChars;f++)if("<"!=n[f]||a||(a=!0,c=n.substring(f+1,n.indexOf(">",f)),"/"==c[0]?c!="/"+l[0]?t.errMsg="ERROR en HTML: the top of the stack should be the tag that closes":l.shift():"br"!=c.toLowerCase()&&l.unshift(c)),a&&">"==n[f]&&(a=!1),a)i+=n.charAt(f);else if(u++,h<=t.showChars)i+=n.charAt(f),h++;else if(l.length>0){for(j=0;j";break}o=e("
").html(i+''+t.ellipsesText+"").html()}else o+=t.ellipsesText;var m='
'+o+'
'+n+'
'+t.moreText+"";s.html(m),s.find(".allcontent").hide(),e(".shortcontent p:last",s).css("margin-bottom",0)}}))}}(jQuery); -------------------------------------------------------------------------------- /samples/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Dynamically shortened Text with Show More link using jQuery 8 | 9 | 10 | 11 | 12 |
13 |
14 | 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. 15 |
16 |
17 | 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. 18 |
19 |
20 | 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. 21 |
22 | 23 | 24 |

Duisds nisl nibh, egestas at fermentum at, viverra et purus. Maecenas lobortis odio id sapien facilisis elementum. chickenCurabitur et magna justo, et gravida augue. Sed tristique pellentesque arcu quis tempor. 25 |
26 | 27 | 28 |
29 | A quick brown fox jumps over a lazy dog 30 |
31 | 32 | 33 |
34 | foo bar 35 |
36 | 37 | 46 | 47 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Shorten 2 | ======= 3 | 4 | ![jquery shorten plugin](http://img.viralpatel.net/2010/12/show-more-link.png "jquery shorten plugin") 5 | 6 | A simple jquery plugin that automatically shortens text within an element and add "more" link. 7 | 8 | *Read tutorial: [jQuery Shorten](http://viralpatel.net/blogs/dynamically-shortened-text-show-more-link-jquery/).* 9 | 10 | Usage 11 | ----- 12 | Shortens the text within 'element' and add a 'more' link. 13 | 14 | $(element).shorten(); 15 | 16 | Add a link with text 'read more' while shortening the content of element. 17 | 18 | $(element).shorten({ 19 | moreText: 'read more' 20 | }); 21 | 22 | Change the link text to 'read more' and 'read less' overriding default value 'more' and 'less'. 23 | 24 | $(element).shorten({ 25 | moreText: 'read more', 26 | lessText: 'read less' 27 | }); 28 | 29 | Override default display 100 characters and hide text above 50 characters. 30 | 31 | $(element).shorten({ 32 | showChars: 50, 33 | }); 34 | 35 | Parameters 36 | ---------- 37 | You can change the behaviour by changing following js variables. 38 | 39 | | Property | Description | 40 | | -------------- | ----------------------------------------------------------------------------------------- | 41 | | `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. | 42 | | `ellipsesText` | The text displayed before “more” link. Default is “…” | 43 | | `moreText` | The text shown in more link. Default is “more”. You can change to ">>" or "read more" | 44 | | `lessText` | The text shown in less link. Default is “less”. You can change to "<<" or "read less" | 45 | | `onMore` | Callback function to trigger when "more" is clicked | 46 | | `onLess` | Callback function to trigger when "less" is clicked | 47 | 48 | 49 | Licence 50 | ------- 51 | 52 | Copyright 2013 Viral Patel and other contributors 53 | http://viralpatel.net 54 | 55 | Permission is hereby granted, free of charge, to any person obtaining 56 | a copy of this software and associated documentation files (the 57 | "Software"), to deal in the Software without restriction, including 58 | without limitation the rights to use, copy, modify, merge, publish, 59 | distribute, sublicense, and/or sell copies of the Software, and to 60 | permit persons to whom the Software is furnished to do so, subject to 61 | the following conditions: 62 | 63 | The above copyright notice and this permission notice shall be 64 | included in all copies or substantial portions of the Software. 65 | 66 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 67 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 68 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 69 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 70 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 71 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 72 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 73 | -------------------------------------------------------------------------------- /src/jquery.shorten.js: -------------------------------------------------------------------------------- 1 | /* 2 | * jQuery Shorten plugin 1.1.0 3 | * 4 | * Copyright (c) 2014 Viral Patel 5 | * http://viralpatel.net 6 | * 7 | * Licensed under the MIT license: 8 | * http://www.opensource.org/licenses/mit-license.php 9 | */ 10 | 11 | /* 12 | ** updated by Jeff Richardson 13 | ** Updated to use strict, 14 | ** IE 7 has a "bug" It is returning underfined when trying to reference string characters in this format 15 | ** content[i]. IE 7 allows content.charAt(i) This works fine in all modern browsers. 16 | ** I've also added brackets where they werent added just for readability (mostly for me). 17 | */ 18 | 19 | (function($) { 20 | $.fn.shorten = function(settings) { 21 | "use strict"; 22 | 23 | var config = { 24 | showChars: 100, 25 | minHideChars: 10, 26 | ellipsesText: "...", 27 | moreText: "more", 28 | lessText: "less", 29 | onLess: function() {}, 30 | onMore: function() {}, 31 | errMsg: null, 32 | force: false 33 | }; 34 | 35 | if (settings) { 36 | $.extend(config, settings); 37 | } 38 | 39 | if ($(this).data('jquery.shorten') && !config.force) { 40 | return false; 41 | } 42 | $(this).data('jquery.shorten', true); 43 | 44 | $(document).off("click", '.morelink'); 45 | 46 | $(document).on({ 47 | click: function() { 48 | 49 | var $this = $(this); 50 | if ($this.hasClass('less')) { 51 | $this.removeClass('less'); 52 | $this.html(config.moreText); 53 | $this.parent().prev().animate({'height':'0'+'%'}, function () { $this.parent().prev().prev().show(); }).hide('fast', function() { 54 | config.onLess(); 55 | }); 56 | 57 | } else { 58 | $this.addClass('less'); 59 | $this.html(config.lessText); 60 | $this.parent().prev().animate({'height':'100'+'%'}, function () { $this.parent().prev().prev().hide(); }).show('fast', function() { 61 | config.onMore(); 62 | }); 63 | } 64 | return false; 65 | } 66 | }, '.morelink'); 67 | 68 | return this.each(function() { 69 | var $this = $(this); 70 | 71 | var content = $this.html(); 72 | var contentlen = $this.text().length; 73 | if (contentlen > config.showChars + config.minHideChars) { 74 | var c = content.substr(0, config.showChars); 75 | if (c.indexOf('<') >= 0) // If there's HTML don't want to cut it 76 | { 77 | var inTag = false; // I'm in a tag? 78 | var bag = ''; // Put the characters to be shown here 79 | var countChars = 0; // Current bag size 80 | var openTags = []; // Stack for opened tags, so I can close them later 81 | var tagName = null; 82 | 83 | for (var i = 0, r = 0; r <= config.showChars; i++) { 84 | if (content[i] == '<' && !inTag) { 85 | inTag = true; 86 | 87 | // This could be "tag" or "/tag" 88 | tagName = content.substring(i + 1, content.indexOf('>', i)); 89 | 90 | // If its a closing tag 91 | if (tagName[0] == '/') { 92 | 93 | 94 | if (tagName != '/' + openTags[0]) { 95 | config.errMsg = 'ERROR en HTML: the top of the stack should be the tag that closes'; 96 | } else { 97 | openTags.shift(); // Pops the last tag from the open tag stack (the tag is closed in the retult HTML!) 98 | } 99 | 100 | } else { 101 | // There are some nasty tags that don't have a close tag like
102 | if (tagName.toLowerCase() != 'br') { 103 | openTags.unshift(tagName); // Add to start the name of the tag that opens 104 | } 105 | } 106 | } 107 | if (inTag && content[i] == '>') { 108 | inTag = false; 109 | } 110 | 111 | if (inTag) { bag += content.charAt(i); } // Add tag name chars to the result 112 | else { 113 | r++; 114 | if (countChars <= config.showChars) { 115 | bag += content.charAt(i); // Fix to ie 7 not allowing you to reference string characters using the [] 116 | countChars++; 117 | } else // Now I have the characters needed 118 | { 119 | if (openTags.length > 0) // I have unclosed tags 120 | { 121 | //console.log('They were open tags'); 122 | //console.log(openTags); 123 | for (j = 0; j < openTags.length; j++) { 124 | //console.log('Cierro tag ' + openTags[j]); 125 | bag += ''; // Close all tags that were opened 126 | 127 | // You could shift the tag from the stack to check if you end with an empty stack, that means you have closed all open tags 128 | } 129 | break; 130 | } 131 | } 132 | } 133 | } 134 | c = $('
').html(bag + '' + config.ellipsesText + '').html(); 135 | }else{ 136 | c+=config.ellipsesText; 137 | } 138 | 139 | var html = '
' + c + 140 | '
' + content + 141 | '
' + config.moreText + ''; 142 | 143 | $this.html(html); 144 | $this.find(".allcontent").hide(); // Hide all text 145 | $('.shortcontent p:last', $this).css('margin-bottom', 0); //Remove bottom margin on last paragraph as it's likely shortened 146 | } 147 | }); 148 | 149 | }; 150 | 151 | })(jQuery); 152 | --------------------------------------------------------------------------------