##// END OF EJS Templates
Merged r10714 from trunk....
Jean-Philippe Lang -
r10511:0f219b973aa2
parent child
Show More
@@ -1,582 +1,582
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 if (checked) {
6 6 $('#'+id).find('input[type=checkbox]').attr('checked', true);
7 7 } else {
8 8 $('#'+id).find('input[type=checkbox]').removeAttr('checked');
9 9 }
10 10 }
11 11
12 12 function toggleCheckboxesBySelector(selector) {
13 13 var all_checked = true;
14 14 $(selector).each(function(index) {
15 15 if (!$(this).is(':checked')) { all_checked = false; }
16 16 });
17 17 $(selector).attr('checked', !all_checked)
18 18 }
19 19
20 20 function showAndScrollTo(id, focus) {
21 21 $('#'+id).show();
22 22 if (focus!=null) {
23 23 $('#'+focus).focus();
24 24 }
25 25 $('html, body').animate({scrollTop: $('#'+id).offset().top}, 100);
26 26 }
27 27
28 28 function toggleRowGroup(el) {
29 29 var tr = $(el).parents('tr').first();
30 30 var n = tr.next();
31 31 tr.toggleClass('open');
32 32 while (n.length && !n.hasClass('group')) {
33 33 n.toggle();
34 34 n = n.next('tr');
35 35 }
36 36 }
37 37
38 38 function collapseAllRowGroups(el) {
39 39 var tbody = $(el).parents('tbody').first();
40 40 tbody.children('tr').each(function(index) {
41 41 if ($(this).hasClass('group')) {
42 42 $(this).removeClass('open');
43 43 } else {
44 44 $(this).hide();
45 45 }
46 46 });
47 47 }
48 48
49 49 function expandAllRowGroups(el) {
50 50 var tbody = $(el).parents('tbody').first();
51 51 tbody.children('tr').each(function(index) {
52 52 if ($(this).hasClass('group')) {
53 53 $(this).addClass('open');
54 54 } else {
55 55 $(this).show();
56 56 }
57 57 });
58 58 }
59 59
60 60 function toggleAllRowGroups(el) {
61 61 var tr = $(el).parents('tr').first();
62 62 if (tr.hasClass('open')) {
63 63 collapseAllRowGroups(el);
64 64 } else {
65 65 expandAllRowGroups(el);
66 66 }
67 67 }
68 68
69 69 function toggleFieldset(el) {
70 70 var fieldset = $(el).parents('fieldset').first();
71 71 fieldset.toggleClass('collapsed');
72 72 fieldset.children('div').toggle();
73 73 }
74 74
75 75 function hideFieldset(el) {
76 76 var fieldset = $(el).parents('fieldset').first();
77 77 fieldset.toggleClass('collapsed');
78 78 fieldset.children('div').hide();
79 79 }
80 80
81 81 function initFilters(){
82 82 $('#add_filter_select').change(function(){
83 83 addFilter($(this).val(), '', []);
84 84 });
85 85 $('#filters-table td.field input[type=checkbox]').each(function(){
86 86 toggleFilter($(this).val());
87 87 });
88 88 $('#filters-table td.field input[type=checkbox]').live('click',function(){
89 89 toggleFilter($(this).val());
90 90 });
91 91 $('#filters-table .toggle-multiselect').live('click',function(){
92 92 toggleMultiSelect($(this).siblings('select'));
93 93 });
94 94 $('#filters-table input[type=text]').live('keypress', function(e){
95 95 if (e.keyCode == 13) submit_query_form("query_form");
96 96 });
97 97 }
98 98
99 99 function addFilter(field, operator, values) {
100 100 var fieldId = field.replace('.', '_');
101 101 var tr = $('#tr_'+fieldId);
102 102 if (tr.length > 0) {
103 103 tr.show();
104 104 } else {
105 105 buildFilterRow(field, operator, values);
106 106 }
107 107 $('#cb_'+fieldId).attr('checked', true);
108 108 toggleFilter(field);
109 109 $('#add_filter_select').val('').children('option').each(function(){
110 110 if ($(this).attr('value') == field) {
111 111 $(this).attr('disabled', true);
112 112 }
113 113 });
114 114 }
115 115
116 116 function buildFilterRow(field, operator, values) {
117 117 var fieldId = field.replace('.', '_');
118 118 var filterTable = $("#filters-table");
119 119 var filterOptions = availableFilters[field];
120 120 var operators = operatorByType[filterOptions['type']];
121 121 var filterValues = filterOptions['values'];
122 122 var i, select;
123 123
124 124 var tr = $('<tr class="filter">').attr('id', 'tr_'+fieldId).html(
125 125 '<td class="field"><input checked="checked" id="cb_'+fieldId+'" name="f[]" value="'+field+'" type="checkbox"><label for="cb_'+fieldId+'"> '+filterOptions['name']+'</label></td>' +
126 126 '<td class="operator"><select id="operators_'+fieldId+'" name="op['+field+']"></td>' +
127 127 '<td class="values"></td>'
128 128 );
129 129 filterTable.append(tr);
130 130
131 131 select = tr.find('td.operator select');
132 132 for (i=0;i<operators.length;i++){
133 133 var option = $('<option>').val(operators[i]).text(operatorLabels[operators[i]]);
134 134 if (operators[i] == operator) {option.attr('selected', true)};
135 135 select.append(option);
136 136 }
137 137 select.change(function(){toggleOperator(field)});
138 138
139 139 switch (filterOptions['type']){
140 140 case "list":
141 141 case "list_optional":
142 142 case "list_status":
143 143 case "list_subprojects":
144 144 tr.find('td.values').append(
145 145 '<span style="display:none;"><select class="value" id="values_'+fieldId+'_1" name="v['+field+'][]"></select>' +
146 146 ' <span class="toggle-multiselect">&nbsp;</span></span>'
147 147 );
148 148 select = tr.find('td.values select');
149 149 if (values.length > 1) {select.attr('multiple', true)};
150 150 for (i=0;i<filterValues.length;i++){
151 151 var filterValue = filterValues[i];
152 152 var option = $('<option>');
153 153 if ($.isArray(filterValue)) {
154 154 option.val(filterValue[1]).text(filterValue[0]);
155 155 if ($.inArray(filterValue[1], values) > -1) {option.attr('selected', true);}
156 156 } else {
157 157 option.val(filterValue).text(filterValue);
158 158 if ($.inArray(filterValue, values) > -1) {option.attr('selected', true);}
159 159 }
160 160 select.append(option);
161 161 }
162 162 break;
163 163 case "date":
164 164 case "date_past":
165 165 tr.find('td.values').append(
166 166 '<span style="display:none;"><input type="text" name="v['+field+'][]" id="values_'+fieldId+'_1" size="10" class="value date_value" /></span>' +
167 167 ' <span style="display:none;"><input type="text" name="v['+field+'][]" id="values_'+fieldId+'_2" size="10" class="value date_value" /></span>' +
168 168 ' <span style="display:none;"><input type="text" name="v['+field+'][]" id="values_'+fieldId+'" size="3" class="value" /> '+labelDayPlural+'</span>'
169 169 );
170 170 $('#values_'+fieldId+'_1').val(values[0]).datepicker(datepickerOptions);
171 171 $('#values_'+fieldId+'_2').val(values[1]).datepicker(datepickerOptions);
172 172 $('#values_'+fieldId).val(values[0]);
173 173 break;
174 174 case "string":
175 175 case "text":
176 176 tr.find('td.values').append(
177 177 '<span style="display:none;"><input type="text" name="v['+field+'][]" id="values_'+fieldId+'" size="30" class="value" /></span>'
178 178 );
179 179 $('#values_'+fieldId).val(values[0]);
180 180 break;
181 181 case "integer":
182 182 case "float":
183 183 tr.find('td.values').append(
184 184 '<span style="display:none;"><input type="text" name="v['+field+'][]" id="values_'+fieldId+'_1" size="6" class="value" /></span>' +
185 185 ' <span style="display:none;"><input type="text" name="v['+field+'][]" id="values_'+fieldId+'_2" size="6" class="value" /></span>'
186 186 );
187 187 $('#values_'+fieldId+'_1').val(values[0]);
188 188 $('#values_'+fieldId+'_2').val(values[1]);
189 189 break;
190 190 }
191 191 }
192 192
193 193 function toggleFilter(field) {
194 194 var fieldId = field.replace('.', '_');
195 195 if ($('#cb_' + fieldId).is(':checked')) {
196 196 $("#operators_" + fieldId).show().removeAttr('disabled');
197 197 toggleOperator(field);
198 198 } else {
199 199 $("#operators_" + fieldId).hide().attr('disabled', true);
200 200 enableValues(field, []);
201 201 }
202 202 }
203 203
204 204 function enableValues(field, indexes) {
205 205 var fieldId = field.replace('.', '_');
206 206 $('#tr_'+fieldId+' td.values .value').each(function(index) {
207 207 if ($.inArray(index, indexes) >= 0) {
208 208 $(this).removeAttr('disabled');
209 209 $(this).parents('span').first().show();
210 210 } else {
211 211 $(this).val('');
212 212 $(this).attr('disabled', true);
213 213 $(this).parents('span').first().hide();
214 214 }
215 215
216 216 if ($(this).hasClass('group')) {
217 217 $(this).addClass('open');
218 218 } else {
219 219 $(this).show();
220 220 }
221 221 });
222 222 }
223 223
224 224 function toggleOperator(field) {
225 225 var fieldId = field.replace('.', '_');
226 226 var operator = $("#operators_" + fieldId);
227 227 switch (operator.val()) {
228 228 case "!*":
229 229 case "*":
230 230 case "t":
231 231 case "w":
232 232 case "o":
233 233 case "c":
234 234 enableValues(field, []);
235 235 break;
236 236 case "><":
237 237 enableValues(field, [0,1]);
238 238 break;
239 239 case "<t+":
240 240 case ">t+":
241 241 case "t+":
242 242 case ">t-":
243 243 case "<t-":
244 244 case "t-":
245 245 enableValues(field, [2]);
246 246 break;
247 247 default:
248 248 enableValues(field, [0]);
249 249 break;
250 250 }
251 251 }
252 252
253 253 function toggleMultiSelect(el) {
254 254 if (el.attr('multiple')) {
255 255 el.removeAttr('multiple');
256 256 } else {
257 257 el.attr('multiple', true);
258 258 }
259 259 }
260 260
261 261 function submit_query_form(id) {
262 262 selectAllOptions("selected_columns");
263 263 $('#'+id).submit();
264 264 }
265 265
266 266 var fileFieldCount = 1;
267 267 function addFileField() {
268 268 var fields = $('#attachments_fields');
269 269 if (fields.children().length >= 10) return false;
270 270 fileFieldCount++;
271 271 var s = fields.children('span').first().clone();
272 272 s.children('input.file').attr('name', "attachments[" + fileFieldCount + "][file]").val('');
273 273 s.children('input.description').attr('name', "attachments[" + fileFieldCount + "][description]").val('');
274 274 fields.append(s);
275 275 }
276 276
277 277 function removeFileField(el) {
278 278 var fields = $('#attachments_fields');
279 279 var s = $(el).parents('span').first();
280 280 if (fields.children().length > 1) {
281 281 s.remove();
282 282 } else {
283 283 s.children('input.file').val('');
284 284 s.children('input.description').val('');
285 285 }
286 286 }
287 287
288 288 function checkFileSize(el, maxSize, message) {
289 289 var files = el.files;
290 290 if (files) {
291 291 for (var i=0; i<files.length; i++) {
292 292 if (files[i].size > maxSize) {
293 293 alert(message);
294 294 el.value = "";
295 295 }
296 296 }
297 297 }
298 298 }
299 299
300 300 function showTab(name) {
301 301 $('div#content .tab-content').hide();
302 302 $('div.tabs a').removeClass('selected');
303 303 $('#tab-content-' + name).show();
304 304 $('#tab-' + name).addClass('selected');
305 305 return false;
306 306 }
307 307
308 308 function moveTabRight(el) {
309 309 var lis = $(el).parents('div.tabs').first().find('ul').children();
310 310 var tabsWidth = 0;
311 311 var i = 0;
312 312 lis.each(function(){
313 313 if ($(this).is(':visible')) {
314 314 tabsWidth += $(this).width() + 6;
315 315 }
316 316 });
317 317 if (tabsWidth < $(el).parents('div.tabs').first().width() - 60) { return; }
318 318 while (i<lis.length && !lis.eq(i).is(':visible')) { i++; }
319 319 lis.eq(i).hide();
320 320 }
321 321
322 322 function moveTabLeft(el) {
323 323 var lis = $(el).parents('div.tabs').first().find('ul').children();
324 324 var i = 0;
325 325 while (i<lis.length && !lis.eq(i).is(':visible')) { i++; }
326 326 if (i>0) {
327 327 lis.eq(i-1).show();
328 328 }
329 329 }
330 330
331 331 function displayTabsButtons() {
332 332 var lis;
333 333 var tabsWidth = 0;
334 334 var el;
335 335 $('div.tabs').each(function() {
336 336 el = $(this);
337 337 lis = el.find('ul').children();
338 338 lis.each(function(){
339 339 if ($(this).is(':visible')) {
340 340 tabsWidth += $(this).width() + 6;
341 341 }
342 342 });
343 343 if ((tabsWidth < el.width() - 60) && (lis.first().is(':visible'))) {
344 344 el.find('div.tabs-buttons').hide();
345 345 } else {
346 346 el.find('div.tabs-buttons').show();
347 347 }
348 348 });
349 349 }
350 350
351 351 function setPredecessorFieldsVisibility() {
352 352 var relationType = $('#relation_relation_type');
353 353 if (relationType.val() == "precedes" || relationType.val() == "follows") {
354 354 $('#predecessor_fields').show();
355 355 } else {
356 356 $('#predecessor_fields').hide();
357 357 }
358 358 }
359 359
360 360 function showModal(id, width) {
361 361 var el = $('#'+id).first();
362 362 if (el.length == 0 || el.is(':visible')) {return;}
363 363 var title = el.find('h3.title').text();
364 364 el.dialog({
365 365 width: width,
366 366 modal: true,
367 367 resizable: false,
368 368 dialogClass: 'modal',
369 369 title: title
370 370 });
371 371 el.find("input[type=text], input[type=submit]").first().focus();
372 372 }
373 373
374 374 function hideModal(el) {
375 375 var modal;
376 376 if (el) {
377 377 modal = $(el).parents('.ui-dialog-content');
378 378 } else {
379 379 modal = $('#ajax-modal');
380 380 }
381 381 modal.dialog("close");
382 382 }
383 383
384 384 function submitPreview(url, form, target) {
385 385 $.ajax({
386 386 url: url,
387 387 type: 'post',
388 388 data: $('#'+form).serialize(),
389 389 success: function(data){
390 390 $('#'+target).html(data);
391 391 }
392 392 });
393 393 }
394 394
395 395 function collapseScmEntry(id) {
396 396 $('.'+id).each(function() {
397 397 if ($(this).hasClass('open')) {
398 398 collapseScmEntry($(this).attr('id'));
399 399 }
400 400 $(this).hide();
401 401 });
402 402 $('#'+id).removeClass('open');
403 403 }
404 404
405 405 function expandScmEntry(id) {
406 406 $('.'+id).each(function() {
407 407 $(this).show();
408 408 if ($(this).hasClass('loaded') && !$(this).hasClass('collapsed')) {
409 409 expandScmEntry($(this).attr('id'));
410 410 }
411 411 });
412 412 $('#'+id).addClass('open');
413 413 }
414 414
415 415 function scmEntryClick(id, url) {
416 416 el = $('#'+id);
417 417 if (el.hasClass('open')) {
418 418 collapseScmEntry(id);
419 419 el.addClass('collapsed');
420 420 return false;
421 421 } else if (el.hasClass('loaded')) {
422 422 expandScmEntry(id);
423 423 el.removeClass('collapsed');
424 424 return false;
425 425 }
426 426 if (el.hasClass('loading')) {
427 427 return false;
428 428 }
429 429 el.addClass('loading');
430 430 $.ajax({
431 431 url: url,
432 432 success: function(data){
433 433 el.after(data);
434 434 el.addClass('open').addClass('loaded').removeClass('loading');
435 435 }
436 436 });
437 437 return true;
438 438 }
439 439
440 440 function randomKey(size) {
441 441 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');
442 442 var key = '';
443 443 for (i = 0; i < size; i++) {
444 444 key += chars[Math.floor(Math.random() * chars.length)];
445 445 }
446 446 return key;
447 447 }
448 448
449 449 // Can't use Rails' remote select because we need the form data
450 450 function updateIssueFrom(url) {
451 451 $.ajax({
452 452 url: url,
453 453 type: 'post',
454 454 data: $('#issue-form').serialize()
455 455 });
456 456 }
457 457
458 458 function updateBulkEditFrom(url) {
459 459 $.ajax({
460 460 url: url,
461 461 type: 'post',
462 462 data: $('#bulk_edit_form').serialize()
463 463 });
464 464 }
465 465
466 466 function observeAutocompleteField(fieldId, url) {
467 467 $('#'+fieldId).autocomplete({
468 468 source: url,
469 minLength: 2,
469 minLength: 2
470 470 });
471 471 }
472 472
473 473 function observeSearchfield(fieldId, targetId, url) {
474 474 $('#'+fieldId).each(function() {
475 475 var $this = $(this);
476 476 $this.attr('data-value-was', $this.val());
477 477 var check = function() {
478 478 var val = $this.val();
479 479 if ($this.attr('data-value-was') != val){
480 480 $this.attr('data-value-was', val);
481 481 $.ajax({
482 482 url: url,
483 483 type: 'get',
484 484 data: {q: $this.val()},
485 485 success: function(data){ $('#'+targetId).html(data); },
486 486 beforeSend: function(){ $this.addClass('ajax-loading'); },
487 487 complete: function(){ $this.removeClass('ajax-loading'); }
488 488 });
489 489 }
490 490 };
491 491 var reset = function() {
492 492 if (timer) {
493 493 clearInterval(timer);
494 494 timer = setInterval(check, 300);
495 495 }
496 496 };
497 497 var timer = setInterval(check, 300);
498 498 $this.bind('keyup click mousemove', reset);
499 499 });
500 500 }
501 501
502 502 function observeProjectModules() {
503 503 var f = function() {
504 504 /* Hides trackers and issues custom fields on the new project form when issue_tracking module is disabled */
505 505 if ($('#project_enabled_module_names_issue_tracking').attr('checked')) {
506 506 $('#project_trackers').show();
507 507 }else{
508 508 $('#project_trackers').hide();
509 509 }
510 510 };
511 511
512 512 $(window).load(f);
513 513 $('#project_enabled_module_names_issue_tracking').change(f);
514 514 }
515 515
516 516 function initMyPageSortable(list, url) {
517 517 $('#list-'+list).sortable({
518 518 connectWith: '.block-receiver',
519 519 tolerance: 'pointer',
520 520 update: function(){
521 521 $.ajax({
522 522 url: url,
523 523 type: 'post',
524 524 data: {'blocks': $.map($('#list-'+list).children(), function(el){return $(el).attr('id');})}
525 525 });
526 526 }
527 527 });
528 528 $("#list-top, #list-left, #list-right").disableSelection();
529 529 }
530 530
531 531 var warnLeavingUnsavedMessage;
532 532 function warnLeavingUnsaved(message) {
533 533 warnLeavingUnsavedMessage = message;
534 534
535 535 $('form').submit(function(){
536 536 $('textarea').removeData('changed');
537 537 });
538 538 $('textarea').change(function(){
539 539 $(this).data('changed', 'changed');
540 540 });
541 541 window.onbeforeunload = function(){
542 542 var warn = false;
543 543 $('textarea').blur().each(function(){
544 544 if ($(this).data('changed')) {
545 545 warn = true;
546 546 }
547 547 });
548 548 if (warn) {return warnLeavingUnsavedMessage;}
549 549 };
550 550 };
551 551
552 552 $(document).ready(function(){
553 553 $('#ajax-indicator').bind('ajaxSend', function(){
554 554 if ($('.ajax-loading').length == 0) {
555 555 $('#ajax-indicator').show();
556 556 }
557 557 });
558 558 $('#ajax-indicator').bind('ajaxStop', function(){
559 559 $('#ajax-indicator').hide();
560 560 });
561 561 });
562 562
563 563 function hideOnLoad() {
564 564 $('.hol').hide();
565 565 }
566 566
567 567 function addFormObserversForDoubleSubmit() {
568 568 $('form[method=post]').each(function() {
569 569 if (!$(this).hasClass('multiple-submit')) {
570 570 $(this).submit(function(form_submission) {
571 571 if ($(form_submission.target).attr('data-submitted')) {
572 572 form_submission.preventDefault();
573 573 } else {
574 574 $(form_submission.target).attr('data-submitted', true);
575 575 }
576 576 });
577 577 }
578 578 });
579 579 }
580 580
581 581 $(document).ready(hideOnLoad);
582 582 $(document).ready(addFormObserversForDoubleSubmit);
General Comments 0
You need to be logged in to leave comments. Login now