build
[semainetech_django.git] / project / media / admin_tools / js / jquery / jquery.dashboard.js
1 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
2
3 /**
4 * Dashboard plugin.
5 * This plugin is not yet released, but should be when it will be finished.
6 *
7 * copyright (c) 2010 David Jean Louis <izimobil@gmail.com>
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 * DEALINGS IN THE SOFTWARE.
26 */
27
28 (function($) {
29
30 $.fn.extend({
31 //pass the options variable to the function
32 dashboard: function(options) {
33 //Set the default values, use comma to separate the settings, example:
34 var defaults = {
35 panel_id: 'dashboard-panel',
36 dashboard_id: this.attr('id'),
37 dashboard_module_class: 'dashboard-module',
38 columns: 2,
39 load_preferences_function: false,
40 save_preferences_function: false
41 }
42 var options = $.extend(defaults, options);
43
44 return this.each(function() {
45 // set ids for dashboard modules
46 _initialize($(this), options);
47 // restore positions, must be done *before* columnize
48 _restore_positions($(this), options);
49 // columnize the dashboard modules
50 _columnize($(this), options);
51 // add draggable behaviour
52 _set_draggable($(this), options);
53 // add collapsible behaviour
54 _set_collapsible($(this), options);
55 // add deletable behaviour
56 _set_deletable($(this), options);
57 // add addable behaviour to dashboard panel items
58 _set_addable($(this), options);
59 // restore user preferences
60 _restore_preferences($(this), options);
61 });
62 }
63 });
64
65 var preferences = false;
66
67 var _initialize = function(elt, options) {
68 // load preferences
69 if (preferences === false) {
70 if (options.load_preferences_function) {
71 preferences = options.load_preferences_function(options);
72 } else {
73 var json_str = $.cookie('admin-tools.' + options.dashboard_id);
74 preferences = json_str ? JSON.parse(json_str) : {};
75 }
76 }
77 // set ids if not set
78 elt.children('div[id!=' + options.panel_id +']').each(function(index) {
79 if (!$(this).attr('id')) {
80 $(this).attr('id', 'module_' + index);
81 }
82 });
83 };
84
85 var _restore_positions = function(elt, options) {
86 // restore positions
87 try {
88 var saved_positions = _get_preference(options, 'positions');
89 } catch (e) {
90 return;
91 }
92 var current_positions = _get_positions(elt, options);
93 var new_positions = [];
94
95 for(var v = 0; v < current_positions.length; v++) {
96 new_positions[current_positions[v]] = current_positions[v];
97 }
98
99 for(var i = 0; i < saved_positions.length; i++) {
100 // item id from saved order
101 var id = saved_positions[i];
102 if (id in new_positions) {
103 var item = new_positions[id];
104 var child = elt.children('#'+item);
105 // select the item according to the saved order
106 var saved = elt.children('#'+item);
107 child.remove();
108 elt.append(saved);
109 }
110 }
111 };
112
113 var _columnize = function(elt, options) {
114 var elts = elt.children('div[id!=' + options.panel_id +']');
115 var size = Math.ceil(elts.length / options.columns);
116 var sizes = _get_preference(options, 'columns');
117 var percent = Math.floor(100 / options.columns);
118 var start = 0;
119 var stop = 0;
120 for (var i = 0; i < options.columns; i++) {
121 if (typeof(sizes[i]) == 'undefined') {
122 start = i * size;
123 stop = start + size;
124 } else if (sizes[i] == 0) {
125 elt.append(
126 '<div class="dashboard-column" style="float:left;width:'+percent+'%;"/>'
127 );
128 continue;
129 } else {
130 start = (i == 0) ? 0 : start + sizes[i-1];
131 stop = start + sizes[i];
132 }
133 elts.slice(start, stop).wrapAll(
134 '<div class="dashboard-column" style="float:left;width:'+percent+'%;"/>'
135 );
136 }
137 };
138
139 var _restore_preferences = function(elt, options) {
140 elt.children().children('.disabled').each(function() {
141 _delete_element($(this), options);
142 });
143 if (_get_preference(options, 'disabled')) {
144 $.each(_get_preference(options, 'disabled'), function(k, v) {
145 v ? _delete_element($('#'+k), options) : _add_element($('#'+k), options);
146 });
147 }
148 if (_get_preference(options, 'collapsed')) {
149 $.each(_get_preference(options, 'collapsed'), function(k, v) {
150 if (v) {
151 _toggle_element($('#'+k), options);
152 }
153 });
154 }
155 // if there's no element in the panel, hide it
156 if (!$('#' + options.panel_id).find('li').length) {
157 $('#' + options.panel_id).hide();
158 }
159 };
160
161 var _set_draggable = function(elt, options) {
162 // the dashboard column
163 elt.children('.dashboard-column').sortable({
164 handle: 'h2',
165 items: '.draggable',
166 connectWith: '.dashboard-column',
167 placeholder: 'dashboard-placeholder',
168 forcePlaceholderSize: true,
169 cursor: 'crosshair',
170 opacity: 0.7,
171 update: function() {
172 _set_preference(options, 'positions', false, _get_positions(elt, options));
173 var columns = [];
174 elt.children('.dashboard-column').each(function() {
175 columns.push($(this).children().length);
176 });
177 _set_preference(options, 'columns', false, columns, true);
178 }
179 });
180 };
181
182 var _set_collapsible = function(elt, options) {
183 elt.find('> .dashboard-column > .collapsible > h2').each(function() {
184 $(this).append('<a href="#" class="toggle-icon">Toggle</a>').find('a.toggle-icon').click(function() {
185 var prnt = $(this).parent().parent();
186 _toggle_element(prnt, options, true);
187 });
188 });
189 };
190
191 var _toggle_element = function(elt, options, save_preference) {
192 elt.find('h2 a.toggle-icon').toggleClass('collapsed');
193 elt.children('div').slideToggle();
194 if (save_preference) {
195 _set_preference(options, 'collapsed', elt.attr('id'), elt.find('h2 a.toggle-icon').hasClass('collapsed'), true);
196 }
197 };
198
199 var _set_deletable = function(elt, options) {
200 elt.find('> .dashboard-column > .deletable > h2').each(function() {
201 $(this).append('<a href="#" class="close-icon">Close</a>').find('a.close-icon').click(function() {
202 var prnt = $(this).parent().parent();
203 _delete_element(prnt, options, true);
204 });
205 });
206 };
207
208 var _delete_element = function(elt, options, save_preference) {
209 var existing = $('#'+options.panel_id).find('li a[rel='+elt.attr('id')+']');
210 if (!existing.length) {
211 var panel_ul = $('#' + options.panel_id).find('ul');
212 if (!panel_ul.length) {
213 $('#' + options.panel_id).append('<ul/>');
214 panel_ul = $('#' + options.panel_id).find('ul');
215 }
216 panel_ul.append(
217 '<li><a href="#" rel="'
218 + elt.attr('id')
219 + '" class="addlink dashboard-module-add">'
220 + elt.find('h2').contents().first().text()
221 + '</a></li>'
222 );
223 _set_addable(elt, options, $('#'+options.panel_id).find('li a[rel='+elt.attr('id')+']'));
224 } else {
225 existing.parent().show();
226 }
227 elt.fadeOut('fast');
228 $('#' + options.panel_id).show();
229 if (save_preference) {
230 _set_preference(options, 'disabled', elt.attr('id'), true, true);
231 }
232 };
233
234 var _set_addable = function(elt, options, elts) {
235 if (!elts) {
236 elts = $('#'+options.panel_id).find('li a');
237 }
238 elts.click(function() {
239 _add_element($('#'+$(this).attr('rel')), options, true);
240 });
241 };
242
243 var _add_element = function(elt, options, save_preference) {
244 var panel_elt = $('#'+options.panel_id).find('li a[rel='+elt.attr('id')+']');
245 panel_elt.parent().remove();
246 elt.removeClass('disabled');
247 elt.fadeIn('fast');
248 if (save_preference) {
249 _set_preference(options, 'disabled', elt.attr('id'), false, true);
250 }
251 // if there's no element in the panel, hide it
252 if (!$('#' + options.panel_id).find('li').length) {
253 $('#' + options.panel_id).hide();
254 }
255 };
256
257 var load_preferences = function(options) {
258 if (options.load_preferences_function) {
259 return options.load_preferences_function(options);
260 }
261 if (preferences === false) {
262 var json_str = $.cookie('admin-tools.' + options.dashboard_id);
263 preferences = json_str ? JSON.parse(json_str) : {};
264 }
265 return preferences;
266 }
267
268 var _get_preference = function(options, cat, id, defaultval) {
269 try {
270 if (preferences[cat] == undefined) {
271 preferences[cat] = {};
272 }
273 if (id) {
274 return preferences[cat][id];
275 }
276 return preferences[cat];
277 } catch (e) {
278 return defaultval ? defaultval : null;
279 }
280 };
281
282 // quick hack to ensure that we do not save preferences if they are
283 // not modified...
284 var last_saved_preferences = null;
285
286 var _set_preference = function(options, cat, id, val, save) {
287 try {
288 if (preferences[cat] == undefined) {
289 preferences[cat] = {};
290 }
291 if (id) {
292 preferences[cat][id] = val;
293 } else {
294 preferences[cat] = val;
295 }
296 } catch (e) {
297 }
298 // save preferences
299 if (save && JSON.stringify(preferences) != last_saved_preferences) {
300 if (options.save_preferences_function) {
301 options.save_preferences_function(options, preferences);
302 } else {
303 $.cookie(cookie_name, JSON.stringify(preferences), {expires: 1825});
304 }
305 last_saved_preferences = JSON.stringify(preferences);
306 }
307 };
308
309 var _get_positions = function(elt, options) {
310 var modules = [];
311 if (!elt.children('.dashboard-column').length) {
312 elt.children('div[id!=' + options.panel_id +']').each(function() {
313 modules.push($(this).attr('id'));
314 });
315 } else {
316 elt.children('.dashboard-column').each(function() {
317 $.each($(this).sortable('toArray'), function(index, item) {
318 modules.push(item);
319 });
320 });
321 }
322 return modules;
323 }
324
325 })(jQuery);