gantt_rails 0.0.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ /* http://keith-wood.name/svg.html
2
+ jQuery DOM compatibility for jQuery SVG v1.4.5.
3
+ Written by Keith Wood (kbwood{at}iinet.com.au) April 2009.
4
+ Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and
5
+ MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses.
6
+ Please attribute the author if you use it. */
7
+ eval(function(p,a,c,k,e,r){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('(7($){$.q.S=7(e){8 7(d){d=d||\'\';8 9.w(7(){k($.r.v(9)){l c=9;$.w(d.E(/\\s+/),7(i,a){l b=(c.o?c.o.p:c.B(\'z\'));k($.T(a,b.E(/\\s+/))==-1){b+=(b?\' \':\'\')+a;(c.o?c.o.p=b:c.H(\'z\',b))}})}x{e.A($(9),[d])}})}}($.q.S);$.q.U=7(e){8 7(d){d=d||\'\';8 9.w(7(){k($.r.v(9)){l c=9;$.w(d.E(/\\s+/),7(i,a){l b=(c.o?c.o.p:c.B(\'z\'));b=$.1d(b.E(/\\s+/),7(n,i){8 n!=a}).1e(\' \');(c.o?c.o.p=b:c.H(\'z\',b))})}x{e.A($(9),[d])}})}}($.q.U);$.q.V=7(c){8 7(a,b){8 9.w(7(){k($.r.v(9)){k(M b!==\'1f\'){b=!$(9).N(a)}$(9)[(b?\'1g\':\'1h\')+\'1i\'](a)}x{c.A($(9),[a,b])}})}}($.q.V);$.q.N=7(d){8 7(b){b=b||\'\';l c=I;9.w(7(){k($.r.v(9)){l a=(9.o?9.o.p:9.B(\'z\')).E(/\\s+/);c=($.T(b,a)>-1)}x{c=(d.A($(9),[b]))}8!c});8 c}}($.q.N);$.q.O=7(h){8 7(b,c,d){k(M b===\'W\'&&c===1j){l e=h.A(9,[b]);k(e&&e.p&&e.p.X!=J){c=\'\';e=e.p;k(b==\'1k\'){F(l i=0;i<e.X;i++){l f=e.Y(i);1l(f.1m){C 1:c+=\' u(\'+f.u.a+\',\'+f.u.b+\',\'+f.u.c+\',\'+f.u.d+\',\'+f.u.e+\',\'+f.u.f+\')\';D;C 2:c+=\' 1n(\'+f.u.e+\',\'+f.u.f+\')\';D;C 3:c+=\' 1o(\'+f.u.a+\',\'+f.u.d+\')\';D;C 4:c+=\' 1p(\'+f.P+\')\';D;C 5:c+=\' 1q(\'+f.P+\')\';D;C 6:c+=\' 1r(\'+f.P+\')\';D}}e=c.1s(1)}x{e=e.Y(0).Z}}8(e&&e.p?e.p.Z:e)}l g=b;k(M b===\'W\'){g={};g[b]=c}8 9.w(7(){k($.r.v(9)){F(l n 1t g){l a=($.1u(g[n])?g[n]():g[n]);(d?9.1v[n]=a:9.H(n,a))}}x{h.A($(9),[b,c,d])}})}}($.q.O);$.q.10=7(b){8 7(a){8 9.w(7(){k($.r.v(9)){(9[a]&&9[a].p?9[a].p.1w=\'\':9.H(a,\'\'))}x{b.A($(9),[a])}})}}($.q.10);$.1x($.1y,{\'1z\':K,\'1A\':K,\'1B\':K});k($.11){$.12=7(e){8 7(a,b,c){l d=(b.1C(/^r.*/)?$(a).O($.11[b]||b):\'\');8 d||e(a,b,c)}}($.12)}7 G(a){F(l i=0;i<a.13;i++){k(a[i].14==1&&a[i].1D==$.r.1E){8 K}}8 I}$.m.y[\'+\']=7(d){8 7(a,b,c){d(a,b,c||G(a))}}($.m.y[\'+\']);$.m.y[\'>\']=7(d){8 7(a,b,c){d(a,b,c||G(a))}}($.m.y[\'>\']);$.m.y[\'\']=7(d){8 7(a,b,c){d(a,b,c||G(a))}}($.m.y[\'\']);$.m.y[\'~\']=7(d){8 7(a,b,c){d(a,b,c||G(a))}}($.m.y[\'~\']);$.m.Q.15=7(d){8 7(a,b,c){8($.r.v(b)?[b.1F.1G(a[1])]:d(a,b,c))}}($.m.Q.15);l j=16.1H(\'1I\');j.1J(16.1K(\'\'));k(j.17(\'*\').13>0){$.m.Q.1L=7(a,b){l c=b.17(a[1]);k(a[1]===\'*\'){l d=[];F(l i=0;c[i]||c.L(i);i++){k((c[i]||c.L(i)).14===1){d.18(c[i]||c.L(i))}}c=d}8 c}}$.m.1M.19=7(a,b,c,d,f,g){a=\' \'+a[1].1N(/\\\\/g,\'\')+\' \';k(g){8 a}F(l i=0,t={};t!=J;i++){t=b[i];k(!t){1O{t=b.L(i)}1P(e){}}k(t){l h=(!$.r.v(t)?t.o:(t.o?t.o.p:\'\')||t.B(\'z\'));k(f^(h&&(\' \'+h+\' \').1a(a)>-1)){k(!c)d.18(t)}x k(c){b[i]=I}}}8 I};$.m.R.19=7(a,b){l c=(!$.r.v(a)?a.o:(a.o?a.o.p:a.B(\'z\')));8(\' \'+c+\' \').1a(b)>-1};$.m.R.1b=7(g){8 7(c,d){l e=J;k($.r.v(c)){e=d[1];$.m.1c[e]=7(a){l b=a.B(e);8 b&&b.p||b}}l f=g(c,d);k(e){$.m.1c[e]=J}8 f}}($.m.R.1b)})(1Q);',62,115,'|||||||function|return|this|||||||||||if|var|expr||className|baseVal|fn|svg||elem|matrix|isSVGElem|each|else|relative|class|apply|getAttribute|case|break|split|for|anySVG|setAttribute|false|null|true|item|typeof|hasClass|attr|angle|find|filter|addClass|inArray|removeClass|toggleClass|string|numberOfItems|getItem|valueAsString|removeAttr|cssProps|css|length|nodeType|ID|document|getElementsByTagName|push|CLASS|indexOf|ATTR|attrHandle|grep|join|boolean|add|remove|Class|undefined|transform|switch|type|translate|scale|rotate|skewX|skewY|substring|in|isFunction|style|value|extend|cssNumber|stopOpacity|strokeMitrelimit|strokeOpacity|match|namespaceURI|svgNS|ownerDocument|getElementById|createElement|div|appendChild|createComment|TAG|preFilter|replace|try|catch|jQuery'.split('|'),0,{}))
@@ -0,0 +1,142 @@
1
+ jQuery.fn.extend({
2
+ everyTime: function(interval, label, fn, times, belay) {
3
+ return this.each(function() {
4
+ jQuery.timer.add(this, interval, label, fn, times, belay);
5
+ });
6
+ },
7
+ oneTime: function(interval, label, fn) {
8
+ return this.each(function() {
9
+ jQuery.timer.add(this, interval, label, fn, 1);
10
+ });
11
+ },
12
+ stopTime: function(label, fn) {
13
+ return this.each(function() {
14
+ jQuery.timer.remove(this, label, fn);
15
+ });
16
+ }
17
+ });
18
+
19
+ jQuery.extend({
20
+ timer: {
21
+ guid: 1,
22
+ global: {},
23
+ regex: /^([0-9]+)\s*(.*s)?$/,
24
+ powers: {
25
+ // Yeah this is major overkill...
26
+ 'ms': 1,
27
+ 'cs': 10,
28
+ 'ds': 100,
29
+ 's': 1000,
30
+ 'das': 10000,
31
+ 'hs': 100000,
32
+ 'ks': 1000000
33
+ },
34
+ timeParse: function(value) {
35
+ if (value == undefined || value == null)
36
+ return null;
37
+ var result = this.regex.exec(jQuery.trim(value.toString()));
38
+ if (result[2]) {
39
+ var num = parseInt(result[1], 10);
40
+ var mult = this.powers[result[2]] || 1;
41
+ return num * mult;
42
+ } else {
43
+ return value;
44
+ }
45
+ },
46
+ add: function(element, interval, label, fn, times, belay) {
47
+ var counter = 0;
48
+
49
+ if (jQuery.isFunction(label)) {
50
+ if (!times)
51
+ times = fn;
52
+ fn = label;
53
+ label = interval;
54
+ }
55
+
56
+ interval = jQuery.timer.timeParse(interval);
57
+
58
+ if (typeof interval != 'number' || isNaN(interval) || interval <= 0)
59
+ return;
60
+
61
+ if (times && times.constructor != Number) {
62
+ belay = !!times;
63
+ times = 0;
64
+ }
65
+
66
+ times = times || 0;
67
+ belay = belay || false;
68
+
69
+ if (!element.$timers)
70
+ element.$timers = {};
71
+
72
+ if (!element.$timers[label])
73
+ element.$timers[label] = {};
74
+
75
+ fn.$timerID = fn.$timerID || this.guid++;
76
+
77
+ var handler = function() {
78
+ if (belay && this.inProgress)
79
+ return;
80
+ this.inProgress = true;
81
+ if ((++counter > times && times !== 0) || fn.call(element, counter) === false)
82
+ jQuery.timer.remove(element, label, fn);
83
+ this.inProgress = false;
84
+ };
85
+
86
+ handler.$timerID = fn.$timerID;
87
+
88
+ if (!element.$timers[label][fn.$timerID])
89
+ element.$timers[label][fn.$timerID] = window.setInterval(handler,interval);
90
+
91
+ if ( !this.global[label] )
92
+ this.global[label] = [];
93
+ this.global[label].push( element );
94
+
95
+ },
96
+ remove: function(element, label, fn) {
97
+ var timers = element.$timers, ret;
98
+
99
+ if ( timers ) {
100
+
101
+ if (!label) {
102
+ for ( label in timers )
103
+ this.remove(element, label, fn);
104
+ } else if ( timers[label] ) {
105
+ if ( fn ) {
106
+ if ( fn.$timerID ) {
107
+ window.clearInterval(timers[label][fn.$timerID]);
108
+ delete timers[label][fn.$timerID];
109
+ }
110
+ } else {
111
+ for ( var fn in timers[label] ) {
112
+ window.clearInterval(timers[label][fn]);
113
+ delete timers[label][fn];
114
+ }
115
+ }
116
+
117
+ for ( ret in timers[label] ) break;
118
+ if ( !ret ) {
119
+ ret = null;
120
+ delete timers[label];
121
+ }
122
+ }
123
+
124
+ for ( ret in timers ) break;
125
+ if ( !ret )
126
+ element.$timers = null;
127
+ }
128
+ }
129
+ }
130
+ });
131
+
132
+ if (jQuery.browser.msie)
133
+ jQuery(window).one("unload", function() {
134
+ var global = jQuery.timer.global;
135
+ for ( var label in global ) {
136
+ var els = global[label], i = els.length;
137
+ while ( --i )
138
+ jQuery.timer.remove(els[i], label);
139
+ }
140
+ });
141
+
142
+
@@ -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
+