annotate public/javascripts/application.js @ 1452:d6b9fd02bb89 feature_36_js_refactoring

Deprecated develoment branch.
author luisf <luis.figueira@eecs.qmul.ac.uk>
date Fri, 11 Oct 2013 17:01:24 +0100
parents 851510f1b535
children 5e80956cc792
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@441 43 function collapseAllRowGroups(el) {
Chris@441 44 var tbody = Element.up(el, 'tbody');
Chris@441 45 tbody.childElements('tr').each(function(tr) {
Chris@441 46 if (tr.hasClassName('group')) {
Chris@441 47 tr.removeClassName('open');
Chris@441 48 } else {
Chris@441 49 tr.hide();
Chris@441 50 }
Chris@441 51 })
Chris@441 52 }
Chris@441 53
Chris@441 54 function expandAllRowGroups(el) {
Chris@441 55 var tbody = Element.up(el, 'tbody');
Chris@441 56 tbody.childElements('tr').each(function(tr) {
Chris@441 57 if (tr.hasClassName('group')) {
Chris@441 58 tr.addClassName('open');
Chris@441 59 } else {
Chris@441 60 tr.show();
Chris@441 61 }
Chris@441 62 })
Chris@441 63 }
Chris@441 64
Chris@441 65 function toggleAllRowGroups(el) {
Chris@441 66 var tr = Element.up(el, 'tr');
Chris@441 67 if (tr.hasClassName('open')) {
Chris@441 68 collapseAllRowGroups(el);
Chris@441 69 } else {
Chris@441 70 expandAllRowGroups(el);
Chris@441 71 }
Chris@441 72 }
Chris@441 73
Chris@0 74 function toggleFieldset(el) {
Chris@0 75 var fieldset = Element.up(el, 'fieldset');
Chris@0 76 fieldset.toggleClassName('collapsed');
Chris@0 77 Effect.toggle(fieldset.down('div'), 'slide', {duration:0.2});
Chris@0 78 }
Chris@0 79
Chris@245 80 function hideFieldset(el) {
Chris@245 81 var fieldset = Element.up(el, 'fieldset');
Chris@245 82 fieldset.toggleClassName('collapsed');
Chris@245 83 fieldset.down('div').hide();
Chris@245 84 }
Chris@245 85
Chris@0 86 var fileFieldCount = 1;
Chris@0 87
Chris@0 88 function addFileField() {
Chris@0 89 if (fileFieldCount >= 10) return false
Chris@0 90 fileFieldCount++;
Chris@0 91 var f = document.createElement("input");
Chris@0 92 f.type = "file";
Chris@0 93 f.name = "attachments[" + fileFieldCount + "][file]";
Chris@0 94 f.size = 30;
Chris@0 95 var d = document.createElement("input");
Chris@0 96 d.type = "text";
Chris@0 97 d.name = "attachments[" + fileFieldCount + "][description]";
Chris@0 98 d.size = 60;
Chris@1 99 var dLabel = new Element('label');
Chris@0 100 dLabel.addClassName('inline');
Chris@0 101 // Pulls the languge value used for Optional Description
Chris@0 102 dLabel.update($('attachment_description_label_content').innerHTML)
Chris@0 103 p = document.getElementById("attachments_fields");
Chris@0 104 p.appendChild(document.createElement("br"));
Chris@0 105 p.appendChild(f);
Chris@0 106 p.appendChild(dLabel);
Chris@0 107 dLabel.appendChild(d);
Chris@0 108
Chris@0 109 }
Chris@0 110
Chris@0 111 function showTab(name) {
Chris@0 112 var f = $$('div#content .tab-content');
Chris@0 113 for(var i=0; i<f.length; i++){
Chris@0 114 Element.hide(f[i]);
Chris@0 115 }
Chris@0 116 var f = $$('div.tabs a');
Chris@0 117 for(var i=0; i<f.length; i++){
Chris@0 118 Element.removeClassName(f[i], "selected");
Chris@0 119 }
Chris@0 120 Element.show('tab-content-' + name);
Chris@0 121 Element.addClassName('tab-' + name, "selected");
Chris@0 122 return false;
Chris@0 123 }
Chris@0 124
Chris@0 125 function moveTabRight(el) {
Chris@0 126 var lis = Element.up(el, 'div.tabs').down('ul').childElements();
Chris@0 127 var tabsWidth = 0;
Chris@0 128 var i;
Chris@0 129 for (i=0; i<lis.length; i++) {
Chris@0 130 if (lis[i].visible()) {
Chris@0 131 tabsWidth += lis[i].getWidth() + 6;
Chris@0 132 }
Chris@0 133 }
Chris@0 134 if (tabsWidth < Element.up(el, 'div.tabs').getWidth() - 60) {
Chris@0 135 return;
Chris@0 136 }
Chris@0 137 i=0;
Chris@0 138 while (i<lis.length && !lis[i].visible()) {
Chris@0 139 i++;
Chris@0 140 }
Chris@0 141 lis[i].hide();
Chris@0 142 }
Chris@0 143
Chris@0 144 function moveTabLeft(el) {
Chris@0 145 var lis = Element.up(el, 'div.tabs').down('ul').childElements();
Chris@0 146 var i = 0;
Chris@0 147 while (i<lis.length && !lis[i].visible()) {
Chris@0 148 i++;
Chris@0 149 }
Chris@0 150 if (i>0) {
Chris@0 151 lis[i-1].show();
Chris@0 152 }
Chris@0 153 }
Chris@0 154
Chris@0 155 function displayTabsButtons() {
Chris@0 156 var lis;
Chris@0 157 var tabsWidth = 0;
Chris@0 158 var i;
Chris@0 159 $$('div.tabs').each(function(el) {
Chris@0 160 lis = el.down('ul').childElements();
Chris@0 161 for (i=0; i<lis.length; i++) {
Chris@0 162 if (lis[i].visible()) {
Chris@0 163 tabsWidth += lis[i].getWidth() + 6;
Chris@0 164 }
Chris@0 165 }
Chris@0 166 if ((tabsWidth < el.getWidth() - 60) && (lis[0].visible())) {
Chris@0 167 el.down('div.tabs-buttons').hide();
Chris@0 168 } else {
Chris@0 169 el.down('div.tabs-buttons').show();
Chris@0 170 }
Chris@0 171 });
Chris@0 172 }
Chris@0 173
Chris@0 174 function setPredecessorFieldsVisibility() {
Chris@0 175 relationType = $('relation_relation_type');
Chris@0 176 if (relationType && (relationType.value == "precedes" || relationType.value == "follows")) {
Chris@0 177 Element.show('predecessor_fields');
Chris@0 178 } else {
Chris@0 179 Element.hide('predecessor_fields');
Chris@0 180 }
Chris@0 181 }
Chris@0 182
Chris@0 183 function promptToRemote(text, param, url) {
Chris@0 184 value = prompt(text + ':');
Chris@0 185 if (value) {
Chris@0 186 new Ajax.Request(url + '?' + param + '=' + encodeURIComponent(value), {asynchronous:true, evalScripts:true});
Chris@0 187 return false;
Chris@0 188 }
Chris@0 189 }
Chris@0 190
Chris@0 191 function collapseScmEntry(id) {
Chris@0 192 var els = document.getElementsByClassName(id, 'browser');
Chris@0 193 for (var i = 0; i < els.length; i++) {
Chris@0 194 if (els[i].hasClassName('open')) {
Chris@0 195 collapseScmEntry(els[i].id);
Chris@0 196 }
Chris@0 197 Element.hide(els[i]);
Chris@0 198 }
Chris@0 199 $(id).removeClassName('open');
Chris@0 200 }
Chris@0 201
Chris@0 202 function expandScmEntry(id) {
Chris@0 203 var els = document.getElementsByClassName(id, 'browser');
Chris@0 204 for (var i = 0; i < els.length; i++) {
Chris@0 205 Element.show(els[i]);
Chris@0 206 if (els[i].hasClassName('loaded') && !els[i].hasClassName('collapsed')) {
Chris@0 207 expandScmEntry(els[i].id);
Chris@0 208 }
Chris@0 209 }
Chris@0 210 $(id).addClassName('open');
Chris@0 211 }
Chris@0 212
Chris@0 213 function scmEntryClick(id) {
Chris@0 214 el = $(id);
Chris@0 215 if (el.hasClassName('open')) {
Chris@0 216 collapseScmEntry(id);
Chris@0 217 el.addClassName('collapsed');
Chris@0 218 return false;
Chris@0 219 } else if (el.hasClassName('loaded')) {
Chris@0 220 expandScmEntry(id);
Chris@0 221 el.removeClassName('collapsed');
Chris@0 222 return false;
Chris@0 223 }
Chris@0 224 if (el.hasClassName('loading')) {
Chris@0 225 return false;
Chris@0 226 }
Chris@0 227 el.addClassName('loading');
Chris@0 228 return true;
Chris@0 229 }
Chris@0 230
Chris@0 231 function scmEntryLoaded(id) {
Chris@0 232 Element.addClassName(id, 'open');
Chris@0 233 Element.addClassName(id, 'loaded');
Chris@0 234 Element.removeClassName(id, 'loading');
Chris@0 235 }
Chris@0 236
Chris@0 237 function randomKey(size) {
Chris@0 238 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 239 var key = '';
Chris@0 240 for (i = 0; i < size; i++) {
Chris@0 241 key += chars[Math.floor(Math.random() * chars.length)];
Chris@0 242 }
Chris@0 243 return key;
Chris@0 244 }
Chris@0 245
Chris@0 246 function observeParentIssueField(url) {
Chris@0 247 new Ajax.Autocompleter('issue_parent_issue_id',
Chris@0 248 'parent_issue_candidates',
Chris@0 249 url,
Chris@0 250 { minChars: 3,
Chris@0 251 frequency: 0.5,
Chris@0 252 paramName: 'q',
Chris@0 253 updateElement: function(value) {
Chris@0 254 document.getElementById('issue_parent_issue_id').value = value.id;
Chris@0 255 }});
Chris@0 256 }
Chris@0 257
Chris@117 258 function observeRelatedIssueField(url) {
Chris@117 259 new Ajax.Autocompleter('relation_issue_to_id',
Chris@117 260 'related_issue_candidates',
Chris@117 261 url,
Chris@117 262 { minChars: 3,
Chris@117 263 frequency: 0.5,
Chris@117 264 paramName: 'q',
Chris@117 265 updateElement: function(value) {
Chris@117 266 document.getElementById('relation_issue_to_id').value = value.id;
Chris@117 267 },
Chris@117 268 parameters: 'scope=all'
Chris@117 269 });
Chris@117 270 }
Chris@117 271
Chris@117 272 function setVisible(id, visible) {
Chris@117 273 var el = $(id);
Chris@117 274 if (el) {if (visible) {el.show();} else {el.hide();}}
Chris@117 275 }
Chris@117 276
Chris@117 277 function observeProjectModules() {
Chris@117 278 var f = function() {
Chris@117 279 /* Hides trackers and issues custom fields on the new project form when issue_tracking module is disabled */
Chris@117 280 var c = ($('project_enabled_module_names_issue_tracking').checked == true);
Chris@117 281 setVisible('project_trackers', c);
Chris@117 282 setVisible('project_issue_custom_fields', c);
Chris@117 283 };
Chris@117 284
Chris@117 285 Event.observe(window, 'load', f);
Chris@117 286 Event.observe('project_enabled_module_names_issue_tracking', 'change', f);
Chris@117 287 }
Chris@117 288
Chris@245 289 /*
Chris@245 290 * Class used to warn user when leaving a page with unsaved textarea
Chris@245 291 * Author: mathias.fischer@berlinonline.de
Chris@245 292 */
Chris@245 293
Chris@245 294 var WarnLeavingUnsaved = Class.create({
Chris@245 295 observedForms: false,
Chris@245 296 observedElements: false,
Chris@245 297 changedForms: false,
Chris@245 298 message: null,
Chris@245 299
Chris@245 300 initialize: function(message){
Chris@245 301 this.observedForms = $$('form');
Chris@245 302 this.observedElements = $$('textarea');
Chris@245 303 this.message = message;
Chris@245 304
Chris@245 305 this.observedElements.each(this.observeChange.bind(this));
Chris@245 306 this.observedForms.each(this.submitAction.bind(this));
Chris@245 307
Chris@245 308 window.onbeforeunload = this.unload.bind(this);
Chris@245 309 },
Chris@245 310
Chris@245 311 unload: function(){
Chris@507 312 this.observedElements.each(function(el) {el.blur();})
Chris@245 313 if(this.changedForms)
Chris@245 314 return this.message;
Chris@245 315 },
Chris@245 316
Chris@245 317 setChanged: function(){
Chris@245 318 this.changedForms = true;
Chris@245 319 },
Chris@245 320
Chris@245 321 setUnchanged: function(){
Chris@245 322 this.changedForms = false;
Chris@245 323 },
Chris@245 324
Chris@245 325 observeChange: function(element){
Chris@245 326 element.observe('change',this.setChanged.bindAsEventListener(this));
Chris@245 327 },
Chris@245 328
Chris@245 329 submitAction: function(element){
Chris@245 330 element.observe('submit',this.setUnchanged.bindAsEventListener(this));
Chris@245 331 }
Chris@245 332 });
Chris@117 333
Chris@441 334 /*
Chris@441 335 * 1 - registers a callback which copies the csrf token into the
Chris@441 336 * X-CSRF-Token header with each ajax request. Necessary to
Chris@441 337 * work with rails applications which have fixed
Chris@441 338 * CVE-2011-0447
Chris@441 339 * 2 - shows and hides ajax indicator
Chris@441 340 */
Chris@0 341 Ajax.Responders.register({
Chris@441 342 onCreate: function(request){
Chris@441 343 var csrf_meta_tag = $$('meta[name=csrf-token]')[0];
Chris@441 344
Chris@441 345 if (csrf_meta_tag) {
Chris@441 346 var header = 'X-CSRF-Token',
Chris@441 347 token = csrf_meta_tag.readAttribute('content');
Chris@441 348
Chris@441 349 if (!request.options.requestHeaders) {
Chris@441 350 request.options.requestHeaders = {};
Chris@441 351 }
Chris@441 352 request.options.requestHeaders[header] = token;
Chris@441 353 }
Chris@441 354
Chris@0 355 if ($('ajax-indicator') && Ajax.activeRequestCount > 0) {
Chris@0 356 Element.show('ajax-indicator');
Chris@0 357 }
Chris@0 358 },
Chris@0 359 onComplete: function(){
Chris@0 360 if ($('ajax-indicator') && Ajax.activeRequestCount == 0) {
Chris@0 361 Element.hide('ajax-indicator');
Chris@0 362 }
Chris@0 363 }
Chris@0 364 });
Chris@0 365
Chris@0 366 function hideOnLoad() {
Chris@0 367 $$('.hol').each(function(el) {
Chris@0 368 el.hide();
Chris@0 369 });
Chris@0 370 }
Chris@0 371
Chris@0 372 Event.observe(window, 'load', hideOnLoad);
luisf@160 373
luisf@160 374
luisf@160 375
luisf@160 376