Grow your CSS skills. Land your dream job.

[Extraordinary Solved] JQuery Plugin Patterns that can be Applied for Multiple Elements

  • # June 9, 2012 at 2:02 am

    I’m trying to make a JQuery Tab plugin that work for multiple elements:

    (function($) {
    $.fn.simpleTab = function(settings) {

    settings = jQuery.extend({
    active: 1,
    fx: null,
    showSpeed: 600,
    hideSpeed: 400,
    showEasing: null,
    hideEasing: null
    }, settings);

    return this.each(function(i) {
    i = i + 1;
    var $t = $(this),
    $tabContent = $t.children('div[data-tab]'),
    visible = settings.active - 1;

    $t.addClass('simpleTab').prepend('
      ');
      $tabContent.addClass('tab-content').each(function(j) {
      j = j + 1;
      $(this).attr('id', 'tab' + i + j).hide();
      $('.tabs' + i).append('
    • ' + $(this).data('tab') + '
    • ');
      }).eq(visible).show();
      $('.tabs' + i + ' a').on("click", function() {
      var target = $(this).attr('href');
      $(this).parents('.tabs' + i).find('.activeTab').removeClass('activeTab');
      $(this).addClass('activeTab');
      if (settings.fx == "slide") {
      $tabContent.slideUp(settings.hideSpeed, settings.hideEasing);
      $(target).slideDown(settings.showSpeed, settings.showEasing);
      } else if (settings.fx == "fade") {
      $tabContent.hide();
      $(target).fadeIn(settings.showSpeed, settings.showEasing);
      } else {
      $tabContent.hide();
      $(target).show();
      }
      return false;
      }).eq(visible).addClass('activeTab');
      });

      };

      })(jQuery);

      This works for multiple elements when I apply the plugin in a combined selector like this:

      $('#tab1,#tab2,#tab3').simpleTab();

      But what I want is just like JQuery UI plugin. I hope I can apply the above plugin on some elements separately so that I can apply different settings like this:

      $('#tab1').simpleTab();
      $('#tab2').simpleTab({active:4});
      $('#tab3').simpleTab({fx:"fade"});

      But why this concept does not work?
      Do you have a better JQuery plugin pattern. But the simplest. Thanks a lot!

      # June 9, 2012 at 8:35 am

      Hi Hompimpa!

      The main issue is that the i is indexed from each selector so when '#tab1, #tab2, #tab3' is used, it counts 0, 1, 2.

      But when three separate calls to the plugin are made, the count always starts from 0. This is why the tab content is getting mixed between the instances.

      So, the easiest solution is to apply a unique value to each call, so instead define i like this:

      i = this.id;

      Here is an updated demo.

      Also, it is good practice to target the tabs from it’s own wrapper, so instead of depending on i to be unique:

      $('.tabs' + i)

      find the tab this way:

      $t.find('.tabs' + i)
      # June 9, 2012 at 10:14 am

      Works fine. Thanks a lot!!! I add this condition so if the ID is not found, I can use the class:

      clue = '_' + this.id;
      if(!this.id) {
      clue = '_' + this.className;
      }
      (function($) {

      $.fn.simpleTab = function(settings) {

      settings = jQuery.extend({
      active: 1,
      fx: null,
      showSpeed: 600,
      hideSpeed: 400,
      showEasing: null,
      hideEasing: null
      }, settings);

      return this.each(function() {

      var $t = $(this),
      $tabContent = $t.children('div[data-tab]'),
      visible = settings.active - 1,
      clue = '_' + this.id;
      if (!this.id) {
      clue = '_' + this.className;
      }

      $t.addClass('simpleTab').prepend('
        ');

        $tabContent.addClass('tab-content').each(function(i) {
        $(this).attr('id', 'tab' + clue + i).hide();
        $t.find('.tabs' + clue).append('
      • ' + $(this).data('tab') + '
      • ');
        }).eq(visible).show();

        $t.find('.tabs' + clue + ' a').on("click", function() {
        var target = $(this).attr('href');
        $(this).parents('.tabs' + clue).find('.activeTab').removeClass('activeTab');
        $(this).addClass('activeTab');
        if (settings.fx == "slide") {
        $tabContent.slideUp(settings.hideSpeed, settings.hideEasing);
        $(target).slideDown(settings.showSpeed, settings.showEasing);
        } else if (settings.fx == "fade") {
        $tabContent.hide();
        $(target).fadeIn(settings.showSpeed, settings.showEasing);
        } else {
        $tabContent.hide();
        $(target).show();
        }
        return false;
        }).eq(visible).addClass('activeTab');

        });

        };

        })(jQuery);

        http://jsfiddle.net/tovic/yJ6Mg/7/

        # June 9, 2012 at 10:42 pm

        UPSSS!!! I found a better solution. Now it works for all selectors:

        (function($) {

        $.fn.simpleTab = function(settings) {

        settings = jQuery.extend({
        active: 1,
        fx: null,
        showSpeed: 400,
        hideSpeed: 400,
        showEasing: null,
        hideEasing: null
        }, settings);

        return this.each(function() {

        var $t = $(this),
        delayer,
        $tabContent = $t.children('[data-tab]'),
        visible = settings.active - 1;

        $t.addClass('simpleTab').prepend('
          ');

          $tabContent.addClass('tab-content').each(function() {
          $(this).hide();
          $t.find('.tab-wrapper').append('
        • ' + $(this).data('tab') + '
        • ');
          }).eq(visible).show();

          $t.find('.tab-wrapper a').on("click", function() {
          var target = $(this).parent().index();
          $(this).parents('.tab-wrapper').find('.activeTab').removeClass('activeTab');
          $(this).addClass('activeTab');
          if (settings.fx == "slide" || settings.fx == "fancyslide") {
          if (settings.fx == "fancyslide") {
          delayer = settings.hideSpeed;
          } else {
          delayer = 0;
          }
          if ($tabContent.eq(target).is(':hidden')) {
          $tabContent.slideUp(settings.hideSpeed, settings.hideEasing)
          .eq(target).delay(delayer).slideDown(settings.showSpeed, settings.showEasing);
          }
          } else if (settings.fx == "fade") {
          if ($tabContent.eq(target).is(':hidden')) {
          $tabContent.hide()
          .eq(target).fadeIn(settings.showSpeed, settings.showEasing);
          }
          } else {
          $tabContent.hide()
          .eq(target).show();
          }
          return false;
          }).eq(visible).addClass('activeTab');

          });

          };

          })(jQuery);

          http://reader-download.googlecode.com/svn/trunk/SimpleTab/index.html

        Viewing 4 posts - 1 through 4 (of 4 total)

        You must be logged in to reply to this topic.

        *May or may not contain any actual "CSS" or "Tricks".