2011/10/26

Plugin jQuery Sliding Panel

Hola, hoy os presento uno de los plugins de jQuery que he hecho y que os he prometido para esta semana. Hablamos de la continuación del Slide Button ya que comparte gran parte de la apariencia y funcionalidad, pero aplicado a paneles en vez de a botones.


Este plugin está basado en uno denominado jqEasy (un saludo!), pero con cuyas tripas no estoy de acuerdo, ya que arrastraba varios fallos, no seguía las recomendaciones de desarrollo de plugins, definiciones CSS incompletas y memory leaks graves, así que opté por reescribirlo todo desde cero, tanto el CSS como javascript adaptándolo a la apariencia de los slide buttons (lo cual no quiere decir que mi código sea infalible, solo que los errores que detecté han sido corregidos).

Usarlo es lo más sencillo del mundo, ya que solo hay que llamar a la función slidePanel() sobre el contenedor del widget, que tiene que tener una mínima estructura que os detallaré más adelante. La única particularidad es que si se quiere a la izquierda no hay que hacer nada, pero si se quiere a la derecha hay que anadir la clase ".right" al contendor (o usar las propiedades del plugin).

Por defecto también considera que está "fixed" a la página, pero cambiando la propiedad position del CSS (o del objeto jQuery) a "relative" o "absolute", se cambia el comportamiento del widget radicalmete. Para más detalles podéis comprobar el ejemplo del jsFiddle, donde hay ejemplos con las 6 combinaciones posibles.

También es fácilmente integrable con jQueryUI (los estilos aún no, lo siento), pudiéndose usar dentro de una pila de llamadas para añadirle comportamiento con draggable() o modificando las funciones de despliegue del panel mediante las propiedades del objeto jQuery.

Debe funcionar en todos los navegadores, incluido el IE6 (aunque no soporta la propiedad CSS "position: fixed" sustituyéndose por "position: absolute" de forma automática). Evidentemente, mientras más "moderno" sea el navegador, más bonito se verá (transparencias, esquinas redondeadas, etc), pero eso es cosa de CSS y no de código.

Sin más demoras, os dejo el jsF


iddle, donde está todo el código, css y ejemplos necesarios. El código está comentado así como documentado así que no deberíais tener mucho problema. Si encontrarais un bug, no dudéis en comunicármelo. Alternativamente, podéis visitar la página del plugin en la página oficial de jQuery.


Y para los más impacientes, el código completo:

Estructura básica HTML
<div class="slidePanelWidget" id="widget1">
    <a class="slidePanelButton" href="">&nbsp;Widget 1</a>
    <div class="slidePanel panel">

        These are the contents of the widget!
    </div>
</div>

