annotate public/javascripts/application.js @ 250:c90c42a771ec cannam

* Restore further things broken during merge
author Chris Cannam <chris.cannam@soundsoftware.ac.uk>
date Thu, 03 Mar 2011 14:38:43 +0000
parents 73ff0e6a11b1
children 753f1380d6bc
rev   line source
Chris@0 1 /* redMine - project management software
Chris@0 2 Copyright (C) 2006-2008 Jean-Philippe Lang */
Chris@0 3
Chris@0 4 function checkAll (id, checked) {
Chris@0 5 var els = Element.descendants(id);
Chris@0 6 for (var i = 0; i < els.length; i++) {
Chris@0 7 if (els[i].disabled==false) {
Chris@0 8 els[i].checked = checked;
Chris@0 9 }
Chris@0 10 }
Chris@0 11 }
Chris@0 12
Chris@0 13 function toggleCheckboxesBySelector(selector) {
Chris@0 14 boxes = $$(selector);
Chris@0 15 var all_checked = true;
Chris@0 16 for (i = 0; i < boxes.length; i++) { if (boxes[i].checked == false) { all_checked = false; } }
Chris@0 17 for (i = 0; i < boxes.length; i++) { boxes[i].checked = !all_checked; }
Chris@0 18 }
Chris@0 19
chris@37 20 function setCheckboxesBySelector(checked, selector) {
chris@37 21 var boxes = $$(selector);
chris@37 22 boxes.each(function(ele) {
chris@37 23 ele.checked = checked;
chris@37 24 });
chris@37 25 }
chris@37 26
Chris@0 27 function showAndScrollTo(id, focus) {
Chris@0 28 Element.show(id);
Chris@0 29 if (focus!=null) { Form.Element.focus(focus); }
Chris@0 30 Element.scrollTo(id);
Chris@0 31 }
Chris@0 32
Chris@0 33 function toggleRowGroup(el) {
Chris@0 34 var tr = Element.up(el, 'tr');
Chris@0 35 var n = Element.next(tr);
Chris@0 36 tr.toggleClassName('open');
Chris@0 37 while (n != undefined && !n.hasClassName('group')) {
Chris@0 38 Element.toggle(n);
Chris@0 39 n = Element.next(n);
Chris@0 40 }
Chris@0 41 }
Chris@0 42
Chris@0 43 function toggleFieldset(el) {
Chris@0 44 var fieldset = Element.up(el, 'fieldset');
Chris@0 45 fieldset.toggleClassName('collapsed');
Chris@0 46 Effect.toggle(fieldset.down('div'), 'slide', {duration:0.2});
Chris@0 47 }
Chris@0 48
Chris@245 49 function hideFieldset(el) {
Chris@245 50 var fieldset = Element.up(el, 'fieldset');
Chris@245 51 fieldset.toggleClassName('collapsed');
Chris@245 52 fieldset.down('div').hide();
Chris@245 53 }
Chris@245 54
Chris@0 55 var fileFieldCount = 1;
Chris@0 56
Chris@0 57 function addFileField() {
Chris@0 58 if (fileFieldCount >= 10) return false
Chris@0 59 fileFieldCount++;
Chris@0 60 var f = document.createElement("input");
Chris@0 61 f.type = "file";
Chris@0 62 f.name = "attachments[" + fileFieldCount + "][file]";
Chris@0 63 f.size = 30;
Chris@0 64 var d = document.createElement("input");
Chris@0 65 d.type = "text";
Chris@0 66 d.name = "attachments[" + fileFieldCount + "][description]";
Chris@0 67 d.size = 60;
Chris@1 68 var dLabel = new Element('label');
Chris@0 69 dLabel.addClassName('inline');
Chris@0 70 // Pulls the languge value used for Optional Description
Chris@0 71 dLabel.update($('attachment_description_label_content').innerHTML)
Chris@0 72 p = document.getElementById("attachments_fields");
Chris@0 73 p.appendChild(document.createElement("br"));
Chris@0 74 p.appendChild(f);
Chris@0 75 p.appendChild(dLabel);
Chris@0 76 dLabel.appendChild(d);
Chris@0 77
Chris@0 78 }
Chris@0 79
Chris@0 80 function showTab(name) {
Chris@0 81 var f = $$('div#content .tab-content');
Chris@0 82 for(var i=0; i<f.length; i++){
Chris@0 83 Element.hide(f[i]);
Chris@0 84 }
Chris@0 85 var f = $$('div.tabs a');
Chris@0 86 for(var i=0; i<f.length; i++){
Chris@0 87 Element.removeClassName(f[i], "selected");
Chris@0 88 }
Chris@0 89 Element.show('tab-content-' + name);
Chris@0 90 Element.addClassName('tab-' + name, "selected");
Chris@0 91 return false;
Chris@0 92 }
Chris@0 93
Chris@0 94 function moveTabRight(el) {
Chris@0 95 var lis = Element.up(el, 'div.tabs').down('ul').childElements();
Chris@0 96 var tabsWidth = 0;
Chris@0 97 var i;
Chris@0 98 for (i=0; i<lis.length; i++) {
Chris@0 99 if (lis[i].visible()) {
Chris@0 100 tabsWidth += lis[i].getWidth() + 6;
Chris@0 101 }
Chris@0 102 }
Chris@0 103 if (tabsWidth < Element.up(el, 'div.tabs').getWidth() - 60) {
Chris@0 104 return;
Chris@0 105 }
Chris@0 106 i=0;
Chris@0 107 while (i<lis.length && !lis[i].visible()) {
Chris@0 108 i++;
Chris@0 109 }
Chris@0 110 lis[i].hide();
Chris@0 111 }
Chris@0 112
Chris@0 113 function moveTabLeft(el) {
Chris@0 114 var lis = Element.up(el, 'div.tabs').down('ul').childElements();
Chris@0 115 var i = 0;
Chris@0 116 while (i<lis.length && !lis[i].visible()) {
Chris@0 117 i++;
Chris@0 118 }
Chris@0 119 if (i>0) {
Chris@0 120 lis[i-1].show();
Chris@0 121 }
Chris@0 122 }
Chris@0 123
Chris@0 124 function displayTabsButtons() {
Chris@0 125 var lis;
Chris@0 126 var tabsWidth = 0;
Chris@0 127 var i;
Chris@0 128 $$('div.tabs').each(function(el) {
Chris@0 129 lis = el.down('ul').childElements();
Chris@0 130 for (i=0; i<lis.length; i++) {
Chris@0 131 if (lis[i].visible()) {
Chris@0 132 tabsWidth += lis[i].getWidth() + 6;
Chris@0 133 }
Chris@0 134 }
Chris@0 135 if ((tabsWidth < el.getWidth() - 60) && (lis[0].visible())) {
Chris@0 136 el.down('div.tabs-buttons').hide();
Chris@0 137 } else {
Chris@0 138 el.down('div.tabs-buttons').show();
Chris@0 139 }
Chris@0 140 });
Chris@0 141 }
Chris@0 142
Chris@0 143 function setPredecessorFieldsVisibility() {
Chris@0 144 relationType = $('relation_relation_type');
Chris@0 145 if (relationType && (relationType.value == "precedes" || relationType.value == "follows")) {
Chris@0 146 Element.show('predecessor_fields');
Chris@0 147 } else {
Chris@0 148 Element.hide('predecessor_fields');
Chris@0 149 }
Chris@0 150 }
Chris@0 151
Chris@0 152 function promptToRemote(text, param, url) {
Chris@0 153 value = prompt(text + ':');
Chris@0 154 if (value) {
Chris@0 155 new Ajax.Request(url + '?' + param + '=' + encodeURIComponent(value), {asynchronous:true, evalScripts:true});
Chris@0 156 return false;
Chris@0 157 }
Chris@0 158 }
Chris@0 159
Chris@0 160 function collapseScmEntry(id) {
Chris@0 161 var els = document.getElementsByClassName(id, 'browser');
Chris@0 162 for (var i = 0; i < els.length; i++) {
Chris@0 163 if (els[i].hasClassName('open')) {
Chris@0 164 collapseScmEntry(els[i].id);
Chris@0 165 }
Chris@0 166 Element.hide(els[i]);
Chris@0 167 }
Chris@0 168 $(id).removeClassName('open');
Chris@0 169 }
Chris@0 170
Chris@0 171 function expandScmEntry(id) {
Chris@0 172 var els = document.getElementsByClassName(id, 'browser');
Chris@0 173 for (var i = 0; i < els.length; i++) {
Chris@0 174 Element.show(els[i]);
Chris@0 175 if (els[i].hasClassName('loaded') && !els[i].hasClassName('collapsed')) {
Chris@0 176 expandScmEntry(els[i].id);
Chris@0 177 }
Chris@0 178 }
Chris@0 179 $(id).addClassName('open');
Chris@0 180 }
Chris@0 181
Chris@0 182 function scmEntryClick(id) {
Chris@0 183 el = $(id);
Chris@0 184 if (el.hasClassName('open')) {
Chris@0 185 collapseScmEntry(id);
Chris@0 186 el.addClassName('collapsed');
Chris@0 187 return false;
Chris@0 188 } else if (el.hasClassName('loaded')) {
Chris@0 189 expandScmEntry(id);
Chris@0 190 el.removeClassName('collapsed');
Chris@0 191 return false;
Chris@0 192 }
Chris@0 193 if (el.hasClassName('loading')) {
Chris@0 194 return false;
Chris@0 195 }
Chris@0 196 el.addClassName('loading');
Chris@0 197 return true;
Chris@0 198 }
Chris@0 199
Chris@0 200 function scmEntryLoaded(id) {
Chris@0 201 Element.addClassName(id, 'open');
Chris@0 202 Element.addClassName(id, 'loaded');
Chris@0 203 Element.removeClassName(id, 'loading');
Chris@0 204 }
Chris@0 205
Chris@0 206 function randomKey(size) {
Chris@0 207 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');
Chris@0 208 var key = '';
Chris@0 209 for (i = 0; i < size; i++) {
Chris@0 210 key += chars[Math.floor(Math.random() * chars.length)];
Chris@0 211 }
Chris@0 212 return key;
Chris@0 213 }
Chris@0 214
Chris@0 215 function observeParentIssueField(url) {
Chris@0 216 new Ajax.Autocompleter('issue_parent_issue_id',
Chris@0 217 'parent_issue_candidates',
Chris@0 218 url,
Chris@0 219 { minChars: 3,
Chris@0 220 frequency: 0.5,
Chris@0 221 paramName: 'q',
Chris@0 222 updateElement: function(value) {
Chris@0 223 document.getElementById('issue_parent_issue_id').value = value.id;
Chris@0 224 }});
Chris@0 225 }
Chris@0 226
Chris@117 227 function observeRelatedIssueField(url) {
Chris@117 228 new Ajax.Autocompleter('relation_issue_to_id',
Chris@117 229 'related_issue_candidates',
Chris@117 230 url,
Chris@117 231 { minChars: 3,
Chris@117 232 frequency: 0.5,
Chris@117 233 paramName: 'q',
Chris@117 234 updateElement: function(value) {
Chris@117 235 document.getElementById('relation_issue_to_id').value = value.id;
Chris@117 236 },
Chris@117 237 parameters: 'scope=all'
Chris@117 238 });
Chris@117 239 }
Chris@117 240
Chris@117 241 function setVisible(id, visible) {
Chris@117 242 var el = $(id);
Chris@117 243 if (el) {if (visible) {el.show();} else {el.hide();}}
Chris@117 244 }
Chris@117 245
Chris@117 246 function observeProjectModules() {
Chris@117 247 var f = function() {
Chris@117 248 /* Hides trackers and issues custom fields on the new project form when issue_tracking module is disabled */
Chris@117 249 var c = ($('project_enabled_module_names_issue_tracking').checked == true);
Chris@117 250 setVisible('project_trackers', c);
Chris@117 251 setVisible('project_issue_custom_fields', c);
Chris@117 252 };
Chris@117 253
Chris@117 254 Event.observe(window, 'load', f);
Chris@117 255 Event.observe('project_enabled_module_names_issue_tracking', 'change', f);
Chris@117 256 }
Chris@117 257
Chris@245 258 /*
Chris@245 259 * Class used to warn user when leaving a page with unsaved textarea
Chris@245 260 * Author: mathias.fischer@berlinonline.de
Chris@245 261 */
Chris@245 262
Chris@245 263 var WarnLeavingUnsaved = Class.create({
Chris@245 264 observedForms: false,
Chris@245 265 observedElements: false,
Chris@245 266 changedForms: false,
Chris@245 267 message: null,
Chris@245 268
Chris@245 269 initialize: function(message){
Chris@245 270 this.observedForms = $$('form');
Chris@245 271 this.observedElements = $$('textarea');
Chris@245 272 this.message = message;
Chris@245 273
Chris@245 274 this.observedElements.each(this.observeChange.bind(this));
Chris@245 275 this.observedForms.each(this.submitAction.bind(this));
Chris@245 276
Chris@245 277 window.onbeforeunload = this.unload.bind(this);
Chris@245 278 },
Chris@245 279
Chris@245 280 unload: function(){
Chris@245 281 if(this.changedForms)
Chris@245 282 return this.message;
Chris@245 283 },
Chris@245 284
Chris@245 285 setChanged: function(){
Chris@245 286 this.changedForms = true;
Chris@245 287 },
Chris@245 288
Chris@245 289 setUnchanged: function(){
Chris@245 290 this.changedForms = false;
Chris@245 291 },
Chris@245 292
Chris@245 293 observeChange: function(element){
Chris@245 294 element.observe('change',this.setChanged.bindAsEventListener(this));
Chris@245 295 },
Chris@245 296
Chris@245 297 submitAction: function(element){
Chris@245 298 element.observe('submit',this.setUnchanged.bindAsEventListener(this));
Chris@245 299 }
Chris@245 300 });
Chris@117 301
Chris@0 302 /* shows and hides ajax indicator */
Chris@0 303 Ajax.Responders.register({
Chris@0 304 onCreate: function(){
Chris@0 305 if ($('ajax-indicator') && Ajax.activeRequestCount > 0) {
Chris@0 306 Element.show('ajax-indicator');
Chris@0 307 }
Chris@0 308 },
Chris@0 309 onComplete: function(){
Chris@0 310 if ($('ajax-indicator') && Ajax.activeRequestCount == 0) {
Chris@0 311 Element.hide('ajax-indicator');
Chris@0 312 }
Chris@0 313 }
Chris@0 314 });
Chris@0 315
Chris@0 316 function hideOnLoad() {
Chris@0 317 $$('.hol').each(function(el) {
Chris@0 318 el.hide();
Chris@0 319 });
Chris@0 320 }
Chris@0 321
Chris@0 322 Event.observe(window, 'load', hideOnLoad);
luisf@160 323
luisf@160 324
luisf@160 325
luisf@160 326