[ Index ]

PHP Cross Reference of Drupal 6 (yi-drupal)

title

Body

[close]

/sites/all/modules/views/js/ -> tabs.js (source)

   1  
   2  /**
   3   * @file tabs.js
   4   * jQuery UI Tabs (Tabs 3)
   5   *
   6   * This is nothing more than the pure jquery UI tabs implementation.
   7   * It has been implemented under the Drupal.Views.Tabs namespace to
   8   * avoid conflicts with alternatve versions of jquery, jquery UI.
   9   */
  10  
  11  Drupal.Views = Drupal.Views || {};
  12  
  13  Drupal.Views.Tabs = function(el, options) {
  14  
  15    this.source = el;
  16  
  17    this.options = $.extend({
  18  
  19      // basic setup
  20      initial: 0,
  21      event: 'click',
  22      disabled: [],
  23      // TODO bookmarkable: $.ajaxHistory ? true : false,
  24      unselected: false,
  25      toggle: options.unselected ? true : false,
  26  
  27      // Ajax
  28      spinner: 'Loading…',
  29      cache: false,
  30      hashPrefix: 'tab-',
  31  
  32      // animations
  33      /*fxFade: null,
  34      fxSlide: null,
  35      fxShow: null,
  36      fxHide: null,*/
  37      fxSpeed: 'normal',
  38      /*fxShowSpeed: null,
  39      fxHideSpeed: null,*/
  40  
  41      // callbacks
  42      add: function() {},
  43      remove: function() {},
  44      enable: function() {},
  45      disable: function() {},
  46      click: function() {},
  47      hide: function() {},
  48      show: function() {},
  49      load: function() {},
  50  
  51      // CSS classes
  52      navClass: 'ui-tabs-nav',
  53      selectedClass: 'ui-tabs-selected',
  54      disabledClass: 'ui-tabs-disabled',
  55      containerClass: 'ui-tabs-container',
  56      hideClass: 'ui-tabs-hide',
  57      loadingClass: 'ui-tabs-loading'
  58  
  59    }, options);
  60  
  61    this.tabify(true);
  62  
  63    // save instance for later
  64    var uuid = 'instance-' + Drupal.Views.Tabs.prototype.count++;
  65    Drupal.Views.Tabs.instances[uuid] = this;
  66    this.source.data('UI_TABS_UUID', uuid);
  67  
  68  };
  69  
  70  // static
  71  Drupal.Views.Tabs.instances = {};
  72  
  73  $.extend(Drupal.Views.Tabs.prototype, {
  74    animating: false,
  75    count: 0,
  76    tabify: function(init) {
  77  
  78      this.$tabs = $('a:first-child', this.source);
  79      this.$containers = $([]);
  80  
  81      var self = this, o = this.options;
  82  
  83      this.$tabs.each(function(i, a) {
  84        // inline tab
  85        if (a.hash && a.hash.replace('#', '')) { // safari 2 reports '#' for an empty hash
  86          self.$containers = self.$containers.add(a.hash);
  87        }
  88        // remote tab
  89        else {
  90          var id = a.title && a.title.replace(/\s/g, '_') || o.hashPrefix + (self.count + 1) + '-' + (i + 1), url = a.href;
  91          a.href = '#' + id;
  92          a.url = url;
  93          self.$containers = self.$containers.add(
  94            $('#' + id)[0] || $('<div id="' + id + '" class="' + o.containerClass + '"></div>')
  95              .insertAfter( self.$containers[i - 1] || self.source )
  96          );
  97        }
  98      });
  99  
 100      if (init) {
 101  
 102        // Try to retrieve initial tab from fragment identifier in url if present,
 103        // otherwise try to find selected class attribute on <li>.
 104        this.$tabs.each(function(i, a) {
 105          if (location.hash) {
 106            if (a.hash == location.hash) {
 107              o.initial = i;
 108              // prevent page scroll to fragment
 109              //if (($.browser.msie || $.browser.opera) && !o.remote) {
 110              if ($.browser.msie || $.browser.opera) {
 111                var $toShow = $(location.hash), toShowId = $toShow.attr('id');
 112                $toShow.attr('id', '');
 113                setTimeout(function() {
 114                  $toShow.attr('id', toShowId); // restore id
 115                }, 500);
 116              }
 117              scrollTo(0, 0);
 118              return false; // break
 119            }
 120          } else if ( $(a).parents('li:eq(0)').is('li.' + o.selectedClass) ) {
 121            o.initial = i;
 122            return false; // break
 123          }
 124        });
 125  
 126        // attach necessary classes for styling if not present
 127        $(this.source).is('.' + o.navClass) || $(this.source).addClass(o.navClass);
 128        this.$containers.each(function() {
 129          var $this = $(this);
 130          $this.is('.' + o.containerClass) || $this.addClass(o.containerClass);
 131        });
 132  
 133        // highlight tab accordingly
 134        var $lis = $('li', this.source);
 135        this.$containers.addClass(o.hideClass);
 136        $lis.removeClass(o.selectedClass);
 137        if (!o.unselected) {
 138          this.$containers.slice(o.initial, o.initial + 1).show();
 139          $lis.slice(o.initial, o.initial + 1).addClass(o.selectedClass);
 140        }
 141  
 142        // trigger load of initial tab is remote tab
 143        if (this.$tabs[o.initial].url) {
 144          this.load(o.initial + 1, this.$tabs[o.initial].url);
 145          if (o.cache) {
 146            this.$tabs[o.initial].url = null; // if loaded once do not load them again
 147          }
 148        }
 149  
 150        // disabled tabs
 151        for (var i = 0, position; position = o.disabled[i]; i++) {
 152          this.disable(position);
 153        }
 154  
 155      }
 156  
 157      // setup animations
 158      var showAnim = {}, hideAnim = {}, showSpeed = o.fxShowSpeed || o.fxSpeed,
 159        hideSpeed = o.fxHideSpeed || o.fxSpeed;
 160      if (o.fxSlide || o.fxFade) {
 161        if (o.fxSlide) {
 162          showAnim['height'] = 'show';
 163          hideAnim['height'] = 'hide';
 164        }
 165        if (o.fxFade) {
 166          showAnim['opacity'] = 'show';
 167          hideAnim['opacity'] = 'hide';
 168        }
 169      } else {
 170        if (o.fxShow) {
 171          showAnim = o.fxShow;
 172        } else { // use some kind of animation to prevent browser scrolling to the tab
 173          showAnim['min-width'] = 0; // avoid opacity, causes flicker in Firefox
 174          showSpeed = 1; // as little as 1 is sufficient
 175        }
 176        if (o.fxHide) {
 177          hideAnim = o.fxHide;
 178        } else { // use some kind of animation to prevent browser scrolling to the tab
 179          hideAnim['min-width'] = 0; // avoid opacity, causes flicker in Firefox
 180          hideSpeed = 1; // as little as 1 is sufficient
 181        }
 182      }
 183  
 184      // callbacks
 185      var click = o.click, hide = o.hide, show = o.show;
 186  
 187      // reset some styles to maintain print style sheets etc.
 188      var resetCSS = { display: '', overflow: '', height: '' };
 189      if (!$.browser.msie) { // not in IE to prevent ClearType font issue
 190        resetCSS['opacity'] = '';
 191      }
 192  
 193      // hide a tab, animation prevents browser scrolling to fragment
 194      function hideTab(clicked, $hide, $show) {
 195        $hide.animate(hideAnim, hideSpeed, function() { //
 196          $hide.addClass(o.hideClass).css(resetCSS); // maintain flexible height and accessibility in print etc.
 197          hide(clicked, $show, $hide[0]);
 198          if ($show) {
 199            showTab(clicked, $hide, $show);
 200          }
 201        });
 202      }
 203  
 204      // show a tab, animation prevents browser scrolling to fragment
 205      function showTab(clicked, $hide, $show) {
 206        // show next tab
 207        if (!(o.fxSlide || o.fxFade || o.fxShow)) {
 208          $show.css('display', 'block'); // prevent occasionally occuring flicker in Firefox cause by gap between showing and hiding the tab containers
 209        }
 210        $show.animate(showAnim, showSpeed, function() {
 211          $show.removeClass(o.hideClass).css(resetCSS); // maintain flexible height and accessibility in print etc.
 212          if ($.browser.msie) {
 213            $hide[0].style.filter = '';
 214            $show[0].style.filter = '';
 215          }
 216          show(clicked, $show[0], $hide[0]);
 217          self.animating = false;
 218        });
 219  
 220      }
 221  
 222      // switch a tab
 223      function switchTab(clicked, $hide, $show) {
 224        /*if (o.bookmarkable && trueClick) { // add to history only if true click occured, not a triggered click
 225          $.ajaxHistory.update(clicked.hash);
 226        }*/
 227        $(clicked).parents('li:eq(0)').addClass(o.selectedClass)
 228          .siblings().removeClass(o.selectedClass);
 229        hideTab(clicked, $hide, $show);
 230      }
 231  
 232      // tab click handler
 233      function tabClick(e) {
 234  
 235        //var trueClick = e.clientX; // add to history only if true click occured, not a triggered click
 236        var $li = $(this).parents('li:eq(0)'), $hide = self.$containers.filter(':visible'), $show = $(this.hash);
 237  
 238        // if tab may be closed
 239        if (o.toggle && !$li.is('.' + o.disabledClass) && !self.animating) {
 240          if ($li.is('.' + o.selectedClass)) {
 241            $li.removeClass(o.selectedClass);
 242            hideTab(this, $hide);
 243            this.blur();
 244            return false;
 245          } else if (!$hide.length) {
 246            $li.addClass(o.selectedClass);
 247            showTab(this, $hide, $show);
 248            this.blur();
 249            return false;
 250          }
 251        }
 252  
 253        // If tab is already selected or disabled, animation is still running or click callback
 254        // returns false stop here.
 255        // Check if click handler returns false last so that it is not executed for a disabled tab!
 256        if ($li.is('.' + o.selectedClass + ', .' + o.disabledClass)
 257          || self.animating || click(this, $show[0], $hide[0]) === false) {
 258          this.blur();
 259          return false;
 260        }
 261  
 262        self.animating = true;
 263  
 264        // show new tab
 265        if ($show.length) {
 266  
 267          // prevent scrollbar scrolling to 0 and than back in IE7, happens only if bookmarking/history is enabled
 268          /*if ($.browser.msie && o.bookmarkable) {
 269            var showId = this.hash.replace('#', '');
 270            $show.attr('id', '');
 271            setTimeout(function() {
 272              $show.attr('id', showId); // restore id
 273            }, 0);
 274          }*/
 275  
 276          if (this.url) { // remote tab
 277            var a = this;
 278            self.load(self.$tabs.index(this) + 1, this.url, function() {
 279              switchTab(a, $hide, $show);
 280            });
 281            if (o.cache) {
 282              this.url = null; // if loaded once do not load them again
 283            }
 284          } else {
 285            switchTab(this, $hide, $show);
 286          }
 287  
 288          // Set scrollbar to saved position - need to use timeout with 0 to prevent browser scroll to target of hash
 289          /*var scrollX = window.pageXOffset || document.documentElement && document.documentElement.scrollLeft || document.body.scrollLeft || 0;
 290          var scrollY = window.pageYOffset || document.documentElement && document.documentElement.scrollTop || document.body.scrollTop || 0;
 291          setTimeout(function() {
 292            scrollTo(scrollX, scrollY);
 293          }, 0);*/
 294  
 295        } else {
 296          throw Drupal.t('jQuery UI Tabs: Mismatching fragment identifier.');
 297        }
 298  
 299        this.blur(); // prevent IE from keeping other link focussed when using the back button
 300  
 301        //return o.bookmarkable && !!trueClick; // convert trueClick == undefined to Boolean required in IE
 302        return false;
 303  
 304      }
 305  
 306      // attach click event, avoid duplicates from former tabifying
 307      this.$tabs.unbind(o.event, tabClick).bind(o.event, tabClick);
 308  
 309    },
 310    add: function(url, text, position) {
 311      if (url && text) {
 312        var o = this.options;
 313        position = position || this.$tabs.length; // append by default
 314        if (position >= this.$tabs.length) {
 315          var method = 'insertAfter';
 316          position = this.$tabs.length;
 317        } else {
 318          var method = 'insertBefore';
 319        }
 320        if (url.indexOf('#') == 0) { // ajax container is created by tabify automatically
 321          var $container = $(url);
 322          // try to find an existing element before creating a new one
 323          ($container.length && $container || $('<div id="' + url.replace('#', '') + '" class="' + o.containerClass + ' ' + o.hideClass + '"></div>'))
 324            [method](this.$containers[position - 1]);
 325        }
 326        $('<li><a href="' + url + '"><span>' + text + '</span></a></li>')
 327          [method](this.$tabs.slice(position - 1, position).parents('li:eq(0)'));
 328        this.tabify();
 329        o.add(this.$tabs[position - 1], this.$containers[position - 1]); // callback
 330      } else {
 331        throw Drupal.t('jQuery UI Tabs: Not enough arguments to add tab.');
 332      }
 333    },
 334    remove: function(position) {
 335      if (position && position.constructor == Number) {
 336        this.$tabs.slice(position - 1, position).parents('li:eq(0)').remove();
 337        this.$containers.slice(position - 1, position).remove();
 338        this.tabify();
 339      }
 340      this.options.remove(); // callback
 341    },
 342    enable: function(position) {
 343      var $li = this.$tabs.slice(position - 1, position).parents('li:eq(0)'), o = this.options;
 344      $li.removeClass(o.disabledClass);
 345      if ($.browser.safari) { // fix disappearing tab after enabling in Safari... TODO check Safari 3
 346        $li.animate({ opacity: 1 }, 1, function() {
 347          $li.css({ opacity: '' });
 348        });
 349      }
 350      o.enable(this.$tabs[position - 1], this.$containers[position - 1]); // callback
 351    },
 352    disable: function(position) {
 353      var $li = this.$tabs.slice(position - 1, position).parents('li:eq(0)'), o = this.options;
 354      if ($.browser.safari) { // fix opacity of tab after disabling in Safari... TODO check Safari 3
 355        $li.animate({ opacity: 0 }, 1, function() {
 356            $li.css({ opacity: '' });
 357        });
 358      }
 359      $li.addClass(this.options.disabledClass);
 360      o.disable(this.$tabs[position - 1], this.$containers[position - 1]); // callback
 361    },
 362    click: function(position) {
 363      this.$tabs.slice(position - 1, position).trigger('click');
 364    },
 365    load: function(position, url, callback) {
 366      var self = this,
 367        o = this.options,
 368        $a = this.$tabs.slice(position - 1, position).addClass(o.loadingClass),
 369        $span = $('span', $a),
 370        text = $span.html();
 371  
 372      // shift arguments
 373      if (url && url.constructor == Function) {
 374        callback = url;
 375      }
 376  
 377      // set new URL
 378      if (url) {
 379        $a[0].url = url;
 380      }
 381  
 382      // load
 383      if (o.spinner) {
 384        $span.html('<em>' + o.spinner + '</em>');
 385      }
 386      setTimeout(function() { // timeout is again required in IE, "wait" for id being restored
 387        $($a[0].hash).load(url, function() {
 388          if (o.spinner) {
 389            $span.html(text);
 390          }
 391          $a.removeClass(o.loadingClass);
 392          // This callback is needed because the switch has to take place after loading
 393          // has completed.
 394          if (callback && callback.constructor == Function) {
 395            callback();
 396          }
 397          o.load(self.$tabs[position - 1], self.$containers[position - 1]); // callback
 398        });
 399      }, 0);
 400    }
 401  });


Generated: Mon Jul 9 18:01:44 2012 Cross-referenced by PHPXref 0.7