xbase-2.x-dev/js/libraries/jquery.clicktoggle/jquery.clicktoggle.js

js/libraries/jquery.clicktoggle/jquery.clicktoggle.js
;(function($, window, document, undefined) {

  'use strict';

  var pluginName = 'clickToggle';
  var defaults = {
    target: {
      'this': 'is-open',
    },
    event: 'click',
    autoClose: false,
    autoCloseIgnore: [],
    closeElement: null,
    condition: null,
    openCallback: null,
    preOpenCallback: null,
    firstOpenCallback: null,
    closeCallback: null,
  };

  function Plugin (element, options) {

    this.element = element;
    this.settings = $.extend({}, defaults, options);
    this._defaults = defaults;
    this.init();
  }

  $.extend(Plugin.prototype, {
    /**
     * Plugin init.
     */
    init: function () {
      var pluginInstance = this;
      var $clickedElement = $(pluginInstance.element);

      $clickedElement.on(pluginInstance.settings.event + '.clickToggle', function (event) {
        if (pluginInstance.settings.condition && pluginInstance.settings.condition($clickedElement) === false) {
          return;
        }

        event.preventDefault();

        var isOpen = pluginInstance.isOpen();

        if (!isOpen) {
          pluginInstance.open();
        }
        else {
          pluginInstance.close();
        }

        // Auto close by click outside
        if (pluginInstance.settings.autoClose && !isOpen) {
          $(document).on('click.clickToggle', function (event) {
            var $eventTarget = $(event.target);

            if ($eventTarget.closest($clickedElement).length) {
              if (!pluginInstance.isOpen()) {
                $(this).off(event);
              }
            }
            else if (
              pluginInstance.settings.autoCloseIgnore &&
              !pluginInstance.elementIsContainedInElements($eventTarget, pluginInstance.settings.autoCloseIgnore, $clickedElement)
            ) {
              pluginInstance.close();
            }
          });
        }
      });

      if (pluginInstance.settings.closeElement) {
        $(pluginInstance.settings.closeElement).on('click.clickToggle', function () {
          $clickedElement.trigger('click');
        });
      }
    },

    /**
     * Destroy plugin instance.
     */
    destroy: function () {
      var pluginInstance = this;
      var $clickedElement = $(pluginInstance.element);
      $clickedElement.off(pluginInstance.settings.event + '.clickToggle');
      if (pluginInstance.settings.closeElement) {
        $(pluginInstance.settings.closeElement).off('click.clickToggle');
      }
      $clickedElement.data(pluginName + 'Plugin', null);
    },

    /**
     * "Open" handler.
     */
    open: function () {
      var pluginInstance = this;
      var $clickedElement = $(pluginInstance.element);

      if (pluginInstance.isOpen()) {
        return;
      }

      $clickedElement.trigger('clickToggleBeforeOpen', [pluginInstance.settings]);

      if (pluginInstance.settings.preOpenCallback) {
        pluginInstance.settings.preOpenCallback($clickedElement, pluginInstance.settings);
      }

      // Add classes
      $.each(pluginInstance.settings.target, function (key, value) {
        var target = pluginInstance.getTarget(key, value, $clickedElement);
        if (target.element.length) {
          target.element.addClass(target.className);
        }
      });

      // Run callbacks
      if (pluginInstance.settings.firstOpenCallback && !$clickedElement.data('was-clicked')) {
        pluginInstance.settings.firstOpenCallback($clickedElement, pluginInstance.settings);
        $clickedElement.data('was-clicked', true);
      }
      if (pluginInstance.settings.openCallback) {
        pluginInstance.settings.openCallback($clickedElement, pluginInstance.settings);
      }

      $clickedElement.trigger('clickToggleOpen', [pluginInstance.settings]);
    },

    /**
     * "Close" handler.
     */
    close: function () {
      var pluginInstance = this;
      var $clickedElement = $(pluginInstance.element);

      if (!pluginInstance.isOpen()) {
        return;
      }

      $clickedElement.trigger('clickToggleBeforeClose', [pluginInstance.settings]);

      // Remove classes
      $.each(pluginInstance.settings.target, function (key, value) {
        var target = pluginInstance.getTarget(key, value, $clickedElement);
        if (target.element.length) {
          target.element.removeClass(target.className);
        }
      });

      // Run callbacks
      if (pluginInstance.settings.closeCallback) {
        pluginInstance.settings.closeCallback($clickedElement, pluginInstance.settings);
      }

      $clickedElement.trigger('clickToggleClose', [pluginInstance.settings]);
    },

    /**
     * Return element by selector, or pseudo-selector, or function.
     */
    getElement: function (element, context) {
      var $context = $(context);
      var $element;

      if (element instanceof jQuery) {
        $element = element;
      }
      else if (element == 'this') {
        $element = $context;
      }
      else if (element == 'parent') {
        $element = $context.parent();
      }
      else if (element == 'next') {
        $element = $context.next();
      }
      else if ($.isFunction(element)) {
        $element = element($context, this.settings);
      }
      else {
        $element = $(element);
      }

      return $element;
    },

    /**
     * Return true if element is open.
     */
    isOpen: function () {
      var $clickedElement = $(this.element);
      var firstTargetKey = Object.keys(this.settings.target)[0];
      var firstTarget = this.getTarget(firstTargetKey, this.settings.target[firstTargetKey], $clickedElement);

      return firstTarget.element.hasClass(firstTarget.className);
    },

    /**
     * Return target element and class.
     */
    getTarget: function (key, value, context) {
      return {
        element: (typeof value == 'object') ? this.getElement(value.element, context) : this.getElement(key, context),
        className: (typeof value == 'object') ? value.className : value,
      };
    },

    /**
     * Return true if checkedElement contained in any element from elementsArray.
     */
    elementIsContainedInElements: function (checkedElement, elementsArray, elementsArrayContext) {
      var pluginInstance = this;
      var $checkedElement = $(checkedElement);
      var contained = false;
      elementsArray = Array.isArray(elementsArray) ? elementsArray : [elementsArray];

      $.each(elementsArray, function (index, elementFromArray) {
        var $elementFromArray = pluginInstance.getElement(elementFromArray, elementsArrayContext);
        if ($checkedElement.closest($elementFromArray).length > 0) {
          contained = true;
        }
      });

      return contained;
    },
  });

  $.fn[pluginName] = function (options) {
    if (typeof(options) != 'object') {
      options = {target: {}};
      options.target[arguments[0]] = arguments[1];
    }

    return this.each(function () {
      if (!$.data(this, pluginName + 'Plugin')) {
        $.data(this, pluginName + 'Plugin', new Plugin(this, options));
      }
    });
  };

})(jQuery, window, document);

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc