Improving jquery.makeCollapsible:
authorKrinkle <krinkle@users.mediawiki.org>
Thu, 23 Dec 2010 23:34:32 +0000 (23:34 +0000)
committerKrinkle <krinkle@users.mediawiki.org>
Thu, 23 Dec 2010 23:34:32 +0000 (23:34 +0000)
* Setting toggle function in a variable to easier reuse it through the plugin
* Replace "-hide" and "-show" classes with "expanded" and "collapsed" respectively
* For more flexibility, if there's a toggle-element already, bind the function to it and use it instead. Otherwise, just create one as usual. See [[betawiki:User:Krinkle/CollapsingTestpageKr#footer|CollapsingTestpageKr#Combination example]]
** It's more likely that the source has a custom position of the togglelink waiting for it to be bound, then it to be already bound.
* Some comments improved
* Message key "hide" to "collapsible-collapse" (Follow-up r78915 CR)
* Message key "show" to "collapsible-expand"
* Changed toggle-link content filling from html() to text() (message errors like <keyname> caused an HTML-element to be created)

resources/Resources.php
resources/jquery/jquery.makeCollapsible.css
resources/jquery/jquery.makeCollapsible.js

index d4f0a08..d9152b6 100644 (file)
@@ -81,6 +81,7 @@ return array(
        'jquery.makeCollapsible' => array(
                'scripts' => 'resources/jquery/jquery.makeCollapsible.js',
                'styles' => 'resources/jquery/jquery.makeCollapsible.css',
+               'messages' => array( 'collapsible-expand', 'collapsible-collapse' ),
        ),
        'jquery.suggestions' => array(
                'scripts' => 'resources/jquery/jquery.suggestions.js',
index 78d847d..19d4778 100644 (file)
@@ -2,12 +2,12 @@
 .kr-collapsible-toggle {
        float:right;
 }
-.kr-collapsible-toggle-hide,
-.kr-collapsible-toggle-hide a {
+.kr-collapsible-toggle-expanded,
+.kr-collapsible-toggle-expanded a {
        cursor:n-resize;
 }
-.kr-collapsible-toggle-show,
-.kr-collapsible-toggle-show a {
+.kr-collapsible-toggle-collapsed,
+.kr-collapsible-toggle-collapsed a {
        cursor:s-resize;
 }
 /* list-items go as wide as their parent element, don't float them inside list items */
index eb40482..c5e1c5a 100644 (file)
 $.fn.makeCollapsible = function() {
 
        return this.each(function() {
+
                var     $that = $(this).addClass( 'kr-collapsible' ), // in case $( '#myAJAXelement' ).makeCollapsible() was called
                        that = this,
                        collapsetext = $(this).attr( 'data-collapsetext' ),
-                       expandtext = $(this).attr( 'data-expandtext' );
+                       expandtext = $(this).attr( 'data-expandtext' ),
+                       toggleFunction = function( that ) {
+                               var     $that = $(that),
+                                       $collapsible = $that.closest( '.kr-collapsible.kr-made-collapsible' ).toggleClass( 'kr-collapsed' );
+                               
+                               // It's expanded right now
+                               if ( $that.hasClass( 'kr-collapsible-toggle-expanded' ) ) {
+                                       // Change link to "Show"
+                                       $that.removeClass( 'kr-collapsible-toggle-expanded' ).addClass( 'kr-collapsible-toggle-collapsed' );
+                                       if ( $that.find( '> a' ).size() ) {
+                                               $that.find( '> a' ).text( expandtext );
+                                       } else {
+                                               $that.text( expandtext );
+                                       }
+                                       // Hide the collapsible element
+                                       if ( $collapsible.is( 'table' ) ) {
+                                               // Hide all direct childing table rows of this table, except the row containing the link
+                                               // Slide doens't work, but fade works fine as of jQuery 1.1.3
+                                               // http://stackoverflow.com/questions/467336/jquery-how-to-use-slidedown-or-collapsed-function-on-a-table-row#920480
+                                               // Stop to prevent animations from stacking up 
+                                               $collapsible.find( '> tbody > tr' ).not( $that.parent().parent() ).stop( true, true ).fadeOut();
+       
+                                       } else if ( $collapsible.is( 'ul' ) || $collapsible.is( 'ol' ) ) {
+                                               $collapsible.find( '> li' ).not( $that.parent() ).stop( true, true ).slideUp();
+       
+                                       } else { // <div>, <p> etc.
+                                               $collapsible.find( '> .kr-collapsible-content' ).slideUp();
+                                       }
+
+                               // It's collapsed right now
+                               } else {
+                                       // Change link to "Hide"
+                                       $that.removeClass( 'kr-collapsible-toggle-collapsed' ).addClass( 'kr-collapsible-toggle-expanded' );
+                                       if ( $that.find( '> a' ).size() ) {
+                                               $that.find( '> a' ).text( collapsetext );
+                                       } else {
+                                               $that.text( collapsetext );
+                                       }
+                                       // Show the collapsible element
+                                       if ( $collapsible.is( 'table' ) ) {
+                                               $collapsible.find( '> tbody > tr' ).not( $that.parent().parent() ).stop( true, true ).fadeIn();
+       
+                                       } else if ( $collapsible.is( 'ul' ) || $collapsible.is( 'ol' ) ) {
+                                               $collapsible.find( '> li' ).not( $that.parent() ).stop( true, true ).slideDown();
+       
+                                       } else { // <div>, <p> etc.
+                                               $collapsible.find( '> .kr-collapsible-content' ).slideDown();
+                                       }
+                               }
+                               return;
+                       };
+
                // Use custom text or default ?
                if( !collapsetext || collapsetext == '' ){
-                       collapsetext = mw.msg( 'hide' );
+                       collapsetext = mw.msg( 'collapsible-collapse' );
                }
                if ( !expandtext || expandtext == '' ){
-                       expandtext = mw.msg( 'show' );
+                       expandtext = mw.msg( 'collapsible-expand' );
                }
-               // Create toggle link with a space around the brackets (&nbsp)
-               $toggleLink = $( '<span class="kr-collapsible-toggle kr-collapsible-toggle-hide">&nbsp;[<a href="#">' + collapsetext + '</a>]&nbsp;</span>' ).click( function(){
-                       var     $that = $(this),
-                               $collapsible = $that.closest( '.kr-collapsible.kr-made-collapsible' ).toggleClass( 'kr-collapsed' );
-                       if ( $that.hasClass( 'kr-collapsible-toggle-hide' ) ) {
-                               // Change link to "Show"
-                               $that
-                                       .removeClass( 'kr-collapsible-toggle-hide' ).addClass( 'kr-collapsible-toggle-show' )
-                                       .find( '> a' ).html( expandtext );
-                               // Hide the collapsible element
-                               if ( $collapsible.is( 'table' ) ) {
-                                       // Hide all direct childing table rows of this table, except the row containing the link
-                                       // Slide doens't work, but fade works fine as of jQuery 1.1.3
-                                       // http://stackoverflow.com/questions/467336/jquery-how-to-use-slidedown-or-show-function-on-a-table-row#920480
-                                       // Stop to prevent animaties from stacking up 
-                                       $collapsible.find( '> tbody > tr' ).not( $that.parent().parent() ).stop(true, true).fadeOut();
-
-                               } else if ( $collapsible.is( 'ul' ) || $collapsible.is( 'ol' ) ) {
-                                       $collapsible.find( '> li' ).not($that.parent()).stop(true, true).slideUp();
 
-                               } else { // <div>, <p> etc.
-                                       $collapsible.find( '> .kr-collapsible-content' ).slideUp();
-                               }
-
-                       } else {
-                               // Change link to "Hide"
-                               $that
-                                       .removeClass( 'kr-collapsible-toggle-show' ).addClass( 'kr-collapsible-toggle-hide' )
-                                       .find( '> a' ).html( collapsetext );
-                               // Show the collapsible element
-                               if ( $collapsible.is( 'table' ) ) {
-                                       $collapsible.find( '> tbody > tr' ).not( $that.parent().parent() ).stop(true, true).fadeIn();
-
-                               } else if ( $collapsible.is( 'ul' ) || $collapsible.is( 'ol' ) ) {
-                                       $collapsible.find( '> li' ).not( $that.parent() ).stop(true, true).slideDown();
-
-                               } else { // <div>, <p> etc.
-                                       $collapsible.find( '> .kr-collapsible-content' ).slideDown();
-                               }
-                       }
-                       return false;
+               // Create toggle link with a space around the brackets (&nbsp;[text]&nbsp;)
+               var $toggleLink = $( '<a href="#">' ).text( collapsetext ).wrap( '<span class="kr-collapsible-toggle kr-collapsible-toggle-expanded">' ).parent().prepend( '&nbsp;[' ).append( ']&nbsp;' ).click( function(e){
+                       e.preventDefault();
+                       toggleFunction( this );
                } );
 
                // Skip if it has been enabled already.
-               if ($that.hasClass( 'kr-made-collapsible' )) {
+               if ( $that.hasClass( 'kr-made-collapsible' ) ) {
                        return;
                } else {
                        $that.addClass( 'kr-made-collapsible' );
@@ -84,19 +100,36 @@ $.fn.makeCollapsible = function() {
                // Elements are treated differently
                if ( $that.is( 'table' ) ) {
                        // The toggle-link will be in the last cell (td or th) of the first row
-                       var $lastCell = $( 'tr:first th, tr:first td', that ).eq(-1);
-                       if ( !$lastCell.find( '> .kr-collapsible-toggle' ).size() ) {
+                       var     $lastCell = $( 'tr:first th, tr:first td', that ).eq(-1),
+                               $toggle = $lastCell.find( '> .kr-collapsible-toggle' );
+
+                       if ( !$toggle.size() ) {
                                $lastCell.prepend( $toggleLink );
+                       } else {
+                               $toggleLink = $toggle.unbind( 'click' ).click( function( e ){
+                                       e.preventDefault();
+                                       toggleFunction( this );
+                               } );
                        }
                        
-               } else if ($that.is( 'ul' ) || $that.is( 'ol' )) {
-                       if ( !$( 'li:first', $that).find( '> .kr-collapsible-toggle' ).size() ) {
-                               // Make sure the numeral count doesn't get messed up, reset to 1 unless value-attribute is already used
-                               if ( $( 'li:first', $that ).attr( 'value' ) == '' ) {
-                                       $( 'li:first', $that ).attr( 'value', '1' );
+               } else if ( $that.is( 'ul' ) || $that.is( 'ol' ) ) {
+                       // The toggle-link will be in the first list-item
+                       var     $firstItem = $( 'li:first', $that),
+                               $toggle = $firstItem.find( '> .kr-collapsible-toggle' );
+
+                       if ( !$toggle.size() ) {
+                               // Make sure the numeral order doesn't get messed up, reset to 1 unless value-attribute is already used
+                               if ( $firstItem.attr( 'value' ) == '' ) {
+                                       $firstItem.attr( 'value', '1' );
                                }
                                $that.prepend( $toggleLink.wrap( '<li class="kr-collapsibile-toggle-li">' ).parent() );
-                       }               
+                       } else {
+                               $toggleLink = $toggle.unbind( 'click' ).click( function( e ){
+                                       e.preventDefault();
+                                       toggleFunction( this );
+                               } );
+                       }
+
                } else { // <div>, <p> etc.
                        // Is there an content-wrapper already made ?
                        // If a direct child with the class does not exists, create the wrap.
@@ -104,11 +137,20 @@ $.fn.makeCollapsible = function() {
                                $that.wrapInner( '<div class="kr-collapsible-content">' );
                        }
 
-                       // Add toggle-link if not present
-                       if ( !$that.find( '> .kr-collapsible-toggle' ).size() ) {
+                       // The toggle-link will be the first child of the element
+                       var $toggle = $that.find( '> .kr-collapsible-toggle' );
+
+                       if ( !$toggle.size() ) {
                                $that.prepend( $toggleLink );
+                       } else {
+                               $toggleLink = $toggle.unbind( 'click' ).click( function( e ){
+                                       e.preventDefault();
+                                       toggleFunction( this );
+                               } );
                        }
+
                }
+               console.log( $toggleLink.get(0) );
                // Initial state
                if ( $that.hasClass( 'kr-collapsed' ) ) {
                        $toggleLink.click();