diff sites/all/modules/ctools/js/collapsible-div.js @ 0:ff03f76ab3fe

initial version
author danieleb <danielebarchiesi@me.com>
date Wed, 21 Aug 2013 18:51:11 +0100
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/modules/ctools/js/collapsible-div.js	Wed Aug 21 18:51:11 2013 +0100
@@ -0,0 +1,240 @@
+/**
+ * @file
+ * Javascript required for a simple collapsible div.
+ *
+ * Creating a collapsible div with this doesn't take too much. There are
+ * three classes necessary:
+ *
+ * - ctools-collapsible-container: This is the overall container that will be
+ *   collapsible. This must be a div.
+ * - ctools-collapsible-handle: This is the title area, and is what will be
+ *   visible when it is collapsed. This can be any block element, such as div
+ *   or h2.
+ * - ctools-collapsible-content: This is the ocntent area and will only be
+ *   visible when expanded. This must be a div.
+ *
+ * Adding 'ctools-collapsible-remember' to the container class will cause the
+ * state of the container to be stored in a cookie, and remembered from page
+ * load to page load. This will only work if the container has a unique ID, so
+ * very carefully add IDs to your containers.
+ *
+ * If the class 'ctools-no-container' is placed on the container, the container
+ * will be the handle. The content will be found by appending '-content' to the
+ * id of the handle. The ctools-collapsible-handle and
+ * ctools-collapsible-content classes will not be required in that case, and no
+ * restrictions on what of data the container is are placed. Like
+ * ctools-collapsible-remember this requires an id to eist.
+ *
+ * The content will be 'open' unless the container class has 'ctools-collapsed'
+ * as a class, which will cause the container to draw collapsed.
+ */
+
+(function ($) {
+  // All CTools tools begin with this if they need to use the CTools namespace.
+  if (!Drupal.CTools) {
+    Drupal.CTools = {};
+  }
+
+  /**
+   * Object to store state.
+   *
+   * This object will remember the state of collapsible containers. The first
+   * time a state is requested, it will check the cookie and set up the variable.
+   * If a state has been changed, when the window is unloaded the state will be
+   * saved.
+   */
+  Drupal.CTools.Collapsible = {
+    state: {},
+    stateLoaded: false,
+    stateChanged: false,
+    cookieString: 'ctools-collapsible-state=',
+
+    /**
+     * Get the current collapsed state of a container.
+     *
+     * If set to 1, the container is open. If set to -1, the container is
+     * collapsed. If unset the state is unknown, and the default state should
+     * be used.
+     */
+    getState: function (id) {
+      if (!this.stateLoaded) {
+        this.loadCookie();
+      }
+
+      return this.state[id];
+    },
+
+    /**
+     * Set the collapsed state of a container for subsequent page loads.
+     *
+     * Set the state to 1 for open, -1 for collapsed.
+     */
+    setState: function (id, state) {
+      if (!this.stateLoaded) {
+        this.loadCookie();
+      }
+
+      this.state[id] = state;
+
+      if (!this.stateChanged) {
+        this.stateChanged = true;
+        $(window).unload(this.unload);
+      }
+    },
+
+    /**
+     * Check the cookie and load the state variable.
+     */
+    loadCookie: function () {
+      // If there is a previous instance of this cookie
+      if (document.cookie.length > 0) {
+        // Get the number of characters that have the list of values
+        // from our string index.
+        offset = document.cookie.indexOf(this.cookieString);
+
+        // If its positive, there is a list!
+        if (offset != -1) {
+          offset += this.cookieString.length;
+          var end = document.cookie.indexOf(';', offset);
+          if (end == -1) {
+            end = document.cookie.length;
+          }
+
+          // Get a list of all values that are saved on our string
+          var cookie = unescape(document.cookie.substring(offset, end));
+
+          if (cookie != '') {
+            var cookieList = cookie.split(',');
+            for (var i = 0; i < cookieList.length; i++) {
+              var info = cookieList[i].split(':');
+              this.state[info[0]] = info[1];
+            }
+          }
+        }
+      }
+
+      this.stateLoaded = true;
+    },
+
+    /**
+     * Turn the state variable into a string and store it in the cookie.
+     */
+    storeCookie: function () {
+      var cookie = '';
+
+      // Get a list of IDs, saparated by comma
+      for (i in this.state) {
+        if (cookie != '') {
+          cookie += ',';
+        }
+        cookie += i + ':' + this.state[i];
+      }
+
+      // Save this values on the cookie
+      document.cookie = this.cookieString + escape(cookie) + ';path=/';
+    },
+
+    /**
+     * Respond to the unload event by storing the current state.
+     */
+    unload: function() {
+      Drupal.CTools.Collapsible.storeCookie();
+    }
+  };
+
+  // Set up an array for callbacks.
+  Drupal.CTools.CollapsibleCallbacks = [];
+  Drupal.CTools.CollapsibleCallbacksAfterToggle = [];
+
+  /**
+   * Bind collapsible behavior to a given container.
+   */
+  Drupal.CTools.bindCollapsible = function () {
+    var $container = $(this);
+
+    // Allow the specification of the 'no container' class, which means the
+    // handle and the container can be completely independent.
+    if ($container.hasClass('ctools-no-container') && $container.attr('id')) {
+      // In this case, the container *is* the handle and the content is found
+      // by adding '-content' to the id. Obviously, an id is required.
+      var handle = $container;
+      var content = $('#' + $container.attr('id') + '-content');
+    }
+    else {
+      var handle = $container.children('.ctools-collapsible-handle');
+      var content = $container.children('div.ctools-collapsible-content');
+    }
+
+    if (content.length) {
+      // Create the toggle item and place it in front of the toggle.
+      var toggle = $('<span class="ctools-toggle"></span>');
+      handle.before(toggle);
+
+      // If the remember class is set, check to see if we have a remembered
+      // state stored.
+      if ($container.hasClass('ctools-collapsible-remember') && $container.attr('id')) {
+        var state = Drupal.CTools.Collapsible.getState($container.attr('id'));
+        if (state == 1) {
+          $container.removeClass('ctools-collapsed');
+        }
+        else if (state == -1) {
+          $container.addClass('ctools-collapsed');
+        }
+      }
+
+      // If we should start collapsed, do so:
+      if ($container.hasClass('ctools-collapsed')) {
+        toggle.toggleClass('ctools-toggle-collapsed');
+        content.hide();
+      }
+
+      var afterToggle = function () {
+        if (Drupal.CTools.CollapsibleCallbacksAfterToggle) {
+          for (i in Drupal.CTools.CollapsibleCallbacksAfterToggle) {
+            Drupal.CTools.CollapsibleCallbacksAfterToggle[i]($container, handle, content, toggle);
+          }
+        }
+      }
+
+      var clickMe = function () {
+        if (Drupal.CTools.CollapsibleCallbacks) {
+          for (i in Drupal.CTools.CollapsibleCallbacks) {
+            Drupal.CTools.CollapsibleCallbacks[i]($container, handle, content, toggle);
+          }
+        }
+
+        // If the container is a table element slideToggle does not do what
+        // we want, so use toggle() instead.
+        if ($container.is('table')) {
+          content.toggle(0, afterToggle);
+        }
+        else {
+          content.slideToggle(100, afterToggle);
+        }
+
+        toggle.toggleClass('ctools-toggle-collapsed');
+
+        // If we're supposed to remember the state of this class, do so.
+        if ($container.hasClass('ctools-collapsible-remember') && $container.attr('id')) {
+          var state = toggle.hasClass('ctools-toggle-collapsed') ? -1 : 1;
+          Drupal.CTools.Collapsible.setState($container.attr('id'), state);
+        }
+
+        return false;
+      }
+
+      // Let both the toggle and the handle be clickable.
+      toggle.click(clickMe);
+      handle.click(clickMe);
+    }
+  };
+
+  /**
+   * Support Drupal's 'behaviors' system for binding.
+   */
+  Drupal.behaviors.CToolsCollapsible = {
+    attach: function(context) {
+      $('.ctools-collapsible-container', context).once('ctools-collapsible', Drupal.CTools.bindCollapsible);
+    }
+  }
+})(jQuery);