##// END OF EJS Templates
Merged r9391 from trunk....
Jean-Philippe Lang -
r9269:4c330a1241aa
parent child
Show More
@@ -1,523 +1,535
1 1 /* Redmine - project management software
2 2 Copyright (C) 2006-2012 Jean-Philippe Lang */
3 3
4 4 function checkAll (id, checked) {
5 5 var els = Element.descendants(id);
6 6 for (var i = 0; i < els.length; i++) {
7 7 if (els[i].disabled==false) {
8 8 els[i].checked = checked;
9 9 }
10 10 }
11 11 }
12 12
13 13 function toggleCheckboxesBySelector(selector) {
14 14 boxes = $$(selector);
15 15 var all_checked = true;
16 16 for (i = 0; i < boxes.length; i++) { if (boxes[i].checked == false) { all_checked = false; } }
17 17 for (i = 0; i < boxes.length; i++) { boxes[i].checked = !all_checked; }
18 18 }
19 19
20 20 function setCheckboxesBySelector(checked, selector) {
21 21 var boxes = $$(selector);
22 22 boxes.each(function(ele) {
23 23 ele.checked = checked;
24 24 });
25 25 }
26 26
27 27 function showAndScrollTo(id, focus) {
28 28 Element.show(id);
29 29 if (focus!=null) { Form.Element.focus(focus); }
30 30 Element.scrollTo(id);
31 31 }
32 32
33 33 function toggleRowGroup(el) {
34 34 var tr = Element.up(el, 'tr');
35 35 var n = Element.next(tr);
36 36 tr.toggleClassName('open');
37 37 while (n != undefined && !n.hasClassName('group')) {
38 38 Element.toggle(n);
39 39 n = Element.next(n);
40 40 }
41 41 }
42 42
43 43 function collapseAllRowGroups(el) {
44 44 var tbody = Element.up(el, 'tbody');
45 45 tbody.childElements('tr').each(function(tr) {
46 46 if (tr.hasClassName('group')) {
47 47 tr.removeClassName('open');
48 48 } else {
49 49 tr.hide();
50 50 }
51 51 })
52 52 }
53 53
54 54 function expandAllRowGroups(el) {
55 55 var tbody = Element.up(el, 'tbody');
56 56 tbody.childElements('tr').each(function(tr) {
57 57 if (tr.hasClassName('group')) {
58 58 tr.addClassName('open');
59 59 } else {
60 60 tr.show();
61 61 }
62 62 })
63 63 }
64 64
65 65 function toggleAllRowGroups(el) {
66 66 var tr = Element.up(el, 'tr');
67 67 if (tr.hasClassName('open')) {
68 68 collapseAllRowGroups(el);
69 69 } else {
70 70 expandAllRowGroups(el);
71 71 }
72 72 }
73 73
74 74 function toggleFieldset(el) {
75 75 var fieldset = Element.up(el, 'fieldset');
76 76 fieldset.toggleClassName('collapsed');
77 77 Effect.toggle(fieldset.down('div'), 'slide', {duration:0.2});
78 78 }
79 79
80 80 function hideFieldset(el) {
81 81 var fieldset = Element.up(el, 'fieldset');
82 82 fieldset.toggleClassName('collapsed');
83 83 fieldset.down('div').hide();
84 84 }
85 85
86 86 function add_filter() {
87 87 select = $('add_filter_select');
88 88 field = select.value
89 89 Element.show('tr_' + field);
90 90 check_box = $('cb_' + field);
91 91 check_box.checked = true;
92 92 toggle_filter(field);
93 93 select.selectedIndex = 0;
94 94
95 95 for (i=0; i<select.options.length; i++) {
96 96 if (select.options[i].value == field) {
97 97 select.options[i].disabled = true;
98 98 }
99 99 }
100 100 }
101 101
102 102 function toggle_filter(field) {
103 103 check_box = $('cb_' + field);
104 104 if (check_box.checked) {
105 105 Element.show("operators_" + field);
106 106 Form.Element.enable("operators_" + field);
107 107 toggle_operator(field);
108 108 } else {
109 109 Element.hide("operators_" + field);
110 110 Form.Element.disable("operators_" + field);
111 111 enableValues(field, []);
112 112 }
113 113 }
114 114
115 115 function enableValues(field, indexes) {
116 116 var f = $$(".values_" + field);
117 117 for(var i=0;i<f.length;i++) {
118 118 if (indexes.include(i)) {
119 119 Form.Element.enable(f[i]);
120 120 f[i].up('span').show();
121 121 } else {
122 122 f[i].value = '';
123 123 Form.Element.disable(f[i]);
124 124 f[i].up('span').hide();
125 125 }
126 126 }
127 127 if (indexes.length > 0) {
128 128 Element.show("div_values_" + field);
129 129 } else {
130 130 Element.hide("div_values_" + field);
131 131 }
132 132 }
133 133
134 134 function toggle_operator(field) {
135 135 operator = $("operators_" + field);
136 136 switch (operator.value) {
137 137 case "!*":
138 138 case "*":
139 139 case "t":
140 140 case "w":
141 141 case "o":
142 142 case "c":
143 143 enableValues(field, []);
144 144 break;
145 145 case "><":
146 146 enableValues(field, [0,1]);
147 147 break;
148 148 case "<t+":
149 149 case ">t+":
150 150 case "t+":
151 151 case ">t-":
152 152 case "<t-":
153 153 case "t-":
154 154 enableValues(field, [2]);
155 155 break;
156 156 default:
157 157 enableValues(field, [0]);
158 158 break;
159 159 }
160 160 }
161 161
162 162 function toggle_multi_select(el) {
163 163 var select = $(el);
164 164 if (select.multiple == true) {
165 165 select.multiple = false;
166 166 } else {
167 167 select.multiple = true;
168 168 }
169 169 }
170 170
171 171 function submit_query_form(id) {
172 172 selectAllOptions("selected_columns");
173 173 $(id).submit();
174 174 }
175 175
176 176 function apply_filters_observer() {
177 177 $$("#query_form input[type=text]").invoke("observe", "keypress", function(e){
178 178 if(e.keyCode == Event.KEY_RETURN) {
179 179 submit_query_form("query_form");
180 180 }
181 181 });
182 182 }
183 183
184 184 var fileFieldCount = 1;
185 185
186 186 function addFileField() {
187 187 var fields = $('attachments_fields');
188 188 if (fields.childElements().length >= 10) return false;
189 189 fileFieldCount++;
190 190 var s = new Element('span');
191 191 s.update(fields.down('span').innerHTML);
192 192 s.down('input.file').name = "attachments[" + fileFieldCount + "][file]";
193 193 s.down('input.description').name = "attachments[" + fileFieldCount + "][description]";
194 194 fields.appendChild(s);
195 195 }
196 196
197 197 function removeFileField(el) {
198 198 var fields = $('attachments_fields');
199 199 var s = Element.up(el, 'span');
200 200 if (fields.childElements().length > 1) {
201 201 s.remove();
202 202 } else {
203 203 s.update(s.innerHTML);
204 204 }
205 205 }
206 206
207 207 function checkFileSize(el, maxSize, message) {
208 208 var files = el.files;
209 209 if (files) {
210 210 for (var i=0; i<files.length; i++) {
211 211 if (files[i].size > maxSize) {
212 212 alert(message);
213 213 el.value = "";
214 214 }
215 215 }
216 216 }
217 217 }
218 218
219 219 function showTab(name) {
220 220 var f = $$('div#content .tab-content');
221 221 for(var i=0; i<f.length; i++){
222 222 Element.hide(f[i]);
223 223 }
224 224 var f = $$('div.tabs a');
225 225 for(var i=0; i<f.length; i++){
226 226 Element.removeClassName(f[i], "selected");
227 227 }
228 228 Element.show('tab-content-' + name);
229 229 Element.addClassName('tab-' + name, "selected");
230 230 return false;
231 231 }
232 232
233 233 function moveTabRight(el) {
234 234 var lis = Element.up(el, 'div.tabs').down('ul').childElements();
235 235 var tabsWidth = 0;
236 236 var i;
237 237 for (i=0; i<lis.length; i++) {
238 238 if (lis[i].visible()) {
239 239 tabsWidth += lis[i].getWidth() + 6;
240 240 }
241 241 }
242 242 if (tabsWidth < Element.up(el, 'div.tabs').getWidth() - 60) {
243 243 return;
244 244 }
245 245 i=0;
246 246 while (i<lis.length && !lis[i].visible()) {
247 247 i++;
248 248 }
249 249 lis[i].hide();
250 250 }
251 251
252 252 function moveTabLeft(el) {
253 253 var lis = Element.up(el, 'div.tabs').down('ul').childElements();
254 254 var i = 0;
255 255 while (i<lis.length && !lis[i].visible()) {
256 256 i++;
257 257 }
258 258 if (i>0) {
259 259 lis[i-1].show();
260 260 }
261 261 }
262 262
263 263 function displayTabsButtons() {
264 264 var lis;
265 265 var tabsWidth = 0;
266 266 var i;
267 267 $$('div.tabs').each(function(el) {
268 268 lis = el.down('ul').childElements();
269 269 for (i=0; i<lis.length; i++) {
270 270 if (lis[i].visible()) {
271 271 tabsWidth += lis[i].getWidth() + 6;
272 272 }
273 273 }
274 274 if ((tabsWidth < el.getWidth() - 60) && (lis[0].visible())) {
275 275 el.down('div.tabs-buttons').hide();
276 276 } else {
277 277 el.down('div.tabs-buttons').show();
278 278 }
279 279 });
280 280 }
281 281
282 282 function setPredecessorFieldsVisibility() {
283 283 relationType = $('relation_relation_type');
284 284 if (relationType && (relationType.value == "precedes" || relationType.value == "follows")) {
285 285 Element.show('predecessor_fields');
286 286 } else {
287 287 Element.hide('predecessor_fields');
288 288 }
289 289 }
290 290
291 291 function promptToRemote(text, param, url) {
292 292 value = prompt(text + ':');
293 293 if (value) {
294 294 new Ajax.Request(url + '?' + param + '=' + encodeURIComponent(value), {asynchronous:true, evalScripts:true});
295 295 return false;
296 296 }
297 297 }
298 298
299 299 function showModal(id, width) {
300 300 el = $(id);
301 301 if (el == undefined || el.visible()) {return;}
302 302 var h = $$('body')[0].getHeight();
303 303 var d = document.createElement("div");
304 304 d.id = 'modalbg';
305 305 $('main').appendChild(d);
306 306 $('modalbg').setStyle({ width: '100%', height: h + 'px' });
307 307 $('modalbg').show();
308 308
309 309 var pageWidth = document.viewport.getWidth();
310 310 if (width) {
311 311 el.setStyle({'width': width});
312 312 }
313 313 el.setStyle({'left': (((pageWidth - el.getWidth())/2 *100) / pageWidth) + '%'});
314 314 el.addClassName('modal');
315 315 el.show();
316 316
317 317 if (el.down("input[type=text]")) {
318 318 el.down("input[type=text]").focus();
319 319 } else if (el.down("input[type=submit]")) {
320 320 el.down("input[type=submit]").focus();
321 321 }
322 322 }
323 323
324 324 function hideModal(el) {
325 325 var modal;
326 326 if (el) {
327 327 modal = Element.up(el, 'div.modal');
328 328 } else {
329 329 modal = $('ajax-modal');
330 330 }
331 331 if (modal) {
332 332 modal.hide();
333 333 }
334 334 var bg = $('modalbg');
335 335 if (bg) {
336 336 bg.remove();
337 337 }
338 338 }
339 339
340 340 function collapseScmEntry(id) {
341 341 var els = document.getElementsByClassName(id, 'browser');
342 342 for (var i = 0; i < els.length; i++) {
343 343 if (els[i].hasClassName('open')) {
344 344 collapseScmEntry(els[i].id);
345 345 }
346 346 Element.hide(els[i]);
347 347 }
348 348 $(id).removeClassName('open');
349 349 }
350 350
351 351 function expandScmEntry(id) {
352 352 var els = document.getElementsByClassName(id, 'browser');
353 353 for (var i = 0; i < els.length; i++) {
354 354 Element.show(els[i]);
355 355 if (els[i].hasClassName('loaded') && !els[i].hasClassName('collapsed')) {
356 356 expandScmEntry(els[i].id);
357 357 }
358 358 }
359 359 $(id).addClassName('open');
360 360 }
361 361
362 362 function scmEntryClick(id) {
363 363 el = $(id);
364 364 if (el.hasClassName('open')) {
365 365 collapseScmEntry(id);
366 366 el.addClassName('collapsed');
367 367 return false;
368 368 } else if (el.hasClassName('loaded')) {
369 369 expandScmEntry(id);
370 370 el.removeClassName('collapsed');
371 371 return false;
372 372 }
373 373 if (el.hasClassName('loading')) {
374 374 return false;
375 375 }
376 376 el.addClassName('loading');
377 377 return true;
378 378 }
379 379
380 380 function scmEntryLoaded(id) {
381 381 Element.addClassName(id, 'open');
382 382 Element.addClassName(id, 'loaded');
383 383 Element.removeClassName(id, 'loading');
384 384 }
385 385
386 386 function randomKey(size) {
387 387 var chars = new Array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z');
388 388 var key = '';
389 389 for (i = 0; i < size; i++) {
390 390 key += chars[Math.floor(Math.random() * chars.length)];
391 391 }
392 392 return key;
393 393 }
394 394
395 395 function observeParentIssueField(url) {
396 396 new Ajax.Autocompleter('issue_parent_issue_id',
397 397 'parent_issue_candidates',
398 398 url,
399 399 { minChars: 3,
400 400 frequency: 0.5,
401 401 paramName: 'q',
402 402 method: 'get',
403 403 updateElement: function(value) {
404 404 document.getElementById('issue_parent_issue_id').value = value.id;
405 405 }});
406 406 }
407 407
408 408 function observeRelatedIssueField(url) {
409 409 new Ajax.Autocompleter('relation_issue_to_id',
410 410 'related_issue_candidates',
411 411 url,
412 412 { minChars: 3,
413 413 frequency: 0.5,
414 414 paramName: 'q',
415 415 method: 'get',
416 416 updateElement: function(value) {
417 417 document.getElementById('relation_issue_to_id').value = value.id;
418 418 },
419 419 parameters: 'scope=all'
420 420 });
421 421 }
422 422
423 423 function setVisible(id, visible) {
424 424 var el = $(id);
425 425 if (el) {if (visible) {el.show();} else {el.hide();}}
426 426 }
427 427
428 428 function observeProjectModules() {
429 429 var f = function() {
430 430 /* Hides trackers and issues custom fields on the new project form when issue_tracking module is disabled */
431 431 var c = ($('project_enabled_module_names_issue_tracking').checked == true);
432 432 setVisible('project_trackers', c);
433 433 setVisible('project_issue_custom_fields', c);
434 434 };
435 435
436 436 Event.observe(window, 'load', f);
437 437 Event.observe('project_enabled_module_names_issue_tracking', 'change', f);
438 438 }
439 439
440 440 /*
441 441 * Class used to warn user when leaving a page with unsaved textarea
442 442 * Author: mathias.fischer@berlinonline.de
443 443 */
444 444
445 445 var WarnLeavingUnsaved = Class.create({
446 446 observedForms: false,
447 447 observedElements: false,
448 448 changedForms: false,
449 449 message: null,
450 450
451 451 initialize: function(message){
452 452 this.observedForms = $$('form');
453 453 this.observedElements = $$('textarea');
454 454 this.message = message;
455 455
456 456 this.observedElements.each(this.observeChange.bind(this));
457 457 this.observedForms.each(this.submitAction.bind(this));
458 458
459 459 window.onbeforeunload = this.unload.bind(this);
460 460 },
461 461
462 462 unload: function(){
463 463 this.observedElements.each(function(el) {el.blur();})
464 464 if(this.changedForms)
465 465 return this.message;
466 466 },
467 467
468 468 setChanged: function(){
469 469 this.changedForms = true;
470 470 },
471 471
472 472 setUnchanged: function(){
473 473 this.changedForms = false;
474 474 },
475 475
476 476 observeChange: function(element){
477 477 element.observe('change',this.setChanged.bindAsEventListener(this));
478 478 },
479 479
480 480 submitAction: function(element){
481 481 element.observe('submit',this.setUnchanged.bindAsEventListener(this));
482 482 }
483 483 });
484 484
485 485 /*
486 486 * 1 - registers a callback which copies the csrf token into the
487 487 * X-CSRF-Token header with each ajax request. Necessary to
488 488 * work with rails applications which have fixed
489 489 * CVE-2011-0447
490 490 * 2 - shows and hides ajax indicator
491 491 */
492 492 Ajax.Responders.register({
493 493 onCreate: function(request){
494 494 var csrf_meta_tag = $$('meta[name=csrf-token]')[0];
495 495
496 496 if (csrf_meta_tag) {
497 497 var header = 'X-CSRF-Token',
498 498 token = csrf_meta_tag.readAttribute('content');
499 499
500 500 if (!request.options.requestHeaders) {
501 501 request.options.requestHeaders = {};
502 502 }
503 503 request.options.requestHeaders[header] = token;
504 504 }
505 505
506 506 if ($('ajax-indicator') && Ajax.activeRequestCount > 0 && $$('input.ajax-loading').size() == 0) {
507 507 Element.show('ajax-indicator');
508 508 }
509 509 },
510 510 onComplete: function(){
511 511 if ($('ajax-indicator') && Ajax.activeRequestCount == 0) {
512 512 Element.hide('ajax-indicator');
513 513 }
514 514 }
515 515 });
516 516
517 517 function hideOnLoad() {
518 518 $$('.hol').each(function(el) {
519 519 el.hide();
520 520 });
521 521 }
522 522
523 function addFormObserversForDoubleSubmit() {
524 $$('form[method=post]').each(function(el) {
525 Event.observe(el, 'submit', function(e) {
526 var form = Event.element(e);
527 form.select('input[type=submit]').each(function(btn) {
528 btn.disable();
529 });
530 });
531 });
532 }
533
523 534 Event.observe(window, 'load', hideOnLoad);
535 Event.observe(window, 'load', addFormObserversForDoubleSubmit);
General Comments 0
You need to be logged in to leave comments. Login now