##// END OF EJS Templates
Focus the first text input or submit button when showing a modal box....
Jean-Philippe Lang -
r8753:0729ee143bc4
parent child
Show More
@@ -1,522 +1,523
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 var submit = el.down("input[type=submit]");
318 if (submit) {
319 submit.focus();
320 }
317 if (el.down("input[type=text]")) {
318 el.down("input[type=text]").focus();
319 } else if (el.down("input[type=submit]")) {
320 el.down("input[type=submit]").focus();
321 }
321 322 }
322 323
323 324 function hideModal(el) {
324 325 var modal;
325 326 if (el) {
326 327 modal = Element.up(el, 'div.modal');
327 328 } else {
328 329 modal = $('ajax-modal');
329 330 }
330 331 if (modal) {
331 332 modal.hide();
332 333 }
333 334 var bg = $('modalbg');
334 335 if (bg) {
335 336 bg.remove();
336 337 }
337 338 }
338 339
339 340 function collapseScmEntry(id) {
340 341 var els = document.getElementsByClassName(id, 'browser');
341 342 for (var i = 0; i < els.length; i++) {
342 343 if (els[i].hasClassName('open')) {
343 344 collapseScmEntry(els[i].id);
344 345 }
345 346 Element.hide(els[i]);
346 347 }
347 348 $(id).removeClassName('open');
348 349 }
349 350
350 351 function expandScmEntry(id) {
351 352 var els = document.getElementsByClassName(id, 'browser');
352 353 for (var i = 0; i < els.length; i++) {
353 354 Element.show(els[i]);
354 355 if (els[i].hasClassName('loaded') && !els[i].hasClassName('collapsed')) {
355 356 expandScmEntry(els[i].id);
356 357 }
357 358 }
358 359 $(id).addClassName('open');
359 360 }
360 361
361 362 function scmEntryClick(id) {
362 363 el = $(id);
363 364 if (el.hasClassName('open')) {
364 365 collapseScmEntry(id);
365 366 el.addClassName('collapsed');
366 367 return false;
367 368 } else if (el.hasClassName('loaded')) {
368 369 expandScmEntry(id);
369 370 el.removeClassName('collapsed');
370 371 return false;
371 372 }
372 373 if (el.hasClassName('loading')) {
373 374 return false;
374 375 }
375 376 el.addClassName('loading');
376 377 return true;
377 378 }
378 379
379 380 function scmEntryLoaded(id) {
380 381 Element.addClassName(id, 'open');
381 382 Element.addClassName(id, 'loaded');
382 383 Element.removeClassName(id, 'loading');
383 384 }
384 385
385 386 function randomKey(size) {
386 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');
387 388 var key = '';
388 389 for (i = 0; i < size; i++) {
389 390 key += chars[Math.floor(Math.random() * chars.length)];
390 391 }
391 392 return key;
392 393 }
393 394
394 395 function observeParentIssueField(url) {
395 396 new Ajax.Autocompleter('issue_parent_issue_id',
396 397 'parent_issue_candidates',
397 398 url,
398 399 { minChars: 3,
399 400 frequency: 0.5,
400 401 paramName: 'q',
401 402 method: 'get',
402 403 updateElement: function(value) {
403 404 document.getElementById('issue_parent_issue_id').value = value.id;
404 405 }});
405 406 }
406 407
407 408 function observeRelatedIssueField(url) {
408 409 new Ajax.Autocompleter('relation_issue_to_id',
409 410 'related_issue_candidates',
410 411 url,
411 412 { minChars: 3,
412 413 frequency: 0.5,
413 414 paramName: 'q',
414 415 method: 'get',
415 416 updateElement: function(value) {
416 417 document.getElementById('relation_issue_to_id').value = value.id;
417 418 },
418 419 parameters: 'scope=all'
419 420 });
420 421 }
421 422
422 423 function setVisible(id, visible) {
423 424 var el = $(id);
424 425 if (el) {if (visible) {el.show();} else {el.hide();}}
425 426 }
426 427
427 428 function observeProjectModules() {
428 429 var f = function() {
429 430 /* Hides trackers and issues custom fields on the new project form when issue_tracking module is disabled */
430 431 var c = ($('project_enabled_module_names_issue_tracking').checked == true);
431 432 setVisible('project_trackers', c);
432 433 setVisible('project_issue_custom_fields', c);
433 434 };
434 435
435 436 Event.observe(window, 'load', f);
436 437 Event.observe('project_enabled_module_names_issue_tracking', 'change', f);
437 438 }
438 439
439 440 /*
440 441 * Class used to warn user when leaving a page with unsaved textarea
441 442 * Author: mathias.fischer@berlinonline.de
442 443 */
443 444
444 445 var WarnLeavingUnsaved = Class.create({
445 446 observedForms: false,
446 447 observedElements: false,
447 448 changedForms: false,
448 449 message: null,
449 450
450 451 initialize: function(message){
451 452 this.observedForms = $$('form');
452 453 this.observedElements = $$('textarea');
453 454 this.message = message;
454 455
455 456 this.observedElements.each(this.observeChange.bind(this));
456 457 this.observedForms.each(this.submitAction.bind(this));
457 458
458 459 window.onbeforeunload = this.unload.bind(this);
459 460 },
460 461
461 462 unload: function(){
462 463 this.observedElements.each(function(el) {el.blur();})
463 464 if(this.changedForms)
464 465 return this.message;
465 466 },
466 467
467 468 setChanged: function(){
468 469 this.changedForms = true;
469 470 },
470 471
471 472 setUnchanged: function(){
472 473 this.changedForms = false;
473 474 },
474 475
475 476 observeChange: function(element){
476 477 element.observe('change',this.setChanged.bindAsEventListener(this));
477 478 },
478 479
479 480 submitAction: function(element){
480 481 element.observe('submit',this.setUnchanged.bindAsEventListener(this));
481 482 }
482 483 });
483 484
484 485 /*
485 486 * 1 - registers a callback which copies the csrf token into the
486 487 * X-CSRF-Token header with each ajax request. Necessary to
487 488 * work with rails applications which have fixed
488 489 * CVE-2011-0447
489 490 * 2 - shows and hides ajax indicator
490 491 */
491 492 Ajax.Responders.register({
492 493 onCreate: function(request){
493 494 var csrf_meta_tag = $$('meta[name=csrf-token]')[0];
494 495
495 496 if (csrf_meta_tag) {
496 497 var header = 'X-CSRF-Token',
497 498 token = csrf_meta_tag.readAttribute('content');
498 499
499 500 if (!request.options.requestHeaders) {
500 501 request.options.requestHeaders = {};
501 502 }
502 503 request.options.requestHeaders[header] = token;
503 504 }
504 505
505 506 if ($('ajax-indicator') && Ajax.activeRequestCount > 0) {
506 507 Element.show('ajax-indicator');
507 508 }
508 509 },
509 510 onComplete: function(){
510 511 if ($('ajax-indicator') && Ajax.activeRequestCount == 0) {
511 512 Element.hide('ajax-indicator');
512 513 }
513 514 }
514 515 });
515 516
516 517 function hideOnLoad() {
517 518 $$('.hol').each(function(el) {
518 519 el.hide();
519 520 });
520 521 }
521 522
522 523 Event.observe(window, 'load', hideOnLoad);
General Comments 0
You need to be logged in to leave comments. Login now