gantt_rails 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,954 @@
1
+
2
+ if(!window.console) {
3
+ window.console = new function() {
4
+ this.log = function(str) {/*alert(str)*/};
5
+ this.debug = function(str) {/*alert(str)*/};
6
+ this.error = function(str) {/*alert(str)*/};
7
+ };
8
+ }
9
+ if(!window.console.debug || !window.console.error|| !window.console.log ) {
10
+ window.console = new function() {
11
+ this.log = function(str) {/*alert(str)*/};
12
+ this.debug = function(str) {/*alert(str)*/};
13
+ this.error = function(str) {/*alert(str)*/};
14
+ };
15
+ }
16
+
17
+
18
+ //----------------------------------positioning-----------------------------------------------
19
+ $.fn.bringToFront=function(selector){
20
+ var zi=10;
21
+ var elements = selector ? $(selector) : $("*");
22
+ elements.each(function() {
23
+ if($(this).css("position")!="static"){
24
+ var cur = parseInt($(this).css('zIndex'));
25
+ zi = cur > zi ? parseInt($(this).css('zIndex')) : zi;
26
+ }
27
+ });
28
+
29
+ return $(this).css('zIndex',zi+=10);
30
+ };
31
+
32
+ function nearBestPosition(whereId, theObjId, centerOnEl) {
33
+ var el=whereId;
34
+ var target=theObjId;
35
+
36
+ if (typeof whereId != "object"){ el = $("#"+whereId); }
37
+ if (typeof theObjId != "object"){target = $("#"+theObjId);}
38
+
39
+ if (el) {
40
+ target.css("visibility","hidden");
41
+ var hasContainment = false;
42
+
43
+ target.parents().each(function(){
44
+ if($(this).css("position")=="static")
45
+ return;
46
+ hasContainment = true;
47
+
48
+ });
49
+
50
+ var trueX = hasContainment ? el.position().left : el.offset().left;
51
+ var trueY = hasContainment ? el.position().top : el.offset().top;
52
+ var h = el.outerHeight();
53
+ var elHeight = parseFloat(h);
54
+
55
+ if (centerOnEl){
56
+ var elWidth = parseFloat(el.outerWidth());
57
+ var targetWidth = parseFloat(target.outerWidth());
58
+ trueX+=(elWidth-targetWidth)/2;
59
+ }
60
+
61
+ trueY += parseFloat(elHeight);
62
+
63
+ var left = trueX;
64
+ var top = trueY;
65
+ var barHeight = ($.browser.msie) ? 45 : 35;
66
+ var barWidth = ($.browser.msie) ? 20 : 0;
67
+
68
+ if (trueX && trueY) {
69
+ target.css("left", left);
70
+ target.css("top", top);
71
+ }
72
+
73
+ if (target.offset().left >= ($(window).width() - target.outerWidth())) {
74
+ left = ($(window).width() - target.outerWidth() - barWidth )+ "px";
75
+ target.css("left", left);
76
+ }
77
+
78
+ if (target.offset().left < 0) {
79
+ left = 0+ "px";
80
+ target.css("left", left);
81
+ }
82
+
83
+ if ((target.offset().top + target.outerHeight() >= (($(window).height() - barHeight))) && (target.outerHeight() < $(window).height())) {
84
+ target.css("margin-top",(-(el.outerHeight() + target.outerHeight())) + "px");
85
+ }
86
+
87
+ target.css("visibility","visible");
88
+ }
89
+ }
90
+
91
+
92
+ String.prototype.trim = function () {
93
+ return this.replace(/^\s*(\S*(\s+\S+)*)\s*$/, "$1");
94
+ };
95
+
96
+ String.prototype.startsWith = function(t, i) {
97
+ if (!i) {
98
+ return (t == this.substring(0, t.length));
99
+ } else {
100
+ return (t.toLowerCase()== this.substring(0, t.length).toLowerCase());
101
+ }
102
+ };
103
+
104
+ String.prototype.endsWith = function(t, i) {
105
+ if (!i) {
106
+ return (t== this.substring(this.length - t.length));
107
+ } else {
108
+ return (t.toLowerCase() == this.substring(this.length -t.length).toLowerCase());
109
+ }
110
+ };
111
+
112
+ // leaves only char from A to Z, numbers, _ -> valid ID
113
+ String.prototype.asId = function () {
114
+ return this.replace(/[^a-zA-Z0-9_]+/g, '');
115
+ };
116
+
117
+ String.prototype.replaceAll= function(from, to){
118
+ return this.replace(new RegExp(RegExp.quote(from), 'g'),to);
119
+ };
120
+
121
+
122
+ if (!Array.prototype.indexOf) {
123
+ Array.prototype.indexOf = function (searchElement, fromIndex) {
124
+ if (this == null) {
125
+ throw new TypeError();
126
+ }
127
+ var t = Object(this);
128
+ var len = t.length >>> 0;
129
+ if (len === 0) {
130
+ return -1;
131
+ }
132
+ var n = 0;
133
+ if (arguments.length > 0) {
134
+ n = Number(arguments[1]);
135
+ if (n != n) { // shortcut for verifying if it's NaN
136
+ n = 0;
137
+ } else if (n != 0 && n != Infinity && n != -Infinity) {
138
+ n = (n > 0 || -1) * Math.floor(Math.abs(n));
139
+ }
140
+ }
141
+ if (n >= len) {
142
+ return -1;
143
+ }
144
+ var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0);
145
+ for (; k < len; k++) {
146
+ if (k in t && t[k] === searchElement) {
147
+ return k;
148
+ }
149
+ }
150
+ return -1;
151
+ };
152
+ }
153
+
154
+
155
+ Object.size = function(obj) {
156
+ var size = 0, key;
157
+ for (key in obj) {
158
+ if (obj.hasOwnProperty(key)) size++;
159
+ }
160
+ return size;
161
+ };
162
+
163
+
164
+ // transform string values to printable: \n in <br>
165
+ function transformToPrintable(data){
166
+ for (var prop in data) {
167
+ var value = data[prop];
168
+ if (typeof(value)=="string")
169
+ data[prop]=(value + "").replace(/\n/g, "<br>");
170
+ }
171
+ return data;
172
+ }
173
+
174
+
175
+ /* Types Function */
176
+
177
+ function isValidURL(url){
178
+ var RegExp = /^(([\w]+:)?\/\/)?(([\d\w]|%[a-fA-f\d]{2,2})+(:([\d\w]|%[a-fA-f\d]{2,2})+)?@)?([\d\w][-\d\w]{0,253}[\d\w]\.)+[\w]{2,4}(:[\d]+)?(\/([-+_~.\d\w]|%[a-fA-f\d]{2,2})*)*(\?(&?([-+_~.\d\w]|%[a-fA-f\d]{2,2})=?)*)?(#([-+_~.\d\w]|%[a-fA-f\d]{2,2})*)?$/;
179
+ return RegExp.test(url);
180
+ }
181
+
182
+ function isValidEmail(email){
183
+ var RegExp = /^((([a-z]|[0-9]|!|#|$|%|&|'|\*|\+|\-|\/|=|\?|\^|_|`|\{|\||\}|~)+(\.([a-z]|[0-9]|!|#|$|%|&|'|\*|\+|\-|\/|=|\?|\^|_|`|\{|\||\}|~)+)*)@((((([a-z]|[0-9])([a-z]|[0-9]|\-){0,61}([a-z]|[0-9])\.))*([a-z]|[0-9])([a-z]|[0-9]|\-){0,61}([a-z]|[0-9])\.)[\w]{2,4}|(((([0-9]){1,3}\.){3}([0-9]){1,3}))|(\[((([0-9]){1,3}\.){3}([0-9]){1,3})\])))$/;
184
+ return RegExp.test(email);
185
+ }
186
+
187
+ function isValidInteger(n) {
188
+ reg = new RegExp("^[-+]{0,1}[0-9]*$");
189
+ return reg.test(n);
190
+ }
191
+
192
+ function isValidDouble(n) {
193
+ var sep = Number.decimalSeparator;
194
+ reg = new RegExp("^[-+]{0,1}[0-9]*[" + sep + "]{0,1}[0-9]*$");
195
+ return reg.test(n);
196
+ }
197
+
198
+ function isValidTime(n) {
199
+ return !isNaN(millisFromHourMinute(n));
200
+ }
201
+
202
+ function isValidDurationDays(n) {
203
+ return !isNaN(daysFromString(n));
204
+ }
205
+
206
+ function isValidDurationMillis(n) {
207
+ return !isNaN(millisFromString(n));
208
+ }
209
+
210
+ function isValidDurationMillis(n) {
211
+ return !isNaN(millisFromString(n));
212
+ }
213
+
214
+
215
+ /*
216
+ supports almost all Java currency format e.g.: ###,##0.00EUR €#,###.00 #,###.00€ -$#,###.00 $-#,###.00
217
+ */
218
+ function isValidCurrency(numStr){
219
+ //first try to convert format in a regex
220
+ var regex="";
221
+ var format=Number.currencyFormat+"";
222
+
223
+ var minusFound=false;
224
+ var numFound=false;
225
+ var currencyString="";
226
+ var numberRegex="[0-9\\"+Number.groupingSeparator+"]+[\\"+Number.decimalSeparator+"]?[0-9]*";
227
+
228
+ for (var i=0; i<format.length; i++){
229
+ var ch= format.charAt(i);
230
+
231
+ if (ch=="." || ch=="," || ch=="0"){
232
+ //skip it
233
+ if(currencyString!=""){
234
+ regex=regex+"(?:"+RegExp.quote(currencyString)+")?";
235
+ currencyString="";
236
+ }
237
+
238
+ } else if (ch=="#") {
239
+ if(currencyString!=""){
240
+ regex=regex+"(?:"+RegExp.quote(currencyString)+")?";
241
+ currencyString="";
242
+ }
243
+
244
+ if (!numFound){
245
+ numFound=true;
246
+ regex=regex+numberRegex;
247
+ }
248
+
249
+ } else if (ch=="-"){
250
+ if(currencyString!=""){
251
+ regex=regex+"(?:"+RegExp.quote(currencyString)+")?";
252
+ currencyString="";
253
+ }
254
+ if (!minusFound){
255
+ minusFound=true;
256
+ regex=regex+ "[-]?";
257
+ }
258
+
259
+ } else {
260
+ currencyString=currencyString+ch;
261
+ }
262
+ }
263
+ if (!minusFound)
264
+ regex="[-]?"+regex;
265
+
266
+ if(currencyString!="")
267
+ regex=regex+"(?:"+RegExp.quote(currencyString)+")?";
268
+
269
+ regex="^"+regex+"$";
270
+
271
+ var rg=new RegExp(regex);
272
+ return rg.test(numStr);
273
+ }
274
+
275
+ function getCurrencyValue(numStr){
276
+ if (!isValidCurrency(numStr))
277
+ return NaN;
278
+
279
+ return parseFloat(numStr.replaceAll(Number.groupingSeparator,"").replaceAll(Number.decimalSeparator,".").replace(/[^0123456789.]/,""));
280
+ }
281
+
282
+
283
+ function formatCurrency(numberString) {
284
+ return formatNumber(numberString, Number.currencyFormat);
285
+ }
286
+
287
+
288
+ function formatNumber(numberString, format) {
289
+ if (!format)
290
+ format="##0.00";
291
+
292
+ var dec = Number.decimalSeparator;
293
+ var group = Number.groupingSeparator;
294
+ var neg = Number.minusSign;
295
+
296
+ var round = true;
297
+
298
+ var validFormat = "0#-,.";
299
+
300
+ // strip all the invalid characters at the beginning and the end
301
+ // of the format, and we'll stick them back on at the end
302
+ // make a special case for the negative sign "-" though, so
303
+ // we can have formats like -$23.32
304
+ var prefix = "";
305
+ var negativeInFront = false;
306
+ for (var i = 0; i < format.length; i++) {
307
+ if (validFormat.indexOf(format.charAt(i)) == -1) {
308
+ prefix = prefix + format.charAt(i);
309
+ } else {
310
+ if (i == 0 && format.charAt(i) == '-') {
311
+ negativeInFront = true;
312
+ } else {
313
+ break;
314
+ }
315
+ }
316
+ }
317
+ var suffix = "";
318
+ for (var i = format.length - 1; i >= 0; i--) {
319
+ if (validFormat.indexOf(format.charAt(i)) == -1)
320
+ suffix = format.charAt(i) + suffix;
321
+ else
322
+ break;
323
+ }
324
+
325
+ format = format.substring(prefix.length);
326
+ format = format.substring(0, format.length - suffix.length);
327
+
328
+ // now we need to convert it into a number
329
+ //while (numberString.indexOf(group) > -1)
330
+ // numberString = numberString.replace(group, '');
331
+ //var number = new Number(numberString.replace(dec, ".").replace(neg, "-"));
332
+ var number = new Number(numberString);
333
+
334
+
335
+ var forcedToZero = false;
336
+ if (isNaN(number)) {
337
+ number = 0;
338
+ forcedToZero = true;
339
+ }
340
+
341
+ // special case for percentages
342
+ if (suffix == "%")
343
+ number = number * 100;
344
+
345
+ var returnString = "";
346
+ if (format.indexOf(".") > -1) {
347
+ var decimalPortion = dec;
348
+ var decimalFormat = format.substring(format.lastIndexOf(".") + 1);
349
+
350
+ // round or truncate number as needed
351
+ if (round)
352
+ number = new Number(number.toFixed(decimalFormat.length));
353
+ else {
354
+ var numStr = number.toString();
355
+ numStr = numStr.substring(0, numStr.lastIndexOf('.') + decimalFormat.length + 1);
356
+ number = new Number(numStr);
357
+ }
358
+
359
+ var decimalValue = number % 1;
360
+ var decimalString = new String(decimalValue.toFixed(decimalFormat.length));
361
+ decimalString = decimalString.substring(decimalString.lastIndexOf(".") + 1);
362
+
363
+ for (var i = 0; i < decimalFormat.length; i++) {
364
+ if (decimalFormat.charAt(i) == '#' && decimalString.charAt(i) != '0') {
365
+ decimalPortion += decimalString.charAt(i);
366
+ } else if (decimalFormat.charAt(i) == '#' && decimalString.charAt(i) == '0') {
367
+ var notParsed = decimalString.substring(i);
368
+ if (notParsed.match('[1-9]')) {
369
+ decimalPortion += decimalString.charAt(i);
370
+ } else{
371
+ break;
372
+ }
373
+ } else if (decimalFormat.charAt(i) == "0"){
374
+ decimalPortion += decimalString.charAt(i);
375
+ }
376
+ }
377
+ returnString += decimalPortion;
378
+ } else{
379
+ number = Math.round(number);
380
+ }
381
+ var ones = Math.floor(number);
382
+ if (number < 0)
383
+ ones = Math.ceil(number);
384
+
385
+ var onesFormat = "";
386
+ if (format.indexOf(".") == -1)
387
+ onesFormat = format;
388
+ else
389
+ onesFormat = format.substring(0, format.indexOf("."));
390
+
391
+ var onePortion = "";
392
+ if (!(ones == 0 && onesFormat.substr(onesFormat.length - 1) == '#') || forcedToZero) {
393
+ // find how many digits are in the group
394
+ var oneText = new String(Math.abs(ones));
395
+ var groupLength = 9999;
396
+ if (onesFormat.lastIndexOf(",") != -1)
397
+ groupLength = onesFormat.length - onesFormat.lastIndexOf(",") - 1;
398
+ var groupCount = 0;
399
+ for (var i = oneText.length - 1; i > -1; i--) {
400
+ onePortion = oneText.charAt(i) + onePortion;
401
+ groupCount++;
402
+ if (groupCount == groupLength && i != 0) {
403
+ onePortion = group + onePortion;
404
+ groupCount = 0;
405
+ }
406
+ }
407
+
408
+ // account for any pre-data padding
409
+ if (onesFormat.length > onePortion.length) {
410
+ var padStart = onesFormat.indexOf('0');
411
+ if (padStart != -1) {
412
+ var padLen = onesFormat.length - padStart;
413
+
414
+ // pad to left with 0's or group char
415
+ var pos = onesFormat.length - onePortion.length - 1;
416
+ while (onePortion.length < padLen) {
417
+ var padChar = onesFormat.charAt(pos);
418
+ // replace with real group char if needed
419
+ if (padChar == ',')
420
+ padChar = group;
421
+ onePortion = padChar + onePortion;
422
+ pos--;
423
+ }
424
+ }
425
+ }
426
+ }
427
+
428
+ if (!onePortion && onesFormat.indexOf('0', onesFormat.length - 1) !== -1)
429
+ onePortion = '0';
430
+
431
+ returnString = onePortion + returnString;
432
+
433
+ // handle special case where negative is in front of the invalid characters
434
+ if (number < 0 && negativeInFront && prefix.length > 0)
435
+ prefix = neg + prefix;
436
+ else if (number < 0)
437
+ returnString = neg + returnString;
438
+
439
+ if (returnString.lastIndexOf(dec) == returnString.length - 1) {
440
+ returnString = returnString.substring(0, returnString.length - 1);
441
+ }
442
+ returnString = prefix + returnString + suffix;
443
+ return returnString;
444
+ }
445
+
446
+
447
+
448
+
449
+ RegExp.quote = function(str) {
450
+ return str.replace(/([.?*+^$[\]\\(){}-])/g, "\\$1");
451
+ };
452
+
453
+ /* ----- millis format --------- */
454
+ /**
455
+ * @param str - Striga da riempire
456
+ * @param len - Numero totale di caratteri, comprensivo degli "zeri"
457
+ * @param ch - Carattere usato per riempire
458
+ */
459
+ function pad(str, len, ch){
460
+ if ((str+"").length<len){
461
+ return new Array(len-(''+str).length+1).join(ch) + str;
462
+ } else{
463
+ return str
464
+ }
465
+ }
466
+
467
+ function getMillisInHours(millis) {
468
+ if (!millis)
469
+ return "";
470
+ var sgn=millis>=0?1:-1;
471
+ var hour = Math.floor(millis / 3600000);
472
+ return (sgn>0?"":"-")+pad(hour,2,"0");
473
+ }
474
+ function getMillisInHoursMinutes(millis) {
475
+ if (typeof(millis)!="number" )
476
+ return "";
477
+
478
+ var sgn=millis>=0?1:-1;
479
+ millis=Math.abs(millis);
480
+ var hour = Math.floor(millis / 3600000);
481
+ var min = Math.floor((millis % 3600000) / 60000);
482
+ return (sgn>0?"":"-")+pad(hour,1,"0") + ":" + pad(min,2,"0");
483
+ }
484
+
485
+ function getMillisInDaysHoursMinutes(millis) {
486
+ if (!millis)
487
+ return "";
488
+ // millisInWorkingDay is set on partHeaderFooter
489
+ var sgn=millis>=0?1:-1;
490
+ millis=Math.abs(millis);
491
+ var days = Math.floor(millis / millisInWorkingDay);
492
+ var hour = Math.floor((millis % millisInWorkingDay) / 3600000);
493
+ var min = Math.floor((millis-days*millisInWorkingDay-hour*3600000) / 60000);
494
+ return (sgn>=0?"":"-")+(days > 0 ? days + " " : "") + pad(hour,1,"0") + ":" + pad(min,2,"0");
495
+ }
496
+
497
+ function millisFromHourMinute(stringHourMinutes) { //All this format are valid: "12:58" "13.75" "63635676000" (this is already in milliseconds)
498
+ var result = 0;
499
+ stringHourMinutes.replace(",",".");
500
+ var semiColSeparator = stringHourMinutes.indexOf(":");
501
+ var dotSeparator = stringHourMinutes.indexOf(".");
502
+
503
+ if (semiColSeparator < 0 && dotSeparator < 0 && stringHourMinutes.length > 5) {
504
+ return parseInt(stringHourMinutes, 10); //already in millis
505
+ } else {
506
+
507
+ if (dotSeparator > -1) {
508
+ var d = parseFloat(stringHourMinutes);
509
+ result = d * 3600000;
510
+ } else {
511
+ var hour = 0;
512
+ var minute = 0;
513
+ if (semiColSeparator == -1)
514
+ hour = parseInt(stringHourMinutes, 10);
515
+ else {
516
+ hour = parseInt(stringHourMinutes.substring(0, semiColSeparator), 10);
517
+ minute = parseInt(stringHourMinutes.substring(semiColSeparator + 1), 10);
518
+ }
519
+ result = hour * 3600000 + minute * 60000;
520
+ }
521
+ if (typeof(result)!="number")
522
+ result=NaN;
523
+ return result;
524
+ }
525
+ }
526
+
527
+
528
+ /**
529
+ * @param string "3y 4d", "4D:08:10", "12M/3d", "2H4D", "3M4d,2h", "12:30", "11", "3", "1.5", "2m/3D", "12/3d", "1234"
530
+ * by default 2 means 2 hours 1.5 means 1:30
531
+ * @param considerWorkingdays if true day lenght is from global.properties CompanyCalendar.MILLIS_IN_WORKING_DAY otherwise in 24
532
+ * @return milliseconds. 0 if invalid string
533
+ */
534
+ function millisFromString(string,considerWorkingdays) {
535
+ if (!string)
536
+ return 0;
537
+
538
+ var regex = new RegExp("(\\d+[Yy])|(\\d+[M])|(\\d+[Ww])|(\\d+[Dd])|(\\d+[Hh])|(\\d+[m])|(\\d+[Ss])|(\\d+:\\d+)|(:\\d+)|(\\d*[\\.,]\\d+)|(\\d+)","g");
539
+
540
+ var matcher = regex.exec(string);
541
+ var totMillis=0;
542
+
543
+ if (!matcher)
544
+ return NaN;
545
+
546
+ while (matcher!=null) {
547
+ for (var i = 1; i < matcher.length; i++) {
548
+ var match = matcher[i];
549
+ if (match) {
550
+ var number = 0;
551
+ try {
552
+ number = parseInt(match);
553
+ } catch (e) {
554
+ }
555
+ if (i == 1) { // years
556
+ totMillis = totMillis + number * (considerWorkingdays ? millisInWorkingDay * workingDaysPerWeek * 52 : 3600000 * 24 * 365);
557
+ } else if (i == 2) { // months
558
+ totMillis = totMillis + number * (considerWorkingdays ? millisInWorkingDay * workingDaysPerWeek * 4 : 3600000 * 24 * 30);
559
+ } else if (i == 3) { // weeks
560
+ totMillis = totMillis + number * (considerWorkingdays ? millisInWorkingDay * workingDaysPerWeek : 3600000 * 24 * 7);
561
+ } else if (i == 4) { // days
562
+ totMillis = totMillis + number * (considerWorkingdays ? millisInWorkingDay : 3600000 * 24);
563
+ } else if (i == 5) { // hours
564
+ totMillis = totMillis + number * 3600000;
565
+ } else if (i == 6) { // minutes
566
+ totMillis = totMillis + number * 60000;
567
+ } else if (i == 7) { // seconds
568
+ totMillis = totMillis + number * 1000;
569
+ } else if (i == 8) { // hour:minutes
570
+ totMillis = totMillis + millisFromHourMinute(match);
571
+ } else if (i == 9) { // :minutes
572
+ totMillis = totMillis + millisFromHourMinute(match);
573
+ } else if (i == 10) { // hour.minutes
574
+ totMillis = totMillis + millisFromHourMinute(match);
575
+ } else if (i == 11) { // hours
576
+ totMillis = totMillis + number * 3600000;
577
+ }
578
+ }
579
+ }
580
+ matcher=regex.exec(string);
581
+ }
582
+
583
+ return totMillis;
584
+ }
585
+
586
+ /**
587
+ * @param string "3y 4d", "4D:08:10", "12M/3d", "2H4D", "3M4d,2h", "12:30", "11", "3", "1.5", "2m/3D", "12/3d", "1234"
588
+ * by default 2 means 2 hours 1.5 means 1:30
589
+ * @param considerWorkingdays if true day lenght is from global.properties CompanyCalendar.MILLIS_IN_WORKING_DAY otherwise in 24
590
+ * @return milliseconds. 0 if invalid string
591
+ */
592
+ function daysFromString(string,considerWorkingdays) {
593
+ if (!string)
594
+ return undefined;
595
+
596
+ var regex = new RegExp("(\\d+[Yy])|(\\d+[Mm])|(\\d+[Ww])|(\\d+[Dd])|(\\d*[\\.,]\\d+)|(\\d+)","g");
597
+
598
+ var matcher = regex.exec(string);
599
+ var totDays=0;
600
+
601
+ if (!matcher)
602
+ return NaN;
603
+
604
+ while (matcher != null) {
605
+ for (var i = 1; i < matcher.length; i++) {
606
+ var match = matcher[i];
607
+ if (match) {
608
+ var number = 0;
609
+ try {
610
+ number = parseInt(match);
611
+ } catch (e) {
612
+ }
613
+ if (i == 1) { // years
614
+ totDays = totDays + number * (considerWorkingdays ? workingDaysPerWeek * 52 : 365);
615
+ } else if (i == 2) { // months
616
+ totDays = totDays + number * (considerWorkingdays ? workingDaysPerWeek * 4 : 30);
617
+ } else if (i == 3) { // weeks
618
+ totDays = totDays + number * (considerWorkingdays ? workingDaysPerWeek : 7);
619
+ } else if (i == 4) { // days
620
+ totDays = totDays + number;
621
+ } else if (i == 5) { // days.minutes
622
+ totDays = totDays + number;
623
+ } else if (i == 6) { // days
624
+ totDays = totDays + number;
625
+ }
626
+ }
627
+ }
628
+ matcher=regex.exec(string);
629
+ }
630
+
631
+ return totDays;
632
+ }
633
+
634
+
635
+
636
+ /* Object Functions */
637
+
638
+ function stopBubble(e) {
639
+ if ($.browser.msie && event){
640
+ event.cancelBubble = true;
641
+ event.returnValue = false;
642
+
643
+ }else if (e){
644
+ e.stopPropagation();
645
+ e.preventDefault();
646
+ }
647
+ return false;
648
+ }
649
+
650
+ //validation functions - used by textfield and datefield
651
+ function validateField(ev) {
652
+ var el = $(this);
653
+ var rett=true;
654
+ el.clearErrorAlert();
655
+ // check serverside only if not empty
656
+ var value = el.val();
657
+ if (value) {
658
+
659
+ var type = el.attr('entryType').toUpperCase();
660
+
661
+ if (type == "INTEGER") {
662
+ rett = isValidInteger(value);
663
+ } else if (type == "DOUBLE") {
664
+ rett = isValidDouble(value);
665
+ } else if (type == "PERCENTILE") {
666
+ rett = isValidDouble(value);
667
+ } else if (type == "URL") {
668
+ rett = isValidURL(value);
669
+ } else if (type == "EMAIL") {
670
+ rett = isValidEmail(value);
671
+ } else if (type == "DURATIONMILLIS") {
672
+ rett = isValidDurationMillis(value);
673
+ } else if (type == "DURATIONDAYS") {
674
+ rett = isValidDurationDays(value);
675
+ } else if (type == "DATE") {
676
+ rett = Date.isValid(value,el.attr("format"));
677
+ } else if (type == "TIME") {
678
+ rett = isValidTime(value);
679
+ } else if (type == "CURRENCY") {
680
+ rett = isValidCurrency(value);
681
+ }
682
+
683
+ if (!rett) {
684
+ el.createErrorAlert(i18n.ERROR_ON_FIELD,i18n.INVALID_DATA);
685
+ }
686
+ }
687
+ return rett;
688
+ }
689
+
690
+ jQuery.fn.clearErrorAlert= function(){
691
+ this.each(function(){
692
+ var el = $(this);
693
+ el.removeAttr("invalid").removeClass("formElementsError");
694
+ $("#"+el.attr("id")+"error").remove();
695
+ });
696
+ return this;
697
+ };
698
+
699
+ jQuery.fn.createErrorAlert = function(errorCode, message) {
700
+ this.each(function() {
701
+ var el = $(this);
702
+ el.attr("invalid", "true").addClass("formElementsError");
703
+ if ($("#" + el.attr("id") + "error").size() <= 0) {
704
+ var errMess = (errorCode?errorCode:"") + ": " + (message?message:"");
705
+ var err = "<img width='17' heigh='17' id=\"" + el.attr("id") + "error\" error='1'";
706
+ err += " onclick=\"alert($(this).attr('title'))\" border='0' align='absmiddle'>";
707
+ err=$(err);
708
+ err.attr("title",errMess).attr("src","res/alert.gif");
709
+ el.after(err);
710
+ }
711
+ });
712
+ return this;
713
+ };
714
+
715
+
716
+ //errors =[{ceName:ceErrorCode},...]
717
+ function jsonErrorHandling(response){
718
+ if (!response.ok){
719
+ if (response.message)
720
+ alert("ERROR:\n"+ response.message);
721
+ for (var i in response.clientEntryErrors){
722
+ var err=response.clientEntryErrors[i];
723
+ $(":input[name="+err.name+"]").createErrorAlert(err.error);
724
+ }
725
+ }
726
+ }
727
+
728
+
729
+
730
+ // ---------------------------------- oldvalues management
731
+ // update all values selected
732
+ jQuery.fn.updateOldValue= function(){
733
+ this.each(function(){
734
+ var el = $(this);
735
+ el.data("_oldvalue",el.val());
736
+ });
737
+ return this;
738
+ };
739
+
740
+ // return true if at least one element has changed
741
+ jQuery.fn.isValueChanged=function (){
742
+ var ret=false;
743
+ this.each(function(){
744
+ var el = $(this);
745
+ if (el.val()+"" != el.data("_oldvalue") + ""){
746
+ //console.debug("io sono diverso "+el.attr("id")+ " :"+el.val()+" != "+el.data("_oldvalue"));
747
+ ret=true;
748
+ return false;
749
+ }
750
+ });
751
+ return ret;
752
+ };
753
+
754
+ jQuery.fn.getOldValue=function(){
755
+ return $(this).data("_oldvalue");
756
+ };
757
+
758
+
759
+
760
+
761
+ $.fn.unselectable=function(){
762
+ this.each(function(){
763
+ $(this).addClass("unselectable").attr("unselectable","on");
764
+ });
765
+ return $(this);
766
+ };
767
+
768
+ $.fn.clearUnselectable=function(){
769
+ this.each(function(){
770
+ $(this).removeClass("unselectable").removeAttr("unselectable");
771
+ });
772
+ return $(this);
773
+ };
774
+
775
+
776
+ // ---------------------------------- PROFILING ------------------------------------------
777
+ var __profiler = {};
778
+ /**
779
+ * usage: instantiate a new Profiler("a name") at the beginning of the code you want to profile var p= new Profiler("testLoop")
780
+ * call p.stop() at the end of the code you want test.
781
+ * call Profiler.displayAll() or p.display() to see how many times the code has been executed and millisecond spent.
782
+ * call Profiler.resetAll() or p.reset() to restart profiler.
783
+ * @param name
784
+ */
785
+ function Profiler(name) {
786
+ this.startTime = new Date().getTime();
787
+ this.name = name;
788
+
789
+ this.stop = function() {
790
+ if (!__profiler[this.name])
791
+ __profiler[this.name] = {millis:0,count:0};
792
+ __profiler[this.name].millis += new Date().getTime() - this.startTime;
793
+ __profiler[this.name].count++;
794
+ };
795
+ this.display = function() {
796
+ console.debug(__profiler[this.name]);
797
+ };
798
+
799
+ this.reset = function() {
800
+ delete __profiler[this.name];
801
+ };
802
+ }
803
+
804
+ Profiler.reset = function() {
805
+ __profiler = {};
806
+ };
807
+
808
+ Profiler.displayAll = function() {
809
+ var ret = "";
810
+ var totMillis = 0;
811
+ for (var key in __profiler) {
812
+ var p = __profiler[key];
813
+ var extraspace=" ".substr(0,30-key.length);
814
+ ret += key + extraspace+ "\t millis:" + p.millis+"\t count:" + p.count + "\n";
815
+ totMillis += p.millis;
816
+ }
817
+ console.debug(ret);
818
+ };
819
+
820
+
821
+ $(document).ready(function() {
822
+ $(":input[oldValue]").livequery(function(){$(this).updateOldValue();});
823
+ $('.validated').livequery('blur', validateField);
824
+ });
825
+
826
+ function openBlackPopup(url,width,height,onCloseCallBack,iframeId){
827
+ if(!iframeId)
828
+ iframeId="bwinPopup";
829
+
830
+ if (!width)
831
+ width='900px';
832
+ if (!height)
833
+ height='730px';
834
+
835
+ $("#__blackpopup__").remove();
836
+
837
+ var bg=$("<div>").attr("id","__blackpopup__");
838
+ //bg.css({position:'fixed',top:0, left:0,width:'100%',height:'100%', backgroundImage:"url('"+contextPath+"/applications/teamwork/images/black_70.png')",textAlign:'center'});
839
+ bg.css({position:'fixed',top:0, left:0,width:'100%',height:'100%',textAlign:'center'});
840
+
841
+ //add black only if not already in blackpupup
842
+ if(window.name!=iframeId)
843
+ bg.css({backgroundImage:"url('"+contextPath+"/applications/teamwork/images/black_70.png')"});
844
+
845
+ bg.append("<iframe id='"+iframeId+"' name='"+iframeId+"' frameborder='0'></iframe>");
846
+ bg.bringToFront();
847
+
848
+
849
+ //close call callback
850
+ bg.bind("close",function(){
851
+ bg.slideUp(300,function(){
852
+ bg.remove();
853
+ if (typeof(onCloseCallBack)=="function")
854
+ onCloseCallBack();
855
+ });
856
+ });
857
+
858
+ //destroy do not call callback
859
+ bg.bind("destroy",function(){
860
+ bg.remove();
861
+ });
862
+
863
+ bg.find("iframe:first").attr("src",url).css({width:width, height:height,top:100,border:'8px solid #909090', backgroundColor:'#ffffff'});
864
+
865
+ var bdiv= $("<div>").css({width:width,position:"relative",height:"5px", textAlign:"right", margin:"auto" });
866
+ bdiv.append("<img src=\"res/closeBig.png\" style='cursor:pointer;position:absolute;right:-40px;top:30px;'>");
867
+ bdiv.find("img:first").click( function(){
868
+ bg.trigger("close");
869
+
870
+ });
871
+
872
+ bg.prepend(bdiv);
873
+ $("body").append(bg);
874
+ }
875
+
876
+
877
+ //returns a jquery object where to write content
878
+ function createBlackPage(width,height,onCloseCallBack){
879
+ if (!width)
880
+ width='900px';
881
+ if (!height)
882
+ height='730px';
883
+
884
+ $("#__blackpopup__").remove();
885
+
886
+ var bg=$("<div>").attr("id","__blackpopup__");
887
+ bg.css({position:'fixed',top:"0px",paddingTop:"50px", left:0,width:'100%',height:'100%', backgroundImage:"url('res/img/black_70.png')"});
888
+ bg.append("<div id='bwinPopupd' name='bwinPopupd'></div>");
889
+ bg.bringToFront();
890
+
891
+ var ret=bg.find("#bwinPopupd");
892
+ ret.css({width:width, height:height,top:10, "-moz-box-shadow":'1px 1px 6px #333333',overflow:'auto',"-webkit-box-shadow":'1px 1px 6px #333333', border:'8px solid #777', backgroundColor:"#fff", margin:"auto" });
893
+
894
+ var bdiv= $("<div>").css({width:width,position:"relative",height:"0px", textAlign:"right", margin:"auto" });
895
+ var img=$("<img src='res/closeBig.png' style='cursor:pointer;position:absolute;right:-40px;top:5px;' title='close'>");
896
+ bdiv.append(img);
897
+ img.click( function(){
898
+ bg.trigger("close");
899
+ });
900
+
901
+ bg.prepend(bdiv);
902
+ $("body").append(bg);
903
+
904
+ //close call callback
905
+ bg.bind("close",function(){
906
+ bg.slideUp(300,function(){
907
+ bg.remove();
908
+ if (typeof(onCloseCallBack)=="function")
909
+ onCloseCallBack();
910
+ });
911
+ });
912
+
913
+ //destroy do not call callback
914
+ bg.bind("destroy",function(){
915
+ bg.remove();
916
+ });
917
+ return ret;
918
+ }
919
+
920
+
921
+ function getBlackPopup(){
922
+ var ret=$("#__blackpopup__");
923
+ if (typeof(top)!="undefined"){
924
+ ret= window.parent.$("#__blackpopup__");
925
+ }
926
+ return ret;
927
+ }
928
+
929
+
930
+ function closeBlackPopup(){
931
+ getBlackPopup().trigger("close");
932
+ }
933
+
934
+
935
+
936
+ //------------------------------------------------ TEAMWORK SPECIFIC FUNCTIONS --------------------------------------------------------
937
+ function openIssueEditorInBlack(issueId,command,params){
938
+ if (!command)
939
+ command="ED";
940
+ var editUrl=contextPath+"/applications/teamwork/issue/issueEditor.jsp?CM="+command+"&OBJID="+issueId;
941
+ if (params)
942
+ editUrl=editUrl+params;
943
+ openBlackPopup(editUrl,1020,$(window).height()-50, function(){$("#"+issueId).effect("highlight", { color: "yellow" }, 1500);});
944
+ }
945
+
946
+ function openBoardInBlack(boardId,command,params,callback){
947
+ if (!command)
948
+ command="ED";
949
+ var editUrl=contextPath+"/applications/teamwork/board/boardEditor.jsp?CM="+command+"&OBJID="+boardId;
950
+ if (params)
951
+ editUrl=editUrl+params;
952
+ openBlackPopup(editUrl,$(window).width()-100,$(window).height()-50,callback );
953
+ }
954
+