Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

initial commit

  • Loading branch information...
commit 3e786b64254b2e26f8d31c3d601e6d473a6afda6 0 parents
@n1k0 authored
Showing with 254 additions and 0 deletions.
  1. +76 −0 README.md
  2. +178 −0 jquery.expander.js
76 README.md
@@ -0,0 +1,76 @@
+jQuery Expander plugin
+======================
+
+This [jQuery](http://jquery.com/) plugin adds links to expand and shorten (truncate) plain or html texts.
+
+Installation
+------------
+
+In your HTML document:
+
+ <script src="jquery.js" type="text/javascript"></script>
+ <script src="jquery.expander.js" type="text/javascript"></script>
+
+Sample use
+----------
+
+**HTML:**
+
+ <p class="truncate-200">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>
+
+**Javascript:**
+
+ $('p.truncate-200').expander({
+ slicePoint: 200,
+ });
+
+**Result:**
+
+ <p class="truncate-200">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… <a href="#" class="read-more">read more</a></p>
+
+
+Available settings
+------------------
+
+* `slicePoint`: the number of characters at which the contents will be sliced
+ into two parts. Any tag names in the HTML that appear inside the sliced
+ element before the slicePoint will be counted along with the text characters
+ (default: `100`).
+* `widow`: a threshold of sorts for whether to initially hide/collapse part of
+ the element's contents. If after slicing the contents in two there are
+ fewer words in the second part than the value set by widow, we won't bother
+ hiding/collapsing anything (default: `4`).
+* `expandText`: text displayed in a link instead of the hidden part of the element.
+ Clicking this will expand/show the hidden/collapsed text (default: `read more`).
+* `expandPrefix`: prefix to add before expanded text (default: `&hellip;`).
+* `collapseTimer`: number of milliseconds after text has been expanded at which
+ to collapse the text again (default: `0`).
+* `expandEffect`: expanding jquery effect name (default: `fadeIn`).
+* `expandSpeed`: speed in milliseconds of the animation effect for expanding the text.
+* `userCollapse`: allow the user to re-collapse the expanded text (default: `true`).
+* `userCollapseText`: text to use for the link to re-collapse the text (default: `[collapse expanded text]`).
+* `userCollapsePrefix`: prefix to add after collapsed content (default: `' '`).
+* `cssReadLessClassName`: css class name to add to the read-less span (default: `re-collapse`).
+* `cssReadMoreClassName`: css class name to add to the read-more span (default: `read-more`).
+* `cssDetailsClassName`: css class name to add to the details span (default: `details`).
+* `truncatedSuffix`: a suffix to add to truncated inner text (default: `...`).
+
+Some callbacks are also available as settings:
+
+* `beforeExpand`: called just before the text has been expanded.
+* `afterExpand`: called just after the text has been expanded
+* `onCollapse`: called when text is collapsed.
+
+Credits
+-------
+
+This plugin is a fork of the great [original Expander plugin](http://plugins.learningjquery.com/expander/), slightly adapted to my personal needs and with some added features and behaviors.
178 jquery.expander.js
@@ -0,0 +1,178 @@
+/**
+ * jQuery Expander plugin
+ * Version 0.4 (12/09/2008)
+ * @requires jQuery v1.1.1+
+ *
+ * Dual licensed under the MIT and GPL licenses:
+ * http://www.opensource.org/licenses/mit-license.php
+ * http://www.gnu.org/licenses/gpl.html
+ *
+ */
+(function($) {
+ $.fn.expander = function(options) {
+ var opts = $.extend({}, $.fn.expander.defaults, options);
+ var delayedCollapse;
+ return this.each(function() {
+ var $this = $(this);
+ var o = $.meta ? $.extend({},
+ opts, $this.data()) : opts;
+ var cleanedTag, startTags, endTags;
+ var allText = $this.html();
+ var startText = allText.slice(0, o.slicePoint).replace(/\w+$/, '');
+ startTags = startText.match(/<\w[^>]*>/g);
+ if (startTags) {
+ startText = allText.slice(0, o.slicePoint + startTags.join('').length).replace(/\w+$/, '');
+ }
+
+ if (startText.lastIndexOf('<') > startText.lastIndexOf('>')) {
+ startText = startText.slice(0, startText.lastIndexOf('<'));
+ }
+ var endText = allText.slice(startText.length);
+ // create necessary expand/collapse elements if they don't already exist
+ if (!$('span.' + o.cssDetailsClassName, this).length) {
+ // end script if text length isn't long enough.
+ if (endText.replace(/\s+$/, '').split(' ').length < o.widow) {
+ return;
+ }
+ // otherwise, continue...
+ if (endText.indexOf('</') > -1) {
+ endTags = endText.match(/<(\/)?[^>]*>/g);
+ for (var i = 0; i < endTags.length; i++) {
+
+ if (endTags[i].indexOf('</') > -1) {
+ var startTag, startTagExists = false;
+ for (var j = 0; j < i; j++) {
+ startTag = endTags[j].slice(0, endTags[j].indexOf(' ')).replace(/(\w)$/, '$1>');
+ if (startTag == rSlash(endTags[i])) {
+ startTagExists = true;
+ }
+ }
+ if (!startTagExists) {
+ startText = startText + endTags[i];
+ var matched = false;
+ for (var s = startTags.length - 1; s >= 0; s--) {
+ if (startTags[s].slice(0, startTags[s].indexOf(' ')).replace(/(\w)$/, '$1>') == rSlash(endTags[i]) && matched == false) {
+ cleanedTag = cleanedTag ? startTags[s] + cleanedTag : startTags[s];
+ matched = true;
+ }
+ };
+ }
+ }
+ }
+ endText = cleanedTag && cleanedTag + endText || endText;
+ }
+ $this.html([
+ suffixTruncatedText(startText, o.truncatedSuffix),
+ '<span class="' + o.cssReadMoreClassName + '">',
+ o.expandPrefix,
+ '<a href="#">',
+ ('function' == typeof(o.expandText) ? o.expandText($this) : o.expandText),
+ '</a>',
+ '</span>',
+ '<span class="' + o.cssDetailsClassName + '">',
+ endText,
+ '</span>'
+ ].join(''));
+ }
+ var $thisDetails = $('span.' + o.cssDetailsClassName, this),
+ $readMore = $('span.' + o.cssReadMoreClassName, this);
+ $thisDetails.hide();
+ $readMore.find('a').click(function() {
+ $readMore.hide();
+
+ if (o.expandEffect === 'show' && !o.expandSpeed) {
+ o.beforeExpand($this);
+ $thisDetails.show();
+ o.afterExpand($this);
+ delayCollapse(o, $thisDetails);
+ } else {
+ o.beforeExpand($this);
+ $thisDetails[o.expandEffect](o.expandSpeed, function() {
+ $thisDetails.css({
+ zoom: ''
+ });
+ o.afterExpand($this);
+ delayCollapse(o, $thisDetails);
+ });
+ }
+ return false;
+ });
+ if (o.userCollapse) {
+ $this.find('span.' + o.cssDetailsClassName).append(
+ '<span class="' + o.cssReadLessClassName + '">' + o.userCollapsePrefix +
+ '<a href="#">' +
+ ('function' == typeof(o.userCollapseText) ? o.userCollapseText($this) : o.userCollapseText) +
+ '</a>' +
+ '</span>'
+ );
+ $this.find('span.' + o.cssReadLessClassName + ' a').click(function() {
+ clearTimeout(delayedCollapse);
+ var $detailsCollapsed = $(this).parents('span.' + o.cssDetailsClassName);
+ $detailsCollapsed.hide().prev('span.' + o.cssReadMoreClassName).show();
+ o.onCollapse($this, true);
+ return false;
+ });
+ }
+ });
+
+ function suffixTruncatedText(text, suffix) {
+ return text.replace(/<\/(\w)>\s*$/gi, suffix + '</$1>');
+ }
+
+ function delayCollapse(option, $collapseEl) {
+ if (option.collapseTimer) {
+ delayedCollapse = setTimeout(function() {
+ $collapseEl.hide().prev('span.' + o.cssReadMoreClassName).show();
+ option.onCollapse($collapseEl.parent(), false);
+ },
+ option.collapseTimer);
+ }
+ }
+
+ function rSlash(rString) {
+ return rString.replace(/\//, '');
+ }
+
+ return null;
+ };
+ // plugin defaults
+ $.fn.expander.defaults = {
+ // the number of characters at which the contents will be sliced into two parts.
+ // Note: any tag names in the HTML that appear inside the sliced element before
+ // the slicePoint will be counted along with the text characters.
+ slicePoint: 100,
+ // a threshold of sorts for whether to initially hide/collapse part of the element's contents.
+ // If after slicing the contents in two there are fewer words in the second part than
+ // the value set by widow, we won't bother hiding/collapsing anything.
+ widow: 4,
+ // text displayed in a link instead of the hidden part of the element.
+ // clicking this will expand/show the hidden/collapsed text
+ expandText: 'read more',
+ // prefix to add before expanded text
+ expandPrefix: '&hellip; ',
+ // number of milliseconds after text has been expanded at which to collapse the text again
+ collapseTimer: 0,
+ // expanding jquery effect name
+ expandEffect: 'fadeIn',
+ // speed in milliseconds of the animation effect for expanding the text
+ expandSpeed: '',
+ // allow the user to re-collapse the expanded text.
+ userCollapse: true,
+ // text to use for the link to re-collapse the text
+ userCollapseText: '[collapse expanded text]',
+ // prefix to add after collapsed content
+ userCollapsePrefix: ' ',
+ // css class name to add to the read-less span
+ cssReadLessClassName: 're-collapse',
+ // css class name to add to the read-more span
+ cssReadMoreClassName: 'read-more',
+ // css class name to add to the details span
+ cssDetailsClassName: 'details',
+ // a suffix to add to truncated inner text
+ truncatedSuffix: '...',
+ // some callbacks
+ beforeExpand: function($thisEl) {},
+ afterExpand: function($thisEl) {},
+ onCollapse: function($thisEl, byUser) {}
+ };
+})(jQuery);
Please sign in to comment.
Something went wrong with that request. Please try again.