adding jQuery.makeCollapsible plugin
[lhc/web/wiklou.git] / resources / jquery / jquery.makeCollapsible.js
1 /**
2 * make lists, divs, tables etc. toggleable
3 *
4 * This will enable collapsible-functionality on all passed elements.
5 * Will prevent binding twice to the same element.
6 * Initial state is expanded by default, this can be overriden by adding class
7 * "kr-collapsed" to the "kr-collapsible" element.
8 * Elements made collapsible have class "kr-made-collapsible".
9 * Except for tables and lists, the inner content is wrapped in "kr-collapsible-content".
10 *
11 * Copyright 2008-2009 Krinkle <krinklemail@gmail.com>
12 *
13 * @license CC-BY 2.0 NL <http://creativecommons.org/licenses/by/2.0/nl/deed.en>
14 */
15
16 $.fn.makeCollapsible = function() {
17
18 return this.each(function() {
19 var $that = $(this).addClass('kr-collapsible'), // in case $('#myAJAXelement').makeCollapsible() was called
20 that = this,
21 collapsetext = $(this).attr('data-collapsetext'),
22 expandtext = $(this).attr('data-expandtext');
23 // Use custom text or default ?
24 if( !collapsetext || collapsetext == ''){
25 collapsetext = 'Collapse';
26 }
27 if ( !expandtext || expandtext == ''){
28 expandtext = 'Expand';
29 }
30 // Create toggle link with a space around the brackets (&nbsp)
31 $toggleLink = $('<span class="kr-collapsible-toggle kr-collapsible-toggle-hide">&nbsp;[<a href="#">' + collapsetext + '</a>]&nbsp;</span>').click(function(){
32 var $that = $(this),
33 $collapsible = $that.closest('.kr-collapsible.kr-made-collapsible').toggleClass('kr-collapsed');
34 if ($that.hasClass('kr-collapsible-toggle-hide')) {
35 // Change link to "Show"
36 $that
37 .removeClass('kr-collapsible-toggle-hide').addClass('kr-collapsible-toggle-show')
38 .find('> a').html(expandtext);
39 // Hide the collapsible element
40 if ($collapsible.is('table')) {
41 // Hide all direct childing table rows of this table, except the row containing the link
42 // Slide doens't work, but fade works fine as of jQuery 1.1.3
43 // http://stackoverflow.com/questions/467336/jquery-how-to-use-slidedown-or-show-function-on-a-table-row#920480
44 // Stop to prevent animaties from stacking up
45 $collapsible.find('> tbody > tr').not($that.parent().parent()).stop(true, true).fadeOut();
46 } else if ($collapsible.is('ul') || $collapsible.is('ol')) {
47 $collapsible.find('> li').not($that.parent()).stop(true, true).slideUp();
48 } else { // <div>, <p> etc.
49 $collapsible.find('> .kr-collapsible-content').slideUp();
50 }
51 } else {
52 // Change link to "Hide"
53 $that
54 .removeClass('kr-collapsible-toggle-show').addClass('kr-collapsible-toggle-hide')
55 .find('> a').html(collapsetext);
56 // Show the collapsible element
57 if ($collapsible.is('table')) {
58 $collapsible.find('> tbody > tr').not($that.parent().parent()).stop(true, true).fadeIn();
59 } else if ($collapsible.is('ul') || $collapsible.is('ol')) {
60 $collapsible.find('> li').not($that.parent()).stop(true, true).slideDown();
61 } else { // <div>, <p> etc.
62 $collapsible.find('> .kr-collapsible-content').slideDown();
63 }
64 }
65 return false;
66 });
67 // Skip if it has been enabled already.
68 if ($that.hasClass('kr-made-collapsible')) {
69 return;
70 } else {
71 $that.addClass('kr-made-collapsible');
72 }
73 // Elements are treated differently
74 if ($that.is('table')) {
75 // The toggle-link will be in the last cell (td or th) of the first row
76 var $lastCell = $('tr:first th, tr:first td', that).eq(-1);
77 if (!$lastCell.find('> .kr-collapsible-toggle').size()) {
78 $lastCell.prepend($toggleLink);
79 }
80
81 } else if ($that.is('ul') || $that.is('ol')) {
82 if (!$('li:first', $that).find('> .kr-collapsible-toggle').size()) {
83 // Make sure the numeral count doesn't get messed up, reset to 1 unless value-attribute is already used
84 if ( $('li:first', $that).attr('value') == '' ) {
85 $('li:first', $that).attr('value', '1');
86 }
87 $that.prepend($toggleLink.wrap('<li class="kr-collapsibile-toggle-li">').parent());
88 }
89 } else { // <div>, <p> etc.
90 // Is there an content-wrapper already made ?
91 // If a direct child with the class does not exists, create the wrap.
92 if (!$that.find('g> .kr-collapsible-content').size()) {
93 $that.wrapInner('<div class="kr-collapsible-content">');
94 }
95
96 // Add toggle-link if not present
97 if (!$that.find('> .kr-collapsible-toggle').size()) {
98 $that.prepend($toggleLink);
99 }
100 }
101 // Initial state
102 if ($that.hasClass('kr-collapsed')) {
103 $toggleLink.click();
104 }
105 });
106 };
107 $(function(){
108 $('.kr-collapsible').makeCollapsible();
109 });