comparison public/javascripts/application.js @ 1464:261b3d9a4903 redmine-2.4

Update to Redmine 2.4 branch rev 12663
author Chris Cannam
date Tue, 14 Jan 2014 14:37:42 +0000
parents 433d4f72a19b
children 51364c0cd58f e248c7af89ec
comparison
equal deleted inserted replaced
1296:038ba2d95de8 1464:261b3d9a4903
1 /* Redmine - project management software 1 /* Redmine - project management software
2 Copyright (C) 2006-2012 Jean-Philippe Lang */ 2 Copyright (C) 2006-2013 Jean-Philippe Lang */
3 3
4 function checkAll(id, checked) { 4 function checkAll(id, checked) {
5 if (checked) { 5 $('#'+id).find('input[type=checkbox]:enabled').attr('checked', checked);
6 $('#'+id).find('input[type=checkbox]').attr('checked', true);
7 } else {
8 $('#'+id).find('input[type=checkbox]').removeAttr('checked');
9 }
10 } 6 }
11 7
12 function toggleCheckboxesBySelector(selector) { 8 function toggleCheckboxesBySelector(selector) {
13 var all_checked = true; 9 var all_checked = true;
14 $(selector).each(function(index) { 10 $(selector).each(function(index) {
15 if (!$(this).is(':checked')) { all_checked = false; } 11 if (!$(this).is(':checked')) { all_checked = false; }
16 }); 12 });
17 $(selector).attr('checked', !all_checked) 13 $(selector).attr('checked', !all_checked);
18 } 14 }
19 15
20 function showAndScrollTo(id, focus) { 16 function showAndScrollTo(id, focus) {
21 $('#'+id).show(); 17 $('#'+id).show();
22 if (focus!=null) { 18 if (focus !== null) {
23 $('#'+focus).focus(); 19 $('#'+focus).focus();
24 } 20 }
25 $('html, body').animate({scrollTop: $('#'+id).offset().top}, 100); 21 $('html, body').animate({scrollTop: $('#'+id).offset().top}, 100);
26 } 22 }
27 23
76 var fieldset = $(el).parents('fieldset').first(); 72 var fieldset = $(el).parents('fieldset').first();
77 fieldset.toggleClass('collapsed'); 73 fieldset.toggleClass('collapsed');
78 fieldset.children('div').hide(); 74 fieldset.children('div').hide();
79 } 75 }
80 76
81 function initFilters(){ 77 function initFilters() {
82 $('#add_filter_select').change(function(){ 78 $('#add_filter_select').change(function() {
83 addFilter($(this).val(), '', []); 79 addFilter($(this).val(), '', []);
84 }); 80 });
85 $('#filters-table td.field input[type=checkbox]').each(function(){ 81 $('#filters-table td.field input[type=checkbox]').each(function() {
86 toggleFilter($(this).val()); 82 toggleFilter($(this).val());
87 }); 83 });
88 $('#filters-table td.field input[type=checkbox]').live('click',function(){ 84 $('#filters-table td.field input[type=checkbox]').live('click', function() {
89 toggleFilter($(this).val()); 85 toggleFilter($(this).val());
90 }); 86 });
91 $('#filters-table .toggle-multiselect').live('click',function(){ 87 $('#filters-table .toggle-multiselect').live('click', function() {
92 toggleMultiSelect($(this).siblings('select')); 88 toggleMultiSelect($(this).siblings('select'));
93 }); 89 });
94 $('#filters-table input[type=text]').live('keypress', function(e){ 90 $('#filters-table input[type=text]').live('keypress', function(e) {
95 if (e.keyCode == 13) submit_query_form("query_form"); 91 if (e.keyCode == 13) submit_query_form("query_form");
96 }); 92 });
97 } 93 }
98 94
99 function addFilter(field, operator, values) { 95 function addFilter(field, operator, values) {
104 } else { 100 } else {
105 buildFilterRow(field, operator, values); 101 buildFilterRow(field, operator, values);
106 } 102 }
107 $('#cb_'+fieldId).attr('checked', true); 103 $('#cb_'+fieldId).attr('checked', true);
108 toggleFilter(field); 104 toggleFilter(field);
109 $('#add_filter_select').val('').children('option').each(function(){ 105 $('#add_filter_select').val('').children('option').each(function() {
110 if ($(this).attr('value') == field) { 106 if ($(this).attr('value') == field) {
111 $(this).attr('disabled', true); 107 $(this).attr('disabled', true);
112 } 108 }
113 }); 109 });
114 } 110 }
115 111
116 function buildFilterRow(field, operator, values) { 112 function buildFilterRow(field, operator, values) {
117 var fieldId = field.replace('.', '_'); 113 var fieldId = field.replace('.', '_');
118 var filterTable = $("#filters-table"); 114 var filterTable = $("#filters-table");
119 var filterOptions = availableFilters[field]; 115 var filterOptions = availableFilters[field];
116 if (!filterOptions) return;
120 var operators = operatorByType[filterOptions['type']]; 117 var operators = operatorByType[filterOptions['type']];
121 var filterValues = filterOptions['values']; 118 var filterValues = filterOptions['values'];
122 var i, select; 119 var i, select;
123 120
124 var tr = $('<tr class="filter">').attr('id', 'tr_'+fieldId).html( 121 var tr = $('<tr class="filter">').attr('id', 'tr_'+fieldId).html(
127 '<td class="values"></td>' 124 '<td class="values"></td>'
128 ); 125 );
129 filterTable.append(tr); 126 filterTable.append(tr);
130 127
131 select = tr.find('td.operator select'); 128 select = tr.find('td.operator select');
132 for (i=0;i<operators.length;i++){ 129 for (i = 0; i < operators.length; i++) {
133 var option = $('<option>').val(operators[i]).text(operatorLabels[operators[i]]); 130 var option = $('<option>').val(operators[i]).text(operatorLabels[operators[i]]);
134 if (operators[i] == operator) {option.attr('selected', true)}; 131 if (operators[i] == operator) { option.attr('selected', true); }
135 select.append(option); 132 select.append(option);
136 } 133 }
137 select.change(function(){toggleOperator(field)}); 134 select.change(function(){ toggleOperator(field); });
138 135
139 switch (filterOptions['type']){ 136 switch (filterOptions['type']) {
140 case "list": 137 case "list":
141 case "list_optional": 138 case "list_optional":
142 case "list_status": 139 case "list_status":
143 case "list_subprojects": 140 case "list_subprojects":
144 tr.find('td.values').append( 141 tr.find('td.values').append(
145 '<span style="display:none;"><select class="value" id="values_'+fieldId+'_1" name="v['+field+'][]"></select>' + 142 '<span style="display:none;"><select class="value" id="values_'+fieldId+'_1" name="v['+field+'][]"></select>' +
146 ' <span class="toggle-multiselect">&nbsp;</span></span>' 143 ' <span class="toggle-multiselect">&nbsp;</span></span>'
147 ); 144 );
148 select = tr.find('td.values select'); 145 select = tr.find('td.values select');
149 if (values.length > 1) {select.attr('multiple', true)}; 146 if (values.length > 1) { select.attr('multiple', true); }
150 for (i=0;i<filterValues.length;i++){ 147 for (i = 0; i < filterValues.length; i++) {
151 var filterValue = filterValues[i]; 148 var filterValue = filterValues[i];
152 var option = $('<option>'); 149 var option = $('<option>');
153 if ($.isArray(filterValue)) { 150 if ($.isArray(filterValue)) {
154 option.val(filterValue[1]).text(filterValue[0]); 151 option.val(filterValue[1]).text(filterValue[0]);
155 if ($.inArray(filterValue[1], values) > -1) {option.attr('selected', true);} 152 if ($.inArray(filterValue[1], values) > -1) {option.attr('selected', true);}
183 '<span style="display:none;"><input type="text" name="v['+field+'][]" id="values_'+fieldId+'" size="6" class="value" /></span>' + 180 '<span style="display:none;"><input type="text" name="v['+field+'][]" id="values_'+fieldId+'" size="6" class="value" /></span>' +
184 '<span style="display:none;"><select class="value" name="v['+field+'][]" id="values_'+fieldId+'_1"></select></span>' 181 '<span style="display:none;"><select class="value" name="v['+field+'][]" id="values_'+fieldId+'_1"></select></span>'
185 ); 182 );
186 $('#values_'+fieldId).val(values[0]); 183 $('#values_'+fieldId).val(values[0]);
187 select = tr.find('td.values select'); 184 select = tr.find('td.values select');
188 for (i=0;i<allProjects.length;i++){ 185 for (i = 0; i < allProjects.length; i++) {
189 var filterValue = allProjects[i]; 186 var filterValue = allProjects[i];
190 var option = $('<option>'); 187 var option = $('<option>');
191 option.val(filterValue[1]).text(filterValue[0]); 188 option.val(filterValue[1]).text(filterValue[0]);
192 if (values[0] == filterValue[1]) {option.attr('selected', true)}; 189 if (values[0] == filterValue[1]) { option.attr('selected', true); }
193 select.append(option); 190 select.append(option);
194 } 191 }
195 case "integer": 192 case "integer":
196 case "float": 193 case "float":
197 tr.find('td.values').append( 194 tr.find('td.values').append(
240 var operator = $("#operators_" + fieldId); 237 var operator = $("#operators_" + fieldId);
241 switch (operator.val()) { 238 switch (operator.val()) {
242 case "!*": 239 case "!*":
243 case "*": 240 case "*":
244 case "t": 241 case "t":
242 case "ld":
245 case "w": 243 case "w":
244 case "lw":
245 case "l2w":
246 case "m":
247 case "lm":
248 case "y":
246 case "o": 249 case "o":
247 case "c": 250 case "c":
248 enableValues(field, []); 251 enableValues(field, []);
249 break; 252 break;
250 case "><": 253 case "><":
272 } 275 }
273 276
274 function toggleMultiSelect(el) { 277 function toggleMultiSelect(el) {
275 if (el.attr('multiple')) { 278 if (el.attr('multiple')) {
276 el.removeAttr('multiple'); 279 el.removeAttr('multiple');
280 el.attr('size', 1);
277 } else { 281 } else {
278 el.attr('multiple', true); 282 el.attr('multiple', true);
283 if (el.children().length > 10)
284 el.attr('size', 10);
285 else
286 el.attr('size', 4);
279 } 287 }
280 } 288 }
281 289
282 function submit_query_form(id) { 290 function submit_query_form(id) {
283 selectAllOptions("selected_columns"); 291 selectAllOptions("selected_columns");
284 $('#'+id).submit(); 292 $('#'+id).submit();
285 } 293 }
286 294
287 var fileFieldCount = 1; 295 function showTab(name, url) {
288 function addFileField() {
289 var fields = $('#attachments_fields');
290 if (fields.children().length >= 10) return false;
291 fileFieldCount++;
292 var s = fields.children('span').first().clone();
293 s.children('input.file').attr('name', "attachments[" + fileFieldCount + "][file]").val('');
294 s.children('input.description').attr('name', "attachments[" + fileFieldCount + "][description]").val('');
295 fields.append(s);
296 }
297
298 function removeFileField(el) {
299 var fields = $('#attachments_fields');
300 var s = $(el).parents('span').first();
301 if (fields.children().length > 1) {
302 s.remove();
303 } else {
304 s.children('input.file').val('');
305 s.children('input.description').val('');
306 }
307 }
308
309 function checkFileSize(el, maxSize, message) {
310 var files = el.files;
311 if (files) {
312 for (var i=0; i<files.length; i++) {
313 if (files[i].size > maxSize) {
314 alert(message);
315 el.value = "";
316 }
317 }
318 }
319 }
320
321 function showTab(name) {
322 $('div#content .tab-content').hide(); 296 $('div#content .tab-content').hide();
323 $('div.tabs a').removeClass('selected'); 297 $('div.tabs a').removeClass('selected');
324 $('#tab-content-' + name).show(); 298 $('#tab-content-' + name).show();
325 $('#tab-' + name).addClass('selected'); 299 $('#tab-' + name).addClass('selected');
300 //replaces current URL with the "href" attribute of the current link
301 //(only triggered if supported by browser)
302 if ("replaceState" in window.history) {
303 window.history.replaceState(null, document.title, url);
304 }
326 return false; 305 return false;
327 } 306 }
328 307
329 function moveTabRight(el) { 308 function moveTabRight(el) {
330 var lis = $(el).parents('div.tabs').first().find('ul').children(); 309 var lis = $(el).parents('div.tabs').first().find('ul').children();
331 var tabsWidth = 0; 310 var tabsWidth = 0;
332 var i = 0; 311 var i = 0;
333 lis.each(function(){ 312 lis.each(function() {
334 if ($(this).is(':visible')) { 313 if ($(this).is(':visible')) {
335 tabsWidth += $(this).width() + 6; 314 tabsWidth += $(this).width() + 6;
336 } 315 }
337 }); 316 });
338 if (tabsWidth < $(el).parents('div.tabs').first().width() - 60) { return; } 317 if (tabsWidth < $(el).parents('div.tabs').first().width() - 60) { return; }
341 } 320 }
342 321
343 function moveTabLeft(el) { 322 function moveTabLeft(el) {
344 var lis = $(el).parents('div.tabs').first().find('ul').children(); 323 var lis = $(el).parents('div.tabs').first().find('ul').children();
345 var i = 0; 324 var i = 0;
346 while (i<lis.length && !lis.eq(i).is(':visible')) { i++; } 325 while (i < lis.length && !lis.eq(i).is(':visible')) { i++; }
347 if (i>0) { 326 if (i > 0) {
348 lis.eq(i-1).show(); 327 lis.eq(i-1).show();
349 } 328 }
350 } 329 }
351 330
352 function displayTabsButtons() { 331 function displayTabsButtons() {
378 } 357 }
379 } 358 }
380 359
381 function showModal(id, width) { 360 function showModal(id, width) {
382 var el = $('#'+id).first(); 361 var el = $('#'+id).first();
383 if (el.length == 0 || el.is(':visible')) {return;} 362 if (el.length === 0 || el.is(':visible')) {return;}
384 var title = el.find('h3.title').text(); 363 var title = el.find('h3.title').text();
385 el.dialog({ 364 el.dialog({
386 width: width, 365 width: width,
387 modal: true, 366 modal: true,
388 resizable: false, 367 resizable: false,
432 }); 411 });
433 $('#'+id).addClass('open'); 412 $('#'+id).addClass('open');
434 } 413 }
435 414
436 function scmEntryClick(id, url) { 415 function scmEntryClick(id, url) {
437 el = $('#'+id); 416 var el = $('#'+id);
438 if (el.hasClass('open')) { 417 if (el.hasClass('open')) {
439 collapseScmEntry(id); 418 collapseScmEntry(id);
440 el.addClass('collapsed'); 419 el.addClass('collapsed');
441 return false; 420 return false;
442 } else if (el.hasClass('loaded')) { 421 } else if (el.hasClass('loaded')) {
448 return false; 427 return false;
449 } 428 }
450 el.addClass('loading'); 429 el.addClass('loading');
451 $.ajax({ 430 $.ajax({
452 url: url, 431 url: url,
453 success: function(data){ 432 success: function(data) {
454 el.after(data); 433 el.after(data);
455 el.addClass('open').addClass('loaded').removeClass('loading'); 434 el.addClass('open').addClass('loaded').removeClass('loading');
456 } 435 }
457 }); 436 });
458 return true; 437 return true;
459 } 438 }
460 439
461 function randomKey(size) { 440 function randomKey(size) {
462 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'); 441 var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
463 var key = ''; 442 var key = '';
464 for (i = 0; i < size; i++) { 443 for (var i = 0; i < size; i++) {
465 key += chars[Math.floor(Math.random() * chars.length)]; 444 key += chars.charAt(Math.floor(Math.random() * chars.length));
466 } 445 }
467 return key; 446 return key;
468 } 447 }
469 448
470 // Can't use Rails' remote select because we need the form data
471 function updateIssueFrom(url) { 449 function updateIssueFrom(url) {
450 $('#all_attributes input, #all_attributes textarea, #all_attributes select').each(function(){
451 $(this).data('valuebeforeupdate', $(this).val());
452 });
472 $.ajax({ 453 $.ajax({
473 url: url, 454 url: url,
474 type: 'post', 455 type: 'post',
475 data: $('#issue-form').serialize() 456 data: $('#issue-form').serialize()
476 }); 457 });
458 }
459
460 function replaceIssueFormWith(html){
461 var replacement = $(html);
462 $('#all_attributes input, #all_attributes textarea, #all_attributes select').each(function(){
463 var object_id = $(this).attr('id');
464 if (object_id && $(this).data('valuebeforeupdate')!=$(this).val()) {
465 replacement.find('#'+object_id).val($(this).val());
466 }
467 });
468 $('#all_attributes').empty();
469 $('#all_attributes').prepend(replacement);
477 } 470 }
478 471
479 function updateBulkEditFrom(url) { 472 function updateBulkEditFrom(url) {
480 $.ajax({ 473 $.ajax({
481 url: url, 474 url: url,
482 type: 'post', 475 type: 'post',
483 data: $('#bulk_edit_form').serialize() 476 data: $('#bulk_edit_form').serialize()
484 }); 477 });
485 } 478 }
486 479
487 function observeAutocompleteField(fieldId, url) { 480 function observeAutocompleteField(fieldId, url, options) {
488 $(document).ready(function() { 481 $(document).ready(function() {
489 $('#'+fieldId).autocomplete({ 482 $('#'+fieldId).autocomplete($.extend({
490 source: url, 483 source: url,
491 minLength: 2 484 minLength: 2,
492 }); 485 search: function(){$('#'+fieldId).addClass('ajax-loading');},
486 response: function(){$('#'+fieldId).removeClass('ajax-loading');}
487 }, options));
488 $('#'+fieldId).addClass('autocomplete');
493 }); 489 });
494 } 490 }
495 491
496 function observeSearchfield(fieldId, targetId, url) { 492 function observeSearchfield(fieldId, targetId, url) {
497 $('#'+fieldId).each(function() { 493 $('#'+fieldId).each(function() {
498 var $this = $(this); 494 var $this = $(this);
495 $this.addClass('autocomplete');
499 $this.attr('data-value-was', $this.val()); 496 $this.attr('data-value-was', $this.val());
500 var check = function() { 497 var check = function() {
501 var val = $this.val(); 498 var val = $this.val();
502 if ($this.attr('data-value-was') != val){ 499 if ($this.attr('data-value-was') != val){
503 $this.attr('data-value-was', val); 500 $this.attr('data-value-was', val);
504 $.ajax({ 501 $.ajax({
505 url: url, 502 url: url,
506 type: 'get', 503 type: 'get',
507 data: {q: $this.val()}, 504 data: {q: $this.val()},
508 success: function(data){ $('#'+targetId).html(data); }, 505 success: function(data){ if(targetId) $('#'+targetId).html(data); },
509 beforeSend: function(){ $this.addClass('ajax-loading'); }, 506 beforeSend: function(){ $this.addClass('ajax-loading'); },
510 complete: function(){ $this.removeClass('ajax-loading'); } 507 complete: function(){ $this.removeClass('ajax-loading'); }
511 }); 508 });
512 } 509 }
513 }; 510 };
520 var timer = setInterval(check, 300); 517 var timer = setInterval(check, 300);
521 $this.bind('keyup click mousemove', reset); 518 $this.bind('keyup click mousemove', reset);
522 }); 519 });
523 } 520 }
524 521
525 function observeProjectModules() {
526 var f = function() {
527 /* Hides trackers and issues custom fields on the new project form when issue_tracking module is disabled */
528 if ($('#project_enabled_module_names_issue_tracking').attr('checked')) {
529 $('#project_trackers').show();
530 }else{
531 $('#project_trackers').hide();
532 }
533 };
534
535 $(window).load(f);
536 $('#project_enabled_module_names_issue_tracking').change(f);
537 }
538
539 function initMyPageSortable(list, url) { 522 function initMyPageSortable(list, url) {
540 $('#list-'+list).sortable({ 523 $('#list-'+list).sortable({
541 connectWith: '.block-receiver', 524 connectWith: '.block-receiver',
542 tolerance: 'pointer', 525 tolerance: 'pointer',
543 update: function(){ 526 update: function(){
552 } 535 }
553 536
554 var warnLeavingUnsavedMessage; 537 var warnLeavingUnsavedMessage;
555 function warnLeavingUnsaved(message) { 538 function warnLeavingUnsaved(message) {
556 warnLeavingUnsavedMessage = message; 539 warnLeavingUnsavedMessage = message;
557 540 $('form').live('submit', function(){
558 $('form').submit(function(){
559 $('textarea').removeData('changed'); 541 $('textarea').removeData('changed');
560 }); 542 });
561 $('textarea').change(function(){ 543 $('textarea').live('change', function(){
562 $(this).data('changed', 'changed'); 544 $(this).data('changed', 'changed');
563 }); 545 });
564 window.onbeforeunload = function(){ 546 window.onbeforeunload = function(){
565 var warn = false; 547 var warn = false;
566 $('textarea').blur().each(function(){ 548 $('textarea').blur().each(function(){
568 warn = true; 550 warn = true;
569 } 551 }
570 }); 552 });
571 if (warn) {return warnLeavingUnsavedMessage;} 553 if (warn) {return warnLeavingUnsavedMessage;}
572 }; 554 };
573 }; 555 }
574 556
575 $(document).ready(function(){ 557 function setupAjaxIndicator() {
576 $('#ajax-indicator').bind('ajaxSend', function(){ 558 $('#ajax-indicator').bind('ajaxSend', function(event, xhr, settings) {
577 if ($('.ajax-loading').length == 0) { 559 if ($('.ajax-loading').length === 0 && settings.contentType != 'application/octet-stream') {
578 $('#ajax-indicator').show(); 560 $('#ajax-indicator').show();
579 } 561 }
580 }); 562 });
581 $('#ajax-indicator').bind('ajaxStop', function(){ 563 $('#ajax-indicator').bind('ajaxStop', function() {
582 $('#ajax-indicator').hide(); 564 $('#ajax-indicator').hide();
583 }); 565 });
584 }); 566 }
585 567
586 function hideOnLoad() { 568 function hideOnLoad() {
587 $('.hol').hide(); 569 $('.hol').hide();
588 } 570 }
589 571
599 }); 581 });
600 } 582 }
601 }); 583 });
602 } 584 }
603 585
586 function blockEventPropagation(event) {
587 event.stopPropagation();
588 event.preventDefault();
589 }
590
591 $(document).ready(setupAjaxIndicator);
604 $(document).ready(hideOnLoad); 592 $(document).ready(hideOnLoad);
605 $(document).ready(addFormObserversForDoubleSubmit); 593 $(document).ready(addFormObserversForDoubleSubmit);