Código javascript minimizado. Llega a ocupar un mínimo de unos 900 bytes. Quién pide más?
/*! jquery.slidePanel-0.1.js - Slide Panel plugin for jQuery
* ==========================================================
* (C) 2011 José Ramón Díaz - jrdiazweb@gmail.com - v.0.1.0 (25/10/2010)
* Requires: jQuery v1.4.3+
* http://3nibbles.blogspot.com/2011/10/plugin-jquery-sliding-panel.html
* You are free to use this code, but you must give credit and/or keep header intact.
* Please, tell me if you find it useful. An email will be enough.
* If you enhance this code or correct a bug, please, tell me.
*/
(function(b){function f(c,d){var g=b.browser.msie&&b.browser.version=="6.0",a=this;a.opts=d;a.widget=c;a.button=a.widget.find(".slidePanelButton");a.panel=a.widget.find(".slidePanel");a.left=a.widget.hasClass("right")?false:true;if(g)a.opts.position=a.opts.position=="fixed"?"absolute":a.opts.position;a.opts.position&&a.button.css("position",a.opts.position);a.opts.buttonTop&&a.button.css("top",a.opts.buttonTop);a.opts.panelTop&&a.panel.css("top",a.opts.panelTop);a.button.attr("href","javascript:void(0)").click(function(){a.opts.ajax?
a.panel.is(":visible")?a.toggle():a.panel.load(a.opts.ajax,function(b,c){c!=="success"&&a.panel.html("Sorry, but there was an error loading the document.

");a.toggle()}):a.toggle();return false});a.deployed=false;a.toggle=function(b){if(typeof open==="boolean")a.deployed=b;a.deployed?a.close():a.open()};var e=0;a.open=function(){a.deployed=true;var b=a.button.width();b&&(oldPaddingR=a.button.css("padding-right"),oldPaddingL=a.button.css("padding-left"),e=b);a.button.addClass("deployed");a.left?
a.button.animate({width:"0px","padding-right":"0px"},a.opts.speed,a.opts.animFunction):a.button.animate({width:"0px","padding-right":"0px","padding-left":oldPaddingR},a.opts.speed,a.opts.animFunction);a.panel.toggle(a.opts.speed,a.opts.animFunction,function(){});a.opts.clickToClose&&a.enableCloseFn()};a.close=function(){a.deployed=false;a.panel.toggle(a.opts.speed,a.opts.animFunction,function(){});a.left?a.button.animate({width:e+"px","padding-right":oldPaddingR},a.opts.speed,a.opts.animFunction):
a.button.animate({width:e+"px","padding-right":oldPaddingR,"padding-left":oldPaddingL},a.opts.speed,a.opts.animFunction);a.button.removeClass("deployed");a.opts.clickToClose&&a.disableCloseFn()};a.stopCloseFn=function(a){a.stopPropagation()};a.enableCloseFn=function(){b(document).bind("click",a.close);a.panel.bind("click",a.stopCloseFn)};a.disableCloseFn=function(){b(document).unbind("click",a.close);a.panel.unbind("click",a.stopCloseFn)}}b.fn.slidePanel=function(c){var d=b.extend({},{position:null,
buttonTop:null,panelTop:null,animFunction:"swing",speed:"fast",ajax:null,clickToClose:true},c);return!this.data("slidePanel")||typeof c=="object"?this.each(function(){var c=b(this);c.data("slidePanel",new f(c,d))}):this.data("slidePanel")}})(jQuery);

Código javascript completo
/*! jquery.slidePanel-0.1.js - Slide Panel plugin for jQuery
 * ==========================================================
 * (C) 2011 José Ramón Díaz - jrdiazweb@gmail.com
 * Version: 0.1.0 (25/10/2010)
 * Requires: jQuery v1.4.3+
 *
 * http://3nibbles.blogspot.com/2011/10/plugin-jquery-sliding-panel.html
 *
 * INSTANTIATION
 * The basic structure is a div indicating on his class if it must be at
 * left (default, no extra class needed) or right (".right" class needed).
 * Inside the div there must be an <a class="slidePanelButton"> and a
 * <div class="slidePanel">. That's all.
 *
 * Manual instantiation
 *     $('.slidePanelWidget').slidePanel( [ options_object ] );
 *
 * Optionally if you use jQueryUI, you can add draggable to it with
 *     $('.slidePanelWidget').slidePanel( [ options_object ] ).draggable( { axis: 'y' } );
 *
 * OPTIONS
 *     - position     : null null (CSS position) / 'fixed' / 'absolute'
 *     - buttonTop    : null top position of the button inside slidePanelWidget. Null = CSS specified.
 *     - panelTop     : null top position of the panel inside slidePanelWidget. Null = CSS specified.
 *     - animFunction : 'swing' Animation function used to deploy panel
 *     - speed        : 'fast' Animation speed
 *     - ajax         : null URL of th AJAX call to perform to load panel contents. It is loaded before deploying the panel.
 *     - clickToClose : true True = click anywhere to close the panel
 *
 * API
 *     - toggle()  Toggles open/close panel state
 *     - open()    Forces open panel
 *     - close()   Forces close panel
 *     - deployed  Indicates that the control is deployed (opened)
 *
 * CLASSES USED
 *     - Container: .slidePanelWidget, .right
 *     - Button:    .slidePanelButton, .deployed
 *     - Content:   .slidePanel
 *
 * HTML format
 *     <div id="widget1" class="slidePanelWidget">
 *        <a class="slidePanelButton"> Name</a>
 *        <div class="slidePanel panel">
 *
 *            <!-- Widget contents -->
 *            Paste here the contents of the panel
 *            <!-- End of widget contents -->
 *
 *        </div>
 *      </div>
 *
 * Legal stuff
 *     You are free to use this code, but you must give credit and/or keep header intact.
 *     Please, tell me if you find it useful. An email will be enough.
 *     If you enhance this code or correct a bug, please, tell me.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 *
 * Modifications:
 *     - 2011-10-25  JRDiaz  Creation
 */
(function($){

    // Instantiation
 $.fn.slidePanel = function( options ) {
  var defaults = {
     position     : null
   , buttonTop    : null
   , panelTop     : null
   , animFunction : 'swing'
   , speed        : 'fast'
   , ajax         : null
   , clickToClose : true
  };

  var opts = $.extend( {}, defaults, options );

  if( !this.data('slidePanel') || typeof options == 'object' )
  {
   // Not instantiated or part of a selector call
   return this.each(function() {
    var me = $(this);
    me.data('slidePanel', new SlidePanel( me, opts ));
   });
  }
  else
  {
   return this.data('slidePanel');
  }
    };

 // SlidePanel Object
    function SlidePanel( el, opts ) {
  var isIE6  = $.browser.msie && $.browser.version == "6.0";

  var me    = this;
  me.opts   = opts;
  me.widget = el;
  me.button = me.widget.find('.slidePanelButton');
  me.panel  = me.widget.find('.slidePanel');
  me.left   = me.widget.hasClass('right') ? false : true;

  // ie6 doesn't like fixed position
  if( isIE6 ) { me.opts.position = me.opts.position == 'fixed' ? 'absolute' : me.opts.position; }

  // set css properties for button and panel
  if( me.opts.position  ) me.button.css( 'position', me.opts.position );
  if( me.opts.buttonTop ) me.button.css( 'top', me.opts.buttonTop );
  if( me.opts.panelTop  ) me.panel.css ( 'top', me.opts.panelTop  );

  // Button click event
  //me.button.attr( "href", "javascript:void(0)" ).mousedown(function() {
  me.button.attr( "href", "javascript:void(0)" ).click( function() {
   // load default content if ajax is false
   if (!me.opts.ajax) {
    //me.panel.toggle( me.opts.speed, me.opts.animFunction, function () {} );
    me.toggle();
   }
   else
   {
    // Loads the panel contents via AJAX if opts.ajax is defined
    if ( !me.panel.is(':visible') ) { // fetch data ONLY when panel is hidden...
     me.panel.load(me.opts.ajax, function( response, status, xhr ) {
      if (status !== "success") { // the ajax source wasn't loaded properly
       var msg = "<p>Sorry, but there was an error loading the document.</p>";
       me.panel.html(msg);
      };
      // Sets the HTML of the panel BEFORE opening it
      //me.panel.toggle( me.opts.speed, me.opts.animFunction, function () {} );
      me.toggle();
     });
    } else {
     //me.panel.toggle( me.opts.speed, me.opts.animFunction, function () {} );
     me.toggle();
    }
   }
   //me.button.toggleClass("deployed");
   return false;
  });

  // Control functions
  me.deployed = false;
  me.toggle = function( deployPanel ) {
   if( typeof open === 'boolean' ) me.deployed = deployPanel; // Forces open or close
   if( !me.deployed ) me.open();
   else               me.close();
  };

  var oldPadding = '0px';
  var oldWidth   = 0;
  me.open = function() {
   me.deployed = true;

   // Stores old values
   var w = me.button.width();
   if( w ) {
    oldPaddingR = me.button.css('padding-right');
    oldPaddingL = me.button.css('padding-left');
    oldWidth   = w;
   }
   me.button.addClass( 'deployed' );
   // Animates button
   if( me.left )
    me.button.animate( { 'width': '0px', 'padding-right': '0px' }, me.opts.speed, me.opts.animFunction );
   else
    me.button.animate( { 'width': '0px', 'padding-right': '0px', 'padding-left': oldPaddingR }, me.opts.speed, me.opts.animFunction );
   me.panel.toggle( me.opts.speed, me.opts.animFunction, function () {} );

   if ( me.opts.clickToClose ) me.enableCloseFn(); // Enables autoclose function if clickToClose is enabled
  };

  me.close = function() {
   me.deployed = false;

   me.panel.toggle( me.opts.speed, me.opts.animFunction, function () {} );
   // Animates button
   if( me.left )
    me.button.animate( { 'width': oldWidth + 'px', 'padding-right': oldPaddingR }, me.opts.speed, me.opts.animFunction );
   else
    me.button.animate( { 'width': oldWidth + 'px', 'padding-right' : oldPaddingR, 'padding-left': oldPaddingL }, me.opts.speed, me.opts.animFunction );
   me.button.removeClass( 'deployed' );

   if ( me.opts.clickToClose ) me.disableCloseFn(); // Disables autoclose function if clickToClose is enabled
  };

  // Autoclose panel when clicking outside
  me.stopCloseFn    = function(e) { e.stopPropagation(); }; // don't close panel when clicking inside it
        me.enableCloseFn  = function( ) { $(document).bind  ( 'click', me.close ); me.panel.bind  ('click', me.stopCloseFn ); };
        me.disableCloseFn = function( ) { $(document).unbind( 'click', me.close ); me.panel.unbind('click', me.stopCloseFn ); }; // Removes binds
 };
})(jQuery);

Código CSS
/*
 * jQuery slidePanel plugin basic styles
 * Version: 0.1.0 (2011/10/25)
 */

/* Widget styles */
.slidePanelWidget { position: fixed; .position: absolute; left: 0; }
.slidePanelWidget.right { left: auto; right: 0; }

  /* Button styles */
  .slidePanelWidget a.slidePanelButton:focus { outline: none; }

  .slidePanelWidget .slidePanelButton {
    white-space: nowrap;
    overflow: hidden;
    position: absolute;
    top: 4px;
    height: 19px;
    background-color: #BAC8DC;

    text-decoration: none;
    color: #fff;
    font-weight: bold;

    z-index: 2;
  }

  /* Left/right button styles */
  .slidePanelWidget .slidePanelButton {
   left: 0;
    padding: 1px 10px 1px 20px;
    background-position: 0 0;

           -moz-border-radius-topright: 10px;
        -khtml-border-top-right-radius: 10px;
       -webkit-border-top-right-radius: 10px;
               border-top-right-radius: 10px;

        -moz-border-radius-bottomright: 10px;
     -khtml-border-bottom-right-radius: 10px;
    -webkit-border-bottom-right-radius: 10px;
            border-bottom-right-radius: 10px;
  }
  .slidePanelWidget.right .slidePanelButton {
   left: auto; right: 0;
    padding: 1px 20px 1px 10px;
    background-position: 100% 0;

                   -moz-border-radius: 0;
                 -khtml-border-radius: 0;
                -webkit-border-radius: 0;
                        border-radius: 0;

           -moz-border-radius-topleft: 10px;
        -khtml-border-top-left-radius: 10px;
       -webkit-border-top-left-radius: 10px;
               border-top-left-radius: 10px;

        -moz-border-radius-bottomleft: 10px;
    -khtml-border-bottom-right-radius: 10px;
    -webkit-border-bottom-left-radius: 10px;
            border-bottom-left-radius: 10px;
  }

  /* Dynamic change of sprites. Sprites are 19px tall */
  .slidePanelWidget .slidePanelButton         { /* Open sprite */ background: #BAC8DC url(data:image/png;base64,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) no-repeat 0 0; }
    .slidePanelWidget .slidePanelButton:hover { background-color: #59B; background-position: 0 -19px; }
    .slidePanelWidget.right .slidePanelButton:hover { background-position: 100% -19px; }

  .slidePanelWidget .slidePanelButton.deployed         { /* Closed sprite */ background: #666 url(data:image/png;base64,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) no-repeat 0 0; }
    .slidePanelWidget .slidePanelButton.deployed:hover { background-color: #59B; background-position: 0 -19px; }
    .slidePanelWidget.right .slidePanelButton.deployed:hover { background-position: 0 -19px; }


  /* Panel styles */
  .slidePanelWidget .slidePanel {
    display: none;
    position: absolute;
    width: auto;
    height: auto;
    z-index: 1;

    padding: 8px;
    color:#CCC;
    background: #111;

      -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=90)";
          filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=90);
    -moz-opacity: .9;
         opacity: .9;
  }

  /* Left/right panel styles */
  .slidePanelWidget .slidePanel {
    left: 0;
           -moz-border-radius-topright: 4px;
        -khtml-border-top-right-radius: 4px;
       -webkit-border-top-right-radius: 4px;
               border-top-right-radius: 4px;

        -moz-border-radius-bottomright: 4px;
     -khtml-border-bottom-right-radius: 4px;
    -webkit-border-bottom-right-radius: 4px;
            border-bottom-right-radius: 4px;
  }
  .slidePanelWidget.right .slidePanel {
    left: auto;
    right: 0;

                   -moz-border-radius: 0;
                 -khtml-border-radius: 0;
                -webkit-border-radius: 0;
                        border-radius: 0;

           -moz-border-radius-topleft: 4px;
        -khtml-border-top-left-radius: 4px;
       -webkit-border-top-left-radius: 4px;
               border-top-left-radius: 4px;

        -moz-border-radius-bottomleft: 4px;
     -khtml-border-bottom-left-radius: 4px;
    -webkit-border-bottom-left-radius: 4px;
            border-bottom-left-radius: 4px;
  }


No hay comentarios:

Publicar un comentario