Mercurial > hg > soundsoftware-site
comparison public/javascripts/application.js @ 1115:433d4f72a19b redmine-2.2
Update to Redmine SVN revision 11137 on 2.2-stable branch
author | Chris Cannam |
---|---|
date | Mon, 07 Jan 2013 12:01:42 +0000 |
parents | cbb26bc654de |
children | bb32da3bea34 622f24f53b42 261b3d9a4903 |
comparison
equal
deleted
inserted
replaced
929:5f33065ddc4b | 1115:433d4f72a19b |
---|---|
1 /* redMine - project management software | 1 /* Redmine - project management software |
2 Copyright (C) 2006-2008 Jean-Philippe Lang */ | 2 Copyright (C) 2006-2012 Jean-Philippe Lang */ |
3 | 3 |
4 function checkAll (id, checked) { | 4 function checkAll(id, checked) { |
5 var els = Element.descendants(id); | 5 if (checked) { |
6 for (var i = 0; i < els.length; i++) { | 6 $('#'+id).find('input[type=checkbox]').attr('checked', true); |
7 if (els[i].disabled==false) { | 7 } else { |
8 els[i].checked = checked; | 8 $('#'+id).find('input[type=checkbox]').removeAttr('checked'); |
9 } | 9 } |
10 } | |
11 } | 10 } |
12 | 11 |
13 function toggleCheckboxesBySelector(selector) { | 12 function toggleCheckboxesBySelector(selector) { |
14 boxes = $$(selector); | 13 var all_checked = true; |
15 var all_checked = true; | 14 $(selector).each(function(index) { |
16 for (i = 0; i < boxes.length; i++) { if (boxes[i].checked == false) { all_checked = false; } } | 15 if (!$(this).is(':checked')) { all_checked = false; } |
17 for (i = 0; i < boxes.length; i++) { boxes[i].checked = !all_checked; } | 16 }); |
18 } | 17 $(selector).attr('checked', !all_checked) |
19 | |
20 function setCheckboxesBySelector(checked, selector) { | |
21 var boxes = $$(selector); | |
22 boxes.each(function(ele) { | |
23 ele.checked = checked; | |
24 }); | |
25 } | 18 } |
26 | 19 |
27 function showAndScrollTo(id, focus) { | 20 function showAndScrollTo(id, focus) { |
28 Element.show(id); | 21 $('#'+id).show(); |
29 if (focus!=null) { Form.Element.focus(focus); } | 22 if (focus!=null) { |
30 Element.scrollTo(id); | 23 $('#'+focus).focus(); |
24 } | |
25 $('html, body').animate({scrollTop: $('#'+id).offset().top}, 100); | |
31 } | 26 } |
32 | 27 |
33 function toggleRowGroup(el) { | 28 function toggleRowGroup(el) { |
34 var tr = Element.up(el, 'tr'); | 29 var tr = $(el).parents('tr').first(); |
35 var n = Element.next(tr); | 30 var n = tr.next(); |
36 tr.toggleClassName('open'); | 31 tr.toggleClass('open'); |
37 while (n != undefined && !n.hasClassName('group')) { | 32 while (n.length && !n.hasClass('group')) { |
38 Element.toggle(n); | 33 n.toggle(); |
39 n = Element.next(n); | 34 n = n.next('tr'); |
40 } | 35 } |
41 } | 36 } |
42 | 37 |
43 function collapseAllRowGroups(el) { | 38 function collapseAllRowGroups(el) { |
44 var tbody = Element.up(el, 'tbody'); | 39 var tbody = $(el).parents('tbody').first(); |
45 tbody.childElements('tr').each(function(tr) { | 40 tbody.children('tr').each(function(index) { |
46 if (tr.hasClassName('group')) { | 41 if ($(this).hasClass('group')) { |
47 tr.removeClassName('open'); | 42 $(this).removeClass('open'); |
48 } else { | 43 } else { |
49 tr.hide(); | 44 $(this).hide(); |
50 } | 45 } |
51 }) | 46 }); |
52 } | 47 } |
53 | 48 |
54 function expandAllRowGroups(el) { | 49 function expandAllRowGroups(el) { |
55 var tbody = Element.up(el, 'tbody'); | 50 var tbody = $(el).parents('tbody').first(); |
56 tbody.childElements('tr').each(function(tr) { | 51 tbody.children('tr').each(function(index) { |
57 if (tr.hasClassName('group')) { | 52 if ($(this).hasClass('group')) { |
58 tr.addClassName('open'); | 53 $(this).addClass('open'); |
59 } else { | 54 } else { |
60 tr.show(); | 55 $(this).show(); |
61 } | 56 } |
62 }) | 57 }); |
63 } | 58 } |
64 | 59 |
65 function toggleAllRowGroups(el) { | 60 function toggleAllRowGroups(el) { |
66 var tr = Element.up(el, 'tr'); | 61 var tr = $(el).parents('tr').first(); |
67 if (tr.hasClassName('open')) { | 62 if (tr.hasClass('open')) { |
68 collapseAllRowGroups(el); | 63 collapseAllRowGroups(el); |
69 } else { | 64 } else { |
70 expandAllRowGroups(el); | 65 expandAllRowGroups(el); |
71 } | 66 } |
72 } | 67 } |
73 | 68 |
74 function toggleFieldset(el) { | 69 function toggleFieldset(el) { |
75 var fieldset = Element.up(el, 'fieldset'); | 70 var fieldset = $(el).parents('fieldset').first(); |
76 fieldset.toggleClassName('collapsed'); | 71 fieldset.toggleClass('collapsed'); |
77 Effect.toggle(fieldset.down('div'), 'slide', {duration:0.2}); | 72 fieldset.children('div').toggle(); |
78 } | 73 } |
79 | 74 |
80 function hideFieldset(el) { | 75 function hideFieldset(el) { |
81 var fieldset = Element.up(el, 'fieldset'); | 76 var fieldset = $(el).parents('fieldset').first(); |
82 fieldset.toggleClassName('collapsed'); | 77 fieldset.toggleClass('collapsed'); |
83 fieldset.down('div').hide(); | 78 fieldset.children('div').hide(); |
79 } | |
80 | |
81 function initFilters(){ | |
82 $('#add_filter_select').change(function(){ | |
83 addFilter($(this).val(), '', []); | |
84 }); | |
85 $('#filters-table td.field input[type=checkbox]').each(function(){ | |
86 toggleFilter($(this).val()); | |
87 }); | |
88 $('#filters-table td.field input[type=checkbox]').live('click',function(){ | |
89 toggleFilter($(this).val()); | |
90 }); | |
91 $('#filters-table .toggle-multiselect').live('click',function(){ | |
92 toggleMultiSelect($(this).siblings('select')); | |
93 }); | |
94 $('#filters-table input[type=text]').live('keypress', function(e){ | |
95 if (e.keyCode == 13) submit_query_form("query_form"); | |
96 }); | |
97 } | |
98 | |
99 function addFilter(field, operator, values) { | |
100 var fieldId = field.replace('.', '_'); | |
101 var tr = $('#tr_'+fieldId); | |
102 if (tr.length > 0) { | |
103 tr.show(); | |
104 } else { | |
105 buildFilterRow(field, operator, values); | |
106 } | |
107 $('#cb_'+fieldId).attr('checked', true); | |
108 toggleFilter(field); | |
109 $('#add_filter_select').val('').children('option').each(function(){ | |
110 if ($(this).attr('value') == field) { | |
111 $(this).attr('disabled', true); | |
112 } | |
113 }); | |
114 } | |
115 | |
116 function buildFilterRow(field, operator, values) { | |
117 var fieldId = field.replace('.', '_'); | |
118 var filterTable = $("#filters-table"); | |
119 var filterOptions = availableFilters[field]; | |
120 var operators = operatorByType[filterOptions['type']]; | |
121 var filterValues = filterOptions['values']; | |
122 var i, select; | |
123 | |
124 var tr = $('<tr class="filter">').attr('id', 'tr_'+fieldId).html( | |
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 '<td class="operator"><select id="operators_'+fieldId+'" name="op['+field+']"></td>' + | |
127 '<td class="values"></td>' | |
128 ); | |
129 filterTable.append(tr); | |
130 | |
131 select = tr.find('td.operator select'); | |
132 for (i=0;i<operators.length;i++){ | |
133 var option = $('<option>').val(operators[i]).text(operatorLabels[operators[i]]); | |
134 if (operators[i] == operator) {option.attr('selected', true)}; | |
135 select.append(option); | |
136 } | |
137 select.change(function(){toggleOperator(field)}); | |
138 | |
139 switch (filterOptions['type']){ | |
140 case "list": | |
141 case "list_optional": | |
142 case "list_status": | |
143 case "list_subprojects": | |
144 tr.find('td.values').append( | |
145 '<span style="display:none;"><select class="value" id="values_'+fieldId+'_1" name="v['+field+'][]"></select>' + | |
146 ' <span class="toggle-multiselect"> </span></span>' | |
147 ); | |
148 select = tr.find('td.values select'); | |
149 if (values.length > 1) {select.attr('multiple', true)}; | |
150 for (i=0;i<filterValues.length;i++){ | |
151 var filterValue = filterValues[i]; | |
152 var option = $('<option>'); | |
153 if ($.isArray(filterValue)) { | |
154 option.val(filterValue[1]).text(filterValue[0]); | |
155 if ($.inArray(filterValue[1], values) > -1) {option.attr('selected', true);} | |
156 } else { | |
157 option.val(filterValue).text(filterValue); | |
158 if ($.inArray(filterValue, values) > -1) {option.attr('selected', true);} | |
159 } | |
160 select.append(option); | |
161 } | |
162 break; | |
163 case "date": | |
164 case "date_past": | |
165 tr.find('td.values').append( | |
166 '<span style="display:none;"><input type="text" name="v['+field+'][]" id="values_'+fieldId+'_1" size="10" class="value date_value" /></span>' + | |
167 ' <span style="display:none;"><input type="text" name="v['+field+'][]" id="values_'+fieldId+'_2" size="10" class="value date_value" /></span>' + | |
168 ' <span style="display:none;"><input type="text" name="v['+field+'][]" id="values_'+fieldId+'" size="3" class="value" /> '+labelDayPlural+'</span>' | |
169 ); | |
170 $('#values_'+fieldId+'_1').val(values[0]).datepicker(datepickerOptions); | |
171 $('#values_'+fieldId+'_2').val(values[1]).datepicker(datepickerOptions); | |
172 $('#values_'+fieldId).val(values[0]); | |
173 break; | |
174 case "string": | |
175 case "text": | |
176 tr.find('td.values').append( | |
177 '<span style="display:none;"><input type="text" name="v['+field+'][]" id="values_'+fieldId+'" size="30" class="value" /></span>' | |
178 ); | |
179 $('#values_'+fieldId).val(values[0]); | |
180 break; | |
181 case "relation": | |
182 tr.find('td.values').append( | |
183 '<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>' | |
185 ); | |
186 $('#values_'+fieldId).val(values[0]); | |
187 select = tr.find('td.values select'); | |
188 for (i=0;i<allProjects.length;i++){ | |
189 var filterValue = allProjects[i]; | |
190 var option = $('<option>'); | |
191 option.val(filterValue[1]).text(filterValue[0]); | |
192 if (values[0] == filterValue[1]) {option.attr('selected', true)}; | |
193 select.append(option); | |
194 } | |
195 case "integer": | |
196 case "float": | |
197 tr.find('td.values').append( | |
198 '<span style="display:none;"><input type="text" name="v['+field+'][]" id="values_'+fieldId+'_1" size="6" class="value" /></span>' + | |
199 ' <span style="display:none;"><input type="text" name="v['+field+'][]" id="values_'+fieldId+'_2" size="6" class="value" /></span>' | |
200 ); | |
201 $('#values_'+fieldId+'_1').val(values[0]); | |
202 $('#values_'+fieldId+'_2').val(values[1]); | |
203 break; | |
204 } | |
205 } | |
206 | |
207 function toggleFilter(field) { | |
208 var fieldId = field.replace('.', '_'); | |
209 if ($('#cb_' + fieldId).is(':checked')) { | |
210 $("#operators_" + fieldId).show().removeAttr('disabled'); | |
211 toggleOperator(field); | |
212 } else { | |
213 $("#operators_" + fieldId).hide().attr('disabled', true); | |
214 enableValues(field, []); | |
215 } | |
216 } | |
217 | |
218 function enableValues(field, indexes) { | |
219 var fieldId = field.replace('.', '_'); | |
220 $('#tr_'+fieldId+' td.values .value').each(function(index) { | |
221 if ($.inArray(index, indexes) >= 0) { | |
222 $(this).removeAttr('disabled'); | |
223 $(this).parents('span').first().show(); | |
224 } else { | |
225 $(this).val(''); | |
226 $(this).attr('disabled', true); | |
227 $(this).parents('span').first().hide(); | |
228 } | |
229 | |
230 if ($(this).hasClass('group')) { | |
231 $(this).addClass('open'); | |
232 } else { | |
233 $(this).show(); | |
234 } | |
235 }); | |
236 } | |
237 | |
238 function toggleOperator(field) { | |
239 var fieldId = field.replace('.', '_'); | |
240 var operator = $("#operators_" + fieldId); | |
241 switch (operator.val()) { | |
242 case "!*": | |
243 case "*": | |
244 case "t": | |
245 case "w": | |
246 case "o": | |
247 case "c": | |
248 enableValues(field, []); | |
249 break; | |
250 case "><": | |
251 enableValues(field, [0,1]); | |
252 break; | |
253 case "<t+": | |
254 case ">t+": | |
255 case "><t+": | |
256 case "t+": | |
257 case ">t-": | |
258 case "<t-": | |
259 case "><t-": | |
260 case "t-": | |
261 enableValues(field, [2]); | |
262 break; | |
263 case "=p": | |
264 case "=!p": | |
265 case "!p": | |
266 enableValues(field, [1]); | |
267 break; | |
268 default: | |
269 enableValues(field, [0]); | |
270 break; | |
271 } | |
272 } | |
273 | |
274 function toggleMultiSelect(el) { | |
275 if (el.attr('multiple')) { | |
276 el.removeAttr('multiple'); | |
277 } else { | |
278 el.attr('multiple', true); | |
279 } | |
280 } | |
281 | |
282 function submit_query_form(id) { | |
283 selectAllOptions("selected_columns"); | |
284 $('#'+id).submit(); | |
84 } | 285 } |
85 | 286 |
86 var fileFieldCount = 1; | 287 var fileFieldCount = 1; |
87 | |
88 function addFileField() { | 288 function addFileField() { |
89 var fields = $('attachments_fields'); | 289 var fields = $('#attachments_fields'); |
90 if (fields.childElements().length >= 10) return false; | 290 if (fields.children().length >= 10) return false; |
91 fileFieldCount++; | 291 fileFieldCount++; |
92 var s = new Element('span'); | 292 var s = fields.children('span').first().clone(); |
93 s.update(fields.down('span').innerHTML); | 293 s.children('input.file').attr('name', "attachments[" + fileFieldCount + "][file]").val(''); |
94 s.down('input.file').name = "attachments[" + fileFieldCount + "][file]"; | 294 s.children('input.description').attr('name', "attachments[" + fileFieldCount + "][description]").val(''); |
95 s.down('input.description').name = "attachments[" + fileFieldCount + "][description]"; | 295 fields.append(s); |
96 fields.appendChild(s); | |
97 } | 296 } |
98 | 297 |
99 function removeFileField(el) { | 298 function removeFileField(el) { |
100 var fields = $('attachments_fields'); | 299 var fields = $('#attachments_fields'); |
101 var s = Element.up(el, 'span'); | 300 var s = $(el).parents('span').first(); |
102 if (fields.childElements().length > 1) { | 301 if (fields.children().length > 1) { |
103 s.remove(); | 302 s.remove(); |
104 } else { | 303 } else { |
105 s.update(s.innerHTML); | 304 s.children('input.file').val(''); |
106 } | 305 s.children('input.description').val(''); |
306 } | |
107 } | 307 } |
108 | 308 |
109 function checkFileSize(el, maxSize, message) { | 309 function checkFileSize(el, maxSize, message) { |
110 var files = el.files; | 310 var files = el.files; |
111 if (files) { | 311 if (files) { |
117 } | 317 } |
118 } | 318 } |
119 } | 319 } |
120 | 320 |
121 function showTab(name) { | 321 function showTab(name) { |
122 var f = $$('div#content .tab-content'); | 322 $('div#content .tab-content').hide(); |
123 for(var i=0; i<f.length; i++){ | 323 $('div.tabs a').removeClass('selected'); |
124 Element.hide(f[i]); | 324 $('#tab-content-' + name).show(); |
125 } | 325 $('#tab-' + name).addClass('selected'); |
126 var f = $$('div.tabs a'); | 326 return false; |
127 for(var i=0; i<f.length; i++){ | |
128 Element.removeClassName(f[i], "selected"); | |
129 } | |
130 Element.show('tab-content-' + name); | |
131 Element.addClassName('tab-' + name, "selected"); | |
132 return false; | |
133 } | 327 } |
134 | 328 |
135 function moveTabRight(el) { | 329 function moveTabRight(el) { |
136 var lis = Element.up(el, 'div.tabs').down('ul').childElements(); | 330 var lis = $(el).parents('div.tabs').first().find('ul').children(); |
137 var tabsWidth = 0; | 331 var tabsWidth = 0; |
138 var i; | 332 var i = 0; |
139 for (i=0; i<lis.length; i++) { | 333 lis.each(function(){ |
140 if (lis[i].visible()) { | 334 if ($(this).is(':visible')) { |
141 tabsWidth += lis[i].getWidth() + 6; | 335 tabsWidth += $(this).width() + 6; |
142 } | 336 } |
143 } | 337 }); |
144 if (tabsWidth < Element.up(el, 'div.tabs').getWidth() - 60) { | 338 if (tabsWidth < $(el).parents('div.tabs').first().width() - 60) { return; } |
145 return; | 339 while (i<lis.length && !lis.eq(i).is(':visible')) { i++; } |
146 } | 340 lis.eq(i).hide(); |
147 i=0; | |
148 while (i<lis.length && !lis[i].visible()) { | |
149 i++; | |
150 } | |
151 lis[i].hide(); | |
152 } | 341 } |
153 | 342 |
154 function moveTabLeft(el) { | 343 function moveTabLeft(el) { |
155 var lis = Element.up(el, 'div.tabs').down('ul').childElements(); | 344 var lis = $(el).parents('div.tabs').first().find('ul').children(); |
156 var i = 0; | 345 var i = 0; |
157 while (i<lis.length && !lis[i].visible()) { | 346 while (i<lis.length && !lis.eq(i).is(':visible')) { i++; } |
158 i++; | 347 if (i>0) { |
159 } | 348 lis.eq(i-1).show(); |
160 if (i>0) { | 349 } |
161 lis[i-1].show(); | |
162 } | |
163 } | 350 } |
164 | 351 |
165 function displayTabsButtons() { | 352 function displayTabsButtons() { |
166 var lis; | 353 var lis; |
167 var tabsWidth = 0; | 354 var tabsWidth = 0; |
168 var i; | 355 var el; |
169 $$('div.tabs').each(function(el) { | 356 $('div.tabs').each(function() { |
170 lis = el.down('ul').childElements(); | 357 el = $(this); |
171 for (i=0; i<lis.length; i++) { | 358 lis = el.find('ul').children(); |
172 if (lis[i].visible()) { | 359 lis.each(function(){ |
173 tabsWidth += lis[i].getWidth() + 6; | 360 if ($(this).is(':visible')) { |
174 } | 361 tabsWidth += $(this).width() + 6; |
175 } | 362 } |
176 if ((tabsWidth < el.getWidth() - 60) && (lis[0].visible())) { | 363 }); |
177 el.down('div.tabs-buttons').hide(); | 364 if ((tabsWidth < el.width() - 60) && (lis.first().is(':visible'))) { |
178 } else { | 365 el.find('div.tabs-buttons').hide(); |
179 el.down('div.tabs-buttons').show(); | 366 } else { |
180 } | 367 el.find('div.tabs-buttons').show(); |
181 }); | 368 } |
369 }); | |
182 } | 370 } |
183 | 371 |
184 function setPredecessorFieldsVisibility() { | 372 function setPredecessorFieldsVisibility() { |
185 relationType = $('relation_relation_type'); | 373 var relationType = $('#relation_relation_type'); |
186 if (relationType && (relationType.value == "precedes" || relationType.value == "follows")) { | 374 if (relationType.val() == "precedes" || relationType.val() == "follows") { |
187 Element.show('predecessor_fields'); | 375 $('#predecessor_fields').show(); |
188 } else { | 376 } else { |
189 Element.hide('predecessor_fields'); | 377 $('#predecessor_fields').hide(); |
190 } | 378 } |
191 } | 379 } |
192 | 380 |
193 function promptToRemote(text, param, url) { | 381 function showModal(id, width) { |
194 value = prompt(text + ':'); | 382 var el = $('#'+id).first(); |
195 if (value) { | 383 if (el.length == 0 || el.is(':visible')) {return;} |
196 new Ajax.Request(url + '?' + param + '=' + encodeURIComponent(value), {asynchronous:true, evalScripts:true}); | 384 var title = el.find('h3.title').text(); |
385 el.dialog({ | |
386 width: width, | |
387 modal: true, | |
388 resizable: false, | |
389 dialogClass: 'modal', | |
390 title: title | |
391 }); | |
392 el.find("input[type=text], input[type=submit]").first().focus(); | |
393 } | |
394 | |
395 function hideModal(el) { | |
396 var modal; | |
397 if (el) { | |
398 modal = $(el).parents('.ui-dialog-content'); | |
399 } else { | |
400 modal = $('#ajax-modal'); | |
401 } | |
402 modal.dialog("close"); | |
403 } | |
404 | |
405 function submitPreview(url, form, target) { | |
406 $.ajax({ | |
407 url: url, | |
408 type: 'post', | |
409 data: $('#'+form).serialize(), | |
410 success: function(data){ | |
411 $('#'+target).html(data); | |
412 } | |
413 }); | |
414 } | |
415 | |
416 function collapseScmEntry(id) { | |
417 $('.'+id).each(function() { | |
418 if ($(this).hasClass('open')) { | |
419 collapseScmEntry($(this).attr('id')); | |
420 } | |
421 $(this).hide(); | |
422 }); | |
423 $('#'+id).removeClass('open'); | |
424 } | |
425 | |
426 function expandScmEntry(id) { | |
427 $('.'+id).each(function() { | |
428 $(this).show(); | |
429 if ($(this).hasClass('loaded') && !$(this).hasClass('collapsed')) { | |
430 expandScmEntry($(this).attr('id')); | |
431 } | |
432 }); | |
433 $('#'+id).addClass('open'); | |
434 } | |
435 | |
436 function scmEntryClick(id, url) { | |
437 el = $('#'+id); | |
438 if (el.hasClass('open')) { | |
439 collapseScmEntry(id); | |
440 el.addClass('collapsed'); | |
197 return false; | 441 return false; |
198 } | 442 } else if (el.hasClass('loaded')) { |
199 } | 443 expandScmEntry(id); |
200 | 444 el.removeClass('collapsed'); |
201 function showModal(id, width) { | |
202 el = $(id); | |
203 if (el == undefined || el.visible()) {return;} | |
204 var h = $$('body')[0].getHeight(); | |
205 var d = document.createElement("div"); | |
206 d.id = 'modalbg'; | |
207 $('main').appendChild(d); | |
208 $('modalbg').setStyle({ width: '100%', height: h + 'px' }); | |
209 $('modalbg').show(); | |
210 | |
211 var pageWidth = document.viewport.getWidth(); | |
212 el.setStyle({'width': width}); | |
213 el.setStyle({'left': (((pageWidth - el.getWidth())/2 *100) / pageWidth) + '%'}); | |
214 el.addClassName('modal'); | |
215 el.show(); | |
216 | |
217 var submit = el.down("input[type=submit]"); | |
218 if (submit) { | |
219 submit.focus(); | |
220 } | |
221 } | |
222 | |
223 function hideModal(el) { | |
224 var modal = Element.up(el, 'div.modal'); | |
225 if (modal) { | |
226 modal.hide(); | |
227 } | |
228 var bg = $('modalbg'); | |
229 if (bg) { | |
230 bg.remove(); | |
231 } | |
232 } | |
233 | |
234 function collapseScmEntry(id) { | |
235 var els = document.getElementsByClassName(id, 'browser'); | |
236 for (var i = 0; i < els.length; i++) { | |
237 if (els[i].hasClassName('open')) { | |
238 collapseScmEntry(els[i].id); | |
239 } | |
240 Element.hide(els[i]); | |
241 } | |
242 $(id).removeClassName('open'); | |
243 } | |
244 | |
245 function expandScmEntry(id) { | |
246 var els = document.getElementsByClassName(id, 'browser'); | |
247 for (var i = 0; i < els.length; i++) { | |
248 Element.show(els[i]); | |
249 if (els[i].hasClassName('loaded') && !els[i].hasClassName('collapsed')) { | |
250 expandScmEntry(els[i].id); | |
251 } | |
252 } | |
253 $(id).addClassName('open'); | |
254 } | |
255 | |
256 function scmEntryClick(id) { | |
257 el = $(id); | |
258 if (el.hasClassName('open')) { | |
259 collapseScmEntry(id); | |
260 el.addClassName('collapsed'); | |
261 return false; | 445 return false; |
262 } else if (el.hasClassName('loaded')) { | 446 } |
263 expandScmEntry(id); | 447 if (el.hasClass('loading')) { |
264 el.removeClassName('collapsed'); | |
265 return false; | 448 return false; |
266 } | 449 } |
267 if (el.hasClassName('loading')) { | 450 el.addClass('loading'); |
268 return false; | 451 $.ajax({ |
269 } | 452 url: url, |
270 el.addClassName('loading'); | 453 success: function(data){ |
454 el.after(data); | |
455 el.addClass('open').addClass('loaded').removeClass('loading'); | |
456 } | |
457 }); | |
271 return true; | 458 return true; |
272 } | 459 } |
273 | 460 |
274 function scmEntryLoaded(id) { | |
275 Element.addClassName(id, 'open'); | |
276 Element.addClassName(id, 'loaded'); | |
277 Element.removeClassName(id, 'loading'); | |
278 } | |
279 | |
280 function randomKey(size) { | 461 function randomKey(size) { |
281 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'); | 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'); |
282 var key = ''; | 463 var key = ''; |
283 for (i = 0; i < size; i++) { | 464 for (i = 0; i < size; i++) { |
284 key += chars[Math.floor(Math.random() * chars.length)]; | 465 key += chars[Math.floor(Math.random() * chars.length)]; |
285 } | 466 } |
286 return key; | 467 return key; |
287 } | 468 } |
288 | 469 |
289 function observeParentIssueField(url) { | 470 // Can't use Rails' remote select because we need the form data |
290 new Ajax.Autocompleter('issue_parent_issue_id', | 471 function updateIssueFrom(url) { |
291 'parent_issue_candidates', | 472 $.ajax({ |
292 url, | 473 url: url, |
293 { minChars: 3, | 474 type: 'post', |
294 frequency: 0.5, | 475 data: $('#issue-form').serialize() |
295 paramName: 'q', | 476 }); |
296 method: 'get', | 477 } |
297 updateElement: function(value) { | 478 |
298 document.getElementById('issue_parent_issue_id').value = value.id; | 479 function updateBulkEditFrom(url) { |
299 }}); | 480 $.ajax({ |
300 } | 481 url: url, |
301 | 482 type: 'post', |
302 function observeRelatedIssueField(url) { | 483 data: $('#bulk_edit_form').serialize() |
303 new Ajax.Autocompleter('relation_issue_to_id', | 484 }); |
304 'related_issue_candidates', | 485 } |
305 url, | 486 |
306 { minChars: 3, | 487 function observeAutocompleteField(fieldId, url) { |
307 frequency: 0.5, | 488 $(document).ready(function() { |
308 paramName: 'q', | 489 $('#'+fieldId).autocomplete({ |
309 method: 'get', | 490 source: url, |
310 updateElement: function(value) { | 491 minLength: 2 |
311 document.getElementById('relation_issue_to_id').value = value.id; | 492 }); |
312 }, | 493 }); |
313 parameters: 'scope=all' | 494 } |
314 }); | 495 |
315 } | 496 function observeSearchfield(fieldId, targetId, url) { |
316 | 497 $('#'+fieldId).each(function() { |
317 function setVisible(id, visible) { | 498 var $this = $(this); |
318 var el = $(id); | 499 $this.attr('data-value-was', $this.val()); |
319 if (el) {if (visible) {el.show();} else {el.hide();}} | 500 var check = function() { |
501 var val = $this.val(); | |
502 if ($this.attr('data-value-was') != val){ | |
503 $this.attr('data-value-was', val); | |
504 $.ajax({ | |
505 url: url, | |
506 type: 'get', | |
507 data: {q: $this.val()}, | |
508 success: function(data){ $('#'+targetId).html(data); }, | |
509 beforeSend: function(){ $this.addClass('ajax-loading'); }, | |
510 complete: function(){ $this.removeClass('ajax-loading'); } | |
511 }); | |
512 } | |
513 }; | |
514 var reset = function() { | |
515 if (timer) { | |
516 clearInterval(timer); | |
517 timer = setInterval(check, 300); | |
518 } | |
519 }; | |
520 var timer = setInterval(check, 300); | |
521 $this.bind('keyup click mousemove', reset); | |
522 }); | |
320 } | 523 } |
321 | 524 |
322 function observeProjectModules() { | 525 function observeProjectModules() { |
323 var f = function() { | 526 var f = function() { |
324 /* Hides trackers and issues custom fields on the new project form when issue_tracking module is disabled */ | 527 /* Hides trackers and issues custom fields on the new project form when issue_tracking module is disabled */ |
325 var c = ($('project_enabled_module_names_issue_tracking').checked == true); | 528 if ($('#project_enabled_module_names_issue_tracking').attr('checked')) { |
326 setVisible('project_trackers', c); | 529 $('#project_trackers').show(); |
327 setVisible('project_issue_custom_fields', c); | 530 }else{ |
531 $('#project_trackers').hide(); | |
532 } | |
328 }; | 533 }; |
329 | 534 |
330 Event.observe(window, 'load', f); | 535 $(window).load(f); |
331 Event.observe('project_enabled_module_names_issue_tracking', 'change', f); | 536 $('#project_enabled_module_names_issue_tracking').change(f); |
332 } | 537 } |
333 | 538 |
334 /* | 539 function initMyPageSortable(list, url) { |
335 * Class used to warn user when leaving a page with unsaved textarea | 540 $('#list-'+list).sortable({ |
336 * Author: mathias.fischer@berlinonline.de | 541 connectWith: '.block-receiver', |
337 */ | 542 tolerance: 'pointer', |
338 | 543 update: function(){ |
339 var WarnLeavingUnsaved = Class.create({ | 544 $.ajax({ |
340 observedForms: false, | 545 url: url, |
341 observedElements: false, | 546 type: 'post', |
342 changedForms: false, | 547 data: {'blocks': $.map($('#list-'+list).children(), function(el){return $(el).attr('id');})} |
343 message: null, | 548 }); |
344 | 549 } |
345 initialize: function(message){ | 550 }); |
346 this.observedForms = $$('form'); | 551 $("#list-top, #list-left, #list-right").disableSelection(); |
347 this.observedElements = $$('textarea'); | 552 } |
348 this.message = message; | 553 |
349 | 554 var warnLeavingUnsavedMessage; |
350 this.observedElements.each(this.observeChange.bind(this)); | 555 function warnLeavingUnsaved(message) { |
351 this.observedForms.each(this.submitAction.bind(this)); | 556 warnLeavingUnsavedMessage = message; |
352 | 557 |
353 window.onbeforeunload = this.unload.bind(this); | 558 $('form').submit(function(){ |
354 }, | 559 $('textarea').removeData('changed'); |
355 | 560 }); |
356 unload: function(){ | 561 $('textarea').change(function(){ |
357 this.observedElements.each(function(el) {el.blur();}) | 562 $(this).data('changed', 'changed'); |
358 if(this.changedForms) | 563 }); |
359 return this.message; | 564 window.onbeforeunload = function(){ |
360 }, | 565 var warn = false; |
361 | 566 $('textarea').blur().each(function(){ |
362 setChanged: function(){ | 567 if ($(this).data('changed')) { |
363 this.changedForms = true; | 568 warn = true; |
364 }, | 569 } |
365 | 570 }); |
366 setUnchanged: function(){ | 571 if (warn) {return warnLeavingUnsavedMessage;} |
367 this.changedForms = false; | 572 }; |
368 }, | 573 }; |
369 | 574 |
370 observeChange: function(element){ | 575 $(document).ready(function(){ |
371 element.observe('change',this.setChanged.bindAsEventListener(this)); | 576 $('#ajax-indicator').bind('ajaxSend', function(){ |
372 }, | 577 if ($('.ajax-loading').length == 0) { |
373 | 578 $('#ajax-indicator').show(); |
374 submitAction: function(element){ | 579 } |
375 element.observe('submit',this.setUnchanged.bindAsEventListener(this)); | 580 }); |
376 } | 581 $('#ajax-indicator').bind('ajaxStop', function(){ |
582 $('#ajax-indicator').hide(); | |
583 }); | |
377 }); | 584 }); |
378 | 585 |
379 /* | 586 function hideOnLoad() { |
380 * 1 - registers a callback which copies the csrf token into the | 587 $('.hol').hide(); |
381 * X-CSRF-Token header with each ajax request. Necessary to | 588 } |
382 * work with rails applications which have fixed | 589 |
383 * CVE-2011-0447 | 590 function addFormObserversForDoubleSubmit() { |
384 * 2 - shows and hides ajax indicator | 591 $('form[method=post]').each(function() { |
385 */ | 592 if (!$(this).hasClass('multiple-submit')) { |
386 Ajax.Responders.register({ | 593 $(this).submit(function(form_submission) { |
387 onCreate: function(request){ | 594 if ($(form_submission.target).attr('data-submitted')) { |
388 var csrf_meta_tag = $$('meta[name=csrf-token]')[0]; | 595 form_submission.preventDefault(); |
389 | 596 } else { |
390 if (csrf_meta_tag) { | 597 $(form_submission.target).attr('data-submitted', true); |
391 var header = 'X-CSRF-Token', | |
392 token = csrf_meta_tag.readAttribute('content'); | |
393 | |
394 if (!request.options.requestHeaders) { | |
395 request.options.requestHeaders = {}; | |
396 } | |
397 request.options.requestHeaders[header] = token; | |
398 } | |
399 | |
400 if ($('ajax-indicator') && Ajax.activeRequestCount > 0) { | |
401 Element.show('ajax-indicator'); | |
402 } | 598 } |
403 }, | 599 }); |
404 onComplete: function(){ | 600 } |
405 if ($('ajax-indicator') && Ajax.activeRequestCount == 0) { | 601 }); |
406 Element.hide('ajax-indicator'); | 602 } |
407 } | 603 |
408 } | 604 $(document).ready(hideOnLoad); |
409 }); | 605 $(document).ready(addFormObserversForDoubleSubmit); |
410 | |
411 function hideOnLoad() { | |
412 $$('.hol').each(function(el) { | |
413 el.hide(); | |
414 }); | |
415 } | |
416 | |
417 Event.observe(window, 'load', hideOnLoad); |