Last active
December 22, 2015 17:08
-
-
Save stewartknapman/6503861 to your computer and use it in GitHub Desktop.
jQuery plugin for expanding and collapsing an element
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
PM Collapse | |
Expand and collapse a target element but still show the first line of elements child content when its collapsed. | |
basic example: | |
<div class="example1"> | |
<a href="#" data-collapse="example-1-target" class="collapse-action">Expand / Collapse</a> | |
<div id="example-1-target"> | |
... | |
</div> | |
</div> | |
jQuery('.example1').pmCollapse(); | |
not so basic example: | |
<div class="example2"> | |
<a href="#" class="collapse-all-action">Expand all</a> | |
<a href="#" data-collapse="example-2a-target" class="another-collapse-action">Expand</a> | |
<div id="example-2a-target"> | |
... | |
</div> | |
<a href="#" data-collapse="example-2b-target" class="another-collapse-action">Expand</a> | |
<div id="example-2b-target"> | |
... | |
</div> | |
<a href="#" data-collapse="example-2c-target" class="another-collapse-action">Expand</a> | |
<div id="example-2c-target"> | |
... | |
</div> | |
</div> | |
jQuery('.example2').pmCollapse({ | |
actionLink: '.another-collapse-action', // define class name for action links | |
collapseAll: true, // collapse all elements on load | |
onCollapse: function($link, $element){ // Callback function is run when element is collapsed | |
$link.text('Expand'); // e.g. do something link update the current links text | |
}, | |
onExpand: function($link, $element){ // Callback function is run when element is expanded | |
$link.text('Collapse'); | |
}, | |
globalActionLink: '.collapse-all-action', // define a global link to toggle all elements | |
onGlobalCollapse: function($link){ // Callback function is run when all elements are collapsed | |
$link.text('Expand all'); | |
}, | |
onGlobalExpand: function($link){ // Callback function is run when all elements are expanded | |
$link.text('Collapse all'); | |
} | |
}); | |
*/ | |
(function($){ | |
var PMCollapseClass = function(el, opts){ | |
this.container = $(el); | |
var options = opts; | |
var allCollapsed = false; | |
var actionLink = options.actionLink; | |
var collapseCallback = options.onCollapse; | |
var expandCallback = options.onExpand; | |
var globalActionLink = options.globalActionLink; | |
var golbalCollapseCallback = options.onGlobalCollapse; | |
var globalExpandCallback = options.onGlobalExpand; | |
this.init = function(){ // collapse or expand all on load based on allCollapse setting | |
if(options.collapseAll){ | |
this.toggleCollapseAll('collapse'); | |
} else { | |
this.toggleCollapseAll('expand'); | |
} | |
}; | |
this.toggleCollapseAll = function(action){ | |
$(actionLink).each(function(){ | |
var $link = $(this); | |
var $target = getTarget($link); | |
if(action === 'collapse'){ | |
collapse($link, $target, collapseCallback); | |
} else if(action === 'expand'){ | |
expand($link, $target, expandCallback); | |
} | |
}); | |
if(action === 'collapse'){ | |
golbalCollapseCallback($(globalActionLink)); | |
} else if(action === 'expand'){ | |
globalExpandCallback($(globalActionLink)); | |
} | |
}; | |
this.toggleCollapse = function($link){ | |
var $target = getTarget($link); | |
if($target.hasClass('collapse-expanded')){ | |
collapse($link, $target, collapseCallback); | |
} else if($target.hasClass('collapse-collapsed')){ | |
expand($link, $target, expandCallback); | |
} | |
}; | |
var toggleCollapse = this.toggleCollapse; | |
this.container.on('click', actionLink, function(e){ | |
toggleCollapse($(this)); | |
e.preventDefault(); | |
}); | |
if(globalActionLink){ | |
var toggleCollapseAll = this.toggleCollapseAll; | |
this.container.on('click', globalActionLink, function(e){ | |
if(allCollapsed){ | |
toggleCollapseAll('expand'); | |
} else { | |
toggleCollapseAll('collapse'); | |
} | |
e.preventDefault(); | |
}); | |
} | |
var collapse = function($link, $target, callback){ | |
var height = calculateHeight($target); | |
$target.addClass('collapse-collapsed').removeClass('collapse-expanded').height(height); | |
$target.parent().css({'overflow':'hidden'}); | |
if(globalActionLink){ setAllCollapsed(); } | |
callback($link, $target); | |
}; | |
var expand = function($link, $target, callback){ | |
$target.addClass('collapse-expanded').removeClass('collapse-collapsed').height('auto'); | |
$target.parent().css({'overflow':'visible'}); | |
if(globalActionLink){ setAllCollapsed(); } | |
callback($link, $target); | |
}; | |
var getTarget = function($link){ | |
return $(document.getElementById($link.data('collapse'))); | |
}; | |
var calculateHeight = function($target){ | |
var $content = $target.children().first(); | |
var lineHeight = parseInt($content.css('line-height'), 10); | |
var marginTop = parseInt($content.css('margin-top'), 10); | |
return lineHeight + marginTop + 2; // add extra for decenders | |
}; | |
var setAllCollapsed = function(){ | |
var collection = []; | |
var collapsed = []; | |
$(actionLink).each(function(){ | |
var $target = getTarget($(this)); | |
collection.push($target); | |
if($target.hasClass('collapse-collapsed')){ | |
collapsed.push($target); | |
} | |
}); | |
if(collection.length === collapsed.length){ | |
allCollapsed = true; | |
golbalCollapseCallback($(globalActionLink)); | |
} else { | |
allCollapsed = false; | |
globalExpandCallback($(globalActionLink)); | |
} | |
}; | |
}; | |
/*------*/ | |
// jQuery Function | |
$.fn.pmCollapse = function( options ){ | |
var opts = $.extend( {}, $.fn.pmCollapse.defaults, options ); | |
return this.each(function(){ | |
var instance = new PMCollapseClass($(this), opts); | |
instance.init(); | |
}); | |
}; | |
$.fn.pmCollapse.defaults = { | |
collapseAll: false, | |
actionLink: '.collapse-action', | |
onCollapse: function(){}, // $link, $target | |
onExpand: function(){}, // $link, $target | |
globalActionLink: null, | |
onGlobalCollapse: function(){}, // $globalLink | |
onGlobalExpand: function(){} // $globalLink | |
}; | |
}(jQuery)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment