root / htmltest / sites / all / modules / ctools / js / collapsible-div.js @ a5572547
1 |
/**
|
---|---|
2 |
* @file
|
3 |
* Javascript required for a simple collapsible div.
|
4 |
*
|
5 |
* Creating a collapsible div with this doesn't take too much. There are
|
6 |
* three classes necessary:
|
7 |
*
|
8 |
* - ctools-collapsible-container: This is the overall container that will be
|
9 |
* collapsible. This must be a div.
|
10 |
* - ctools-collapsible-handle: This is the title area, and is what will be
|
11 |
* visible when it is collapsed. This can be any block element, such as div
|
12 |
* or h2.
|
13 |
* - ctools-collapsible-content: This is the ocntent area and will only be
|
14 |
* visible when expanded. This must be a div.
|
15 |
*
|
16 |
* Adding 'ctools-collapsible-remember' to the container class will cause the
|
17 |
* state of the container to be stored in a cookie, and remembered from page
|
18 |
* load to page load. This will only work if the container has a unique ID, so
|
19 |
* very carefully add IDs to your containers.
|
20 |
*
|
21 |
* If the class 'ctools-no-container' is placed on the container, the container
|
22 |
* will be the handle. The content will be found by appending '-content' to the
|
23 |
* id of the handle. The ctools-collapsible-handle and
|
24 |
* ctools-collapsible-content classes will not be required in that case, and no
|
25 |
* restrictions on what of data the container is are placed. Like
|
26 |
* ctools-collapsible-remember this requires an id to eist.
|
27 |
*
|
28 |
* The content will be 'open' unless the container class has 'ctools-collapsed'
|
29 |
* as a class, which will cause the container to draw collapsed.
|
30 |
*/
|
31 |
|
32 |
(function ($) { |
33 |
// All CTools tools begin with this if they need to use the CTools namespace.
|
34 |
if (!Drupal.CTools) {
|
35 |
Drupal.CTools = {}; |
36 |
} |
37 |
|
38 |
/**
|
39 |
* Object to store state.
|
40 |
*
|
41 |
* This object will remember the state of collapsible containers. The first
|
42 |
* time a state is requested, it will check the cookie and set up the variable.
|
43 |
* If a state has been changed, when the window is unloaded the state will be
|
44 |
* saved.
|
45 |
*/
|
46 |
Drupal.CTools.Collapsible = { |
47 |
state: {},
|
48 |
stateLoaded: false, |
49 |
stateChanged: false, |
50 |
cookieString: 'ctools-collapsible-state=', |
51 |
|
52 |
/**
|
53 |
* Get the current collapsed state of a container.
|
54 |
*
|
55 |
* If set to 1, the container is open. If set to -1, the container is
|
56 |
* collapsed. If unset the state is unknown, and the default state should
|
57 |
* be used.
|
58 |
*/
|
59 |
getState: function (id) { |
60 |
if (!this.stateLoaded) { |
61 |
this.loadCookie();
|
62 |
} |
63 |
|
64 |
return this.state[id]; |
65 |
}, |
66 |
|
67 |
/**
|
68 |
* Set the collapsed state of a container for subsequent page loads.
|
69 |
*
|
70 |
* Set the state to 1 for open, -1 for collapsed.
|
71 |
*/
|
72 |
setState: function (id, state) { |
73 |
if (!this.stateLoaded) { |
74 |
this.loadCookie();
|
75 |
} |
76 |
|
77 |
this.state[id] = state;
|
78 |
|
79 |
if (!this.stateChanged) { |
80 |
this.stateChanged = true; |
81 |
$(window).unload(this.unload); |
82 |
} |
83 |
}, |
84 |
|
85 |
/**
|
86 |
* Check the cookie and load the state variable.
|
87 |
*/
|
88 |
loadCookie: function () { |
89 |
// If there is a previous instance of this cookie
|
90 |
if (document.cookie.length > 0) { |
91 |
// Get the number of characters that have the list of values
|
92 |
// from our string index.
|
93 |
offset = document.cookie.indexOf(this.cookieString);
|
94 |
|
95 |
// If its positive, there is a list!
|
96 |
if (offset != -1) { |
97 |
offset += this.cookieString.length;
|
98 |
var end = document.cookie.indexOf(';', offset); |
99 |
if (end == -1) { |
100 |
end = document.cookie.length; |
101 |
} |
102 |
|
103 |
// Get a list of all values that are saved on our string
|
104 |
var cookie = unescape(document.cookie.substring(offset, end));
|
105 |
|
106 |
if (cookie != '') { |
107 |
var cookieList = cookie.split(','); |
108 |
for (var i = 0; i < cookieList.length; i++) { |
109 |
var info = cookieList[i].split(':'); |
110 |
this.state[info[0]] = info[1]; |
111 |
} |
112 |
} |
113 |
} |
114 |
} |
115 |
|
116 |
this.stateLoaded = true; |
117 |
}, |
118 |
|
119 |
/**
|
120 |
* Turn the state variable into a string and store it in the cookie.
|
121 |
*/
|
122 |
storeCookie: function () { |
123 |
var cookie = ''; |
124 |
|
125 |
// Get a list of IDs, saparated by comma
|
126 |
for (i in this.state) { |
127 |
if (cookie != '') { |
128 |
cookie += ',';
|
129 |
} |
130 |
cookie += i + ':' + this.state[i]; |
131 |
} |
132 |
|
133 |
// Save this values on the cookie
|
134 |
document.cookie = this.cookieString + escape(cookie) + ';path=/'; |
135 |
}, |
136 |
|
137 |
/**
|
138 |
* Respond to the unload event by storing the current state.
|
139 |
*/
|
140 |
unload: function() { |
141 |
Drupal.CTools.Collapsible.storeCookie(); |
142 |
} |
143 |
}; |
144 |
|
145 |
// Set up an array for callbacks.
|
146 |
Drupal.CTools.CollapsibleCallbacks = []; |
147 |
Drupal.CTools.CollapsibleCallbacksAfterToggle = []; |
148 |
|
149 |
/**
|
150 |
* Bind collapsible behavior to a given container.
|
151 |
*/
|
152 |
Drupal.CTools.bindCollapsible = function () { |
153 |
var $container = $(this); |
154 |
|
155 |
// Allow the specification of the 'no container' class, which means the
|
156 |
// handle and the container can be completely independent.
|
157 |
if ($container.hasClass('ctools-no-container') && $container.attr('id')) { |
158 |
// In this case, the container *is* the handle and the content is found
|
159 |
// by adding '-content' to the id. Obviously, an id is required.
|
160 |
var handle = $container; |
161 |
var content = $('#' + $container.attr('id') + '-content'); |
162 |
} |
163 |
else {
|
164 |
var handle = $container.children('.ctools-collapsible-handle'); |
165 |
var content = $container.children('div.ctools-collapsible-content'); |
166 |
} |
167 |
|
168 |
if (content.length) {
|
169 |
// Create the toggle item and place it in front of the toggle.
|
170 |
var toggle = $('<span class="ctools-toggle"></span>'); |
171 |
handle.before(toggle); |
172 |
|
173 |
// If the remember class is set, check to see if we have a remembered
|
174 |
// state stored.
|
175 |
if ($container.hasClass('ctools-collapsible-remember') && $container.attr('id')) { |
176 |
var state = Drupal.CTools.Collapsible.getState($container.attr('id')); |
177 |
if (state == 1) { |
178 |
$container.removeClass('ctools-collapsed'); |
179 |
} |
180 |
else if (state == -1) { |
181 |
$container.addClass('ctools-collapsed'); |
182 |
} |
183 |
} |
184 |
|
185 |
// If we should start collapsed, do so:
|
186 |
if ($container.hasClass('ctools-collapsed')) { |
187 |
toggle.toggleClass('ctools-toggle-collapsed');
|
188 |
content.hide(); |
189 |
} |
190 |
|
191 |
var afterToggle = function () { |
192 |
if (Drupal.CTools.CollapsibleCallbacksAfterToggle) {
|
193 |
for (i in Drupal.CTools.CollapsibleCallbacksAfterToggle) { |
194 |
Drupal.CTools.CollapsibleCallbacksAfterToggle[i]($container, handle, content, toggle);
|
195 |
} |
196 |
} |
197 |
} |
198 |
|
199 |
var clickMe = function () { |
200 |
if (Drupal.CTools.CollapsibleCallbacks) {
|
201 |
for (i in Drupal.CTools.CollapsibleCallbacks) { |
202 |
Drupal.CTools.CollapsibleCallbacks[i]($container, handle, content, toggle);
|
203 |
} |
204 |
} |
205 |
|
206 |
// If the container is a table element slideToggle does not do what
|
207 |
// we want, so use toggle() instead.
|
208 |
if ($container.is('table')) { |
209 |
content.toggle(0, afterToggle);
|
210 |
} |
211 |
else {
|
212 |
content.slideToggle(100, afterToggle);
|
213 |
} |
214 |
|
215 |
toggle.toggleClass('ctools-toggle-collapsed');
|
216 |
|
217 |
// If we're supposed to remember the state of this class, do so.
|
218 |
if ($container.hasClass('ctools-collapsible-remember') && $container.attr('id')) { |
219 |
var state = toggle.hasClass('ctools-toggle-collapsed') ? -1 : 1; |
220 |
Drupal.CTools.Collapsible.setState($container.attr('id'), state); |
221 |
} |
222 |
|
223 |
return false; |
224 |
} |
225 |
|
226 |
// Let both the toggle and the handle be clickable.
|
227 |
toggle.click(clickMe); |
228 |
handle.click(clickMe); |
229 |
} |
230 |
}; |
231 |
|
232 |
/**
|
233 |
* Support Drupal's 'behaviors' system for binding.
|
234 |
*/
|
235 |
Drupal.behaviors.CToolsCollapsible = { |
236 |
attach: function(context) { |
237 |
$('.ctools-collapsible-container', context).once('ctools-collapsible', Drupal.CTools.bindCollapsible); |
238 |
} |
239 |
} |
240 |
})(jQuery); |