").prop("id", "__popup__" + popupN);
180 | bg.addClass("modalPopup" + (isInIframe ? " inIframe" : "")).hide();
181 |
182 | if (cssClass)
183 | bg.addClass(cssClass);
184 |
185 | function getMarginTop(){
186 | var mt = ($(window).height() - popupHeight)/2 - 100;
187 | return mt < 0 ? 10 : mt;
188 | }
189 |
190 | var internalDiv=$("
").addClass("bwinPopupd").css({ width:popupWidth, minHeight:popupHeight, marginTop: getMarginTop(), maxHeight:$(window).height()-20, overflow: "auto" });
191 |
192 | $(window).off("resize.popup"+popupN).on("resize.popup"+popupN, function(){
193 |
194 | if(typeof localWidth == "function")
195 | popupWidth = localWidth();
196 |
197 | if(typeof localHeight == "function")
198 | popupHeight = localHeight();
199 |
200 | internalDiv.css({ width:popupWidth, minHeight:popupHeight });
201 |
202 | var w = internalDiv.outerWidth() > $(window).width()-20 ? $(window).width()-20 : popupWidth;
203 | var h = internalDiv.outerHeight() > $(window).height()-20 ? $(window).height()-20 : popupHeight;
204 |
205 | internalDiv.css({ marginTop: getMarginTop(), minHeight: h, maxHeight:$(window).height()-20,minWidth: w });
206 |
207 | });
208 |
209 | bg.append(internalDiv);
210 |
211 | var showBG = function(el, time, callback){
212 |
213 | if (isInIframe) {
214 | internalDiv.css({marginTop: -50 });
215 | el.show();
216 | internalDiv.animate({marginTop: 0}, (time/2), callback);
217 | } else {
218 | internalDiv.css({opacity: 0, top: -50}).show();
219 | el.fadeIn(time, function () {
220 | internalDiv.animate({top: 0, opacity: 1}, time/3, callback);
221 | });
222 | }
223 |
224 | /*
225 | if(isInIframe) {
226 | internalDiv.css({marginTop: -1000 });
227 | el.show();
228 | internalDiv.animate({marginTop: 0}, (time * 2), callback);
229 | }else{
230 | internalDiv.css({opacity:0, top: -500}).show();
231 | el.fadeIn(time, function(){
232 | internalDiv.animate({top: 0, opacity:1}, time, callback);
233 | });
234 | }
235 | */
236 |
237 | return this;
238 | };
239 |
240 | if(!element)
241 | $("#twMainContainer").addClass("blur");
242 |
243 | showBG(bg, 300, function(){})
244 | bg.on("click",function(event){
245 | if ($(event.target).closest(".bwinPopupd").length <= 0)
246 | bg.trigger("close");
247 | });
248 |
249 | var close = $("
x");
250 | internalDiv.append(close);
251 |
252 | close.click(function () {
253 | bg.trigger("close");
254 | });
255 |
256 | $("body").css({overflowY:"hidden"});
257 |
258 | if(!element){
259 | $("body").append(bg);
260 | }else{
261 | element.after(bg);
262 | }
263 |
264 | //close call callback
265 | bg.on("close", function () {
266 | var callBackdata = $(this).data("callBackdata");
267 | var ndo=bg;
268 |
269 | if (typeof (enableUploadize)=="function")
270 | enableUploadize();
271 |
272 | //console.debug("ndo",ndo);
273 |
274 | var alertMsg;
275 | var ifr=bg.find("iframe");
276 |
277 | if (ifr.length>0){
278 | try {
279 | alertMsg = ifr.get(0).contentWindow.alertOnUnload();
280 | }catch (e){}
281 | } else {
282 | alertMsg=alertOnUnload(ndo);
283 | }
284 |
285 | if (alertMsg){
286 | if (!confirm(alertMsg))
287 | return;
288 | }
289 |
290 | bg.fadeOut(100, function () {
291 |
292 | $(window).off("resize.popup"+popupN);
293 | bg.remove();
294 | __popups.pop();
295 |
296 | if (__popups.length == 0)
297 | $("#twMainContainer").removeClass("blur");
298 |
299 | if (typeof(onCloseCallBack) == "function")
300 | onCloseCallBack(callBackdata);
301 |
302 | $("body").css({overflowY: "auto"});
303 | });
304 |
305 | });
306 |
307 | //destroy do not call callback
308 | bg.on("destroy", function () {
309 | bg.remove();
310 | $("body").css({overflowY: "auto"});
311 | });
312 |
313 | //rise resize event in order to show buttons
314 | $("body").oneTime(1000,"br",function(){$(this).resize();}); // con meno di 1000 non funziona
315 |
316 |
317 | //si deposita l'popupOpener sul bg. Per riprenderlo si usa getBlackPopupOpener()
318 | bg.data("__opener",popupOpener);
319 |
320 | return internalDiv;
321 | }
322 |
323 | function changeModalSize(w,h){
324 | var newDim = {};
325 | if(w)
326 | newDim.width = w;
327 | if(h)
328 | newDim.minHeight = h;
329 |
330 | var isInIframe = isIframe();
331 | var popUp = isInIframe ? window.parent.$(".bwinPopupd") : $(".bwinPopupd");
332 |
333 | if(popUp.length)
334 | popUp.delay(300).animate(newDim, 200);
335 | }
336 |
337 | function openBlackPopup(url, width, height, onCloseCallBack, iframeId, cssClass) {
338 |
339 | if (!iframeId)
340 | iframeId = "bwinPopupIframe";
341 |
342 | //add black only if not already in blackpupup
343 | var color= cssClass ? cssClass + " iframe" : "iframe";
344 |
345 | var ndo = top.createModalPopup(width, height, onCloseCallBack, color,null,window);
346 |
347 | //ndo.closest(".modalPopup ").data("__opener",window); // si deposita il vero opener
348 |
349 | var isInIframe = isIframe();
350 |
351 | ndo.append("");
352 | ndo.find("iframe:first").prop("src", url).css({width:"100%", height:"100%", backgroundColor: isInIframe ? '#F9F9F9' : '#FFFFFF'});
353 | }
354 |
355 | function getBlackPopup() {
356 | var ret=$([]);
357 | if (__popups.length>0) {
358 | var id = __popups[__popups.length - 1];
359 | ret = $("#" + id);
360 | }
361 | if (ret.length==0 && window!=top) {
362 | ret = window.parent.getBlackPopup();
363 | }
364 | return ret;
365 | }
366 |
367 |
368 | function getBlackPopupOpener(){
369 | return getBlackPopup().data("__opener")
370 | }
371 |
372 | function closeBlackPopup(callBackdata) {
373 | //console.debug("closeBlackPopup ",callBackdata);
374 | var bp = getBlackPopup();
375 |
376 | if (callBackdata)
377 | bp.data("callBackdata",callBackdata);
378 | bp.trigger("close");
379 | }
380 |
381 | function openPopUp(el,width,height){
382 | var popup=createModalPopup(width,height);
383 | popup.append(el.clone().show());
384 | }
385 |
386 | //returns a jquery object where to write content
387 |
388 | function isIframe() {
389 | var isIframe = false;
390 | try{
391 | //try to access the document object
392 | if (self.location.href != top.location.href)
393 | isIframe = true;
394 | }catch(e) {
395 | //We don't have access, it's cross-origin!
396 | isIframe = true;
397 | }
398 | return isIframe;
399 | };
400 |
401 |
402 | function openBulkAction(bulkDivId){
403 | var popup=createModalPopup(500,300);
404 | popup.append($("#"+bulkDivId).clone().show());
405 | }
406 |
407 |
408 | function refreshBulk(el) {
409 | //console.debug("refreshBulk")
410 |
411 | if (el.is(":checked"))
412 | el.closest("tr").addClass("selected");
413 | else
414 | el.closest("tr").removeClass("selected");
415 |
416 | var table=el.closest(".dataTable");
417 | if (table.find(".selected :checked").length > 0) {
418 |
419 | $("#bulkOp #bulkRowSel").html(table.find("tbody > tr.selected").length + "/" + table.children("tbody").children("tr").length);
420 |
421 | var bukOpt = $("#bulkOp").clone().addClass("bulkOpClone");
422 | bukOpt.fadeIn(200, function(){
423 | $("#bulkPlace").html(bukOpt);
424 | $.tableHF.refreshTfoot();
425 | });
426 |
427 | } else {
428 | $(".bulkOpClone").fadeOut(200, function(){
429 | $.tableHF.refreshTfoot();
430 | });
431 | }
432 | }
433 |
434 | function selUnselAll(el){
435 | //var bulkCheckbox = $("#multi td [type='checkbox']");
436 | var bulkCheckbox = el.closest(".dataTable").find("[type='checkbox']");
437 | if (el.is(":checked")){
438 | bulkCheckbox.prop("checked", true);
439 | bulkCheckbox.closest("tr").addClass("selected");
440 | } else {
441 | bulkCheckbox.prop("checked", false);
442 | bulkCheckbox.closest("tr").removeClass("selected");
443 | }
444 |
445 | refreshBulk(el);
446 | }
447 |
--------------------------------------------------------------------------------
/libs/utilities.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2012-2017 Open Lab
3 | Permission is hereby granted, free of charge, to any person obtaining
4 | a copy of this software and associated documentation files (the
5 | "Software"), to deal in the Software without restriction, including
6 | without limitation the rights to use, copy, modify, merge, publish,
7 | distribute, sublicense, and/or sell copies of the Software, and to
8 | permit persons to whom the Software is furnished to do so, subject to
9 | the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be
12 | included in all copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 | */
22 |
23 |
24 |
25 | // works also for IE8 beta
26 | var isExplorer = navigator.userAgent.toUpperCase().indexOf("MSIE") >= 0 || !!navigator.userAgent.match(/Trident.*rv\:11\./);
27 | var isMozilla = navigator.userAgent.toUpperCase().indexOf("FIREFOX") >= 0;
28 | var isSafari = navigator.userAgent.toLowerCase().indexOf("safari") != -1 && navigator.userAgent.toLowerCase().indexOf('chrome') < 0;
29 |
30 | //Version detection
31 | var version = navigator.appVersion.substring(0, 1);
32 | var inProduction = false;
33 | if (inProduction) {
34 | window.console = undefined;
35 | }
36 |
37 | // deprecated use $("#domid")...
38 | function obj(element) {
39 | if (arguments.length > 1) {
40 | alert("invalid use of obj with multiple params:" + element)
41 | }
42 | var el = document.getElementById(element);
43 | if (!el)
44 | console.error("element not found: " + element);
45 | return el;
46 | }
47 |
48 | if (!window.console) {
49 | window.console = new function () {
50 | this.log = function (str) {/*alert(str)*/};
51 | this.debug = function (str) {/*alert(str)*/};
52 | this.error = function (str) {/*alert(str)*/};
53 | };
54 | }
55 | if (!window.console.debug || !window.console.error || !window.console.log) {
56 | window.console = new function () {
57 | this.log = function (str) {/*alert(str)*/};
58 | this.debug = function (str) {/*alert(str)*/};
59 | this.error = function (str) {/*alert(str)*/};
60 | };
61 | }
62 |
63 |
64 |
65 | String.prototype.trim = function () {
66 | return this.replace(/^\s*(\S*(\s+\S+)*)\s*$/, "$1");
67 | };
68 |
69 | String.prototype.startsWith = function (t, i) {
70 | if (!i) {
71 | return (t == this.substring(0, t.length));
72 | } else {
73 | return (t.toLowerCase() == this.substring(0, t.length).toLowerCase());
74 | }
75 | };
76 |
77 | String.prototype.endsWith = function (t, i) {
78 | if (!i) {
79 | return (t == this.substring(this.length - t.length));
80 | } else {
81 | return (t.toLowerCase() == this.substring(this.length - t.length).toLowerCase());
82 | }
83 | };
84 |
85 | // leaves only char from A to Z, numbers, _ -> valid ID
86 | String.prototype.asId = function () {
87 | return this.replace(/[^a-zA-Z0-9_]+/g, '');
88 | };
89 |
90 | String.prototype.replaceAll = function (from, to) {
91 | return this.replace(new RegExp(RegExp.quote(from), 'g'), to);
92 | };
93 |
94 |
95 | if (!Array.prototype.indexOf) {
96 | Array.prototype.indexOf = function (searchElement, fromIndex) {
97 | if (this == null) {
98 | throw new TypeError();
99 | }
100 | var t = Object(this);
101 | var len = t.length >>> 0;
102 | if (len === 0) {
103 | return -1;
104 | }
105 | var n = 0;
106 | if (arguments.length > 0) {
107 | n = Number(arguments[1]);
108 | if (n != n) { // shortcut for verifying if it's NaN
109 | n = 0;
110 | } else if (n != 0 && n != Infinity && n != -Infinity) {
111 | n = (n > 0 || -1) * Math.floor(Math.abs(n));
112 | }
113 | }
114 | if (n >= len) {
115 | return -1;
116 | }
117 | var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0);
118 | for (; k < len; k++) {
119 | if (k in t && t[k] === searchElement) {
120 | return k;
121 | }
122 | }
123 | return -1;
124 | };
125 | }
126 |
127 |
128 | Object.size = function (obj) {
129 | var size = 0, key;
130 | for (key in obj) {
131 | if (obj.hasOwnProperty(key)) size++;
132 | }
133 | return size;
134 | };
135 |
136 |
137 | // transform string values to printable: \n in
138 | function transformToPrintable(data) {
139 | for (var prop in data) {
140 | var value = data[prop];
141 | if (typeof(value) == "string")
142 | data[prop] = (value + "").replace(/\n/g, "
");
143 | }
144 | return data;
145 | }
146 |
147 |
148 | RegExp.quote = function (str) {
149 | return str.replace(/([.?*+^$[\]\\(){}-])/g, "\\$1");
150 | };
151 |
152 |
153 | /* Object Functions */
154 |
155 | function stopBubble(e) {
156 | e.stopPropagation();
157 | e.preventDefault();
158 | return false;
159 | }
160 |
161 |
162 | // ------ ------- -------- wraps http://www.mysite.com/....... with
163 | jQuery.fn.activateLinks = function (showImages) {
164 | var httpRE = /(['"]\s*)?(http[s]?:[\d]*\/\/[^"<>\s]*)/g;
165 | var wwwRE = /(['"/]\s*)?(www\.[^"<>\s]+)/g;
166 | var imgRE = /(['"]\s*)?(http[s]?:[\d]*\/\/[^"<>\s]*\.(?:gif|jpg|png|jpeg|bmp))/g;
167 |
168 |
169 | this.each(function () {
170 | var el = $(this);
171 | var html = el.html();
172 |
173 | if (showImages) {
174 | // workaround for negative look ahead
175 | html = html.replace(imgRE, function ($0, $1) {
176 | return $1 ? $0 : "";
177 | });
178 | }
179 |
180 | html = html.replace(httpRE, function ($0, $1) {
181 | return $1 ? $0 : "" + $0 + "";
182 | });
183 |
184 | html = html.replace(wwwRE, function ($0, $1) {
185 | return $1 ? $0 : "
" + $0 + "";
186 | });
187 |
188 | el.empty().append(html);
189 |
190 | if (showImages) {
191 | //inject expand capability on images
192 | el.find("div.imgWrap").each(function () {
193 | var imageDiv = $(this);
194 |
195 |
196 | imageDiv.click(function (e) {
197 | if (e.ctrlKey || e.metaKey) {
198 | window.open(imageDiv.find("img").prop("src"), "_blank");
199 | } else {
200 | var imageClone = imageDiv.find("img").clone();
201 | imageClone.mouseout(function () {
202 | $(this).remove();
203 | });
204 | imageClone.addClass("imageClone").css({"position":"absolute", "display":"none", "top":imageDiv.position().top, "left":imageDiv.position().left, "z-index":1000000});
205 | imageDiv.after(imageClone);
206 | imageClone.fadeIn();
207 | }
208 | });
209 | });
210 | }
211 |
212 | });
213 | return this;
214 | };
215 |
216 | jQuery.fn.emoticonize = function () {
217 | function convert(text) {
218 | var faccRE = /(:\))|(:-\))|(:-])|(:-\()|(:\()|(:-\/)|(:-\\)|(:-\|)|(;-\))|(:-D)|(:-P)|(:-p)|(:-0)|(:-o)|(:-O)|(:'-\()|(\(@\))/g;
219 | return text.replace(faccRE, function (str) {
220 | var ret = {":)":"smile",
221 | ":-)":"smile",
222 | ":-]":"polite_smile",
223 | ":-(":"frown",
224 | ":(":"frown",
225 | ":-/":"skepticism",
226 | ":-\\":"skepticism",
227 | ":-|":"sarcasm",
228 | ";-)":"wink",
229 | ":-D":"grin",
230 | ":-P":"tongue",
231 | ":-p":"tongue",
232 | ":-o":"surprise",
233 | ":-O":"surprise",
234 | ":-0":"surprise",
235 | ":'-(":"tear",
236 | "(@)":"angry"}[str];
237 | if (ret) {
238 | ret = "

";
239 | return ret;
240 | } else
241 | return str;
242 | });
243 | }
244 |
245 | function addBold(text) {
246 | var returnedValue;
247 | var faccRE = /\*\*[^*]*\*\*/ig;
248 | return text.replace(faccRE, function (str) {
249 | var temp = str.substr(2);
250 | var temp2 = temp.substr(0, temp.length - 2);
251 | return "
" + temp2 + "";
252 | });
253 | }
254 |
255 | this.each(function () {
256 | var el = $(this);
257 | var html = convert(el.html());
258 | html = addBold(html);
259 | el.html(html);
260 | });
261 | return this;
262 | };
263 |
264 |
265 | $.fn.unselectable = function () {
266 | this.each(function () {
267 | $(this).addClass("unselectable").attr("unselectable", "on");
268 | });
269 | return $(this);
270 | };
271 |
272 | $.fn.clearUnselectable = function () {
273 | this.each(function () {
274 | $(this).removeClass("unselectable").removeAttr("unselectable");
275 | });
276 | return $(this);
277 | };
278 |
279 | // ---------------------------------- initialize management
280 | var __initedComponents = new Object();
281 |
282 | function initialize(url, type, ndo) {
283 | //console.debug("initialize before: " + url);
284 | var normUrl = url.asId();
285 | var deferred = $.Deferred();
286 |
287 | if (!__initedComponents[normUrl]) {
288 | __initedComponents[normUrl] = deferred;
289 |
290 | if ("CSS" == (type + "").toUpperCase()) {
291 | var link = $("
").prop("href", url);
292 | $("head").append(link);
293 | deferred.resolve();
294 |
295 | } else if ("SCRIPT" == (type + "").toUpperCase()) {
296 | $.ajax({type: "GET",
297 | url: url + "?" + buildNumber,
298 | dataType: "script",
299 | cache: true,
300 | success: function () {
301 | //console.debug("initialize loaded:" + url);
302 | deferred.resolve()
303 | },
304 | error: function () {
305 | //console.debug("initialize failed:" + url);
306 | deferred.reject();
307 | }
308 | });
309 |
310 |
311 | } else {
312 | //console.debug(url+" as DOM");
313 | //var text = getContent(url);
314 | url = url + (url.indexOf("?") > -1 ? "&" : "?") + buildNumber;
315 | var text = $.ajax({
316 | type: "GET",
317 | url: url,
318 | dataType: "html",
319 | cache: true,
320 | success: function (text) {
321 | //console.debug("initialize loaded:" + url);
322 | ndo = ndo || $("body");
323 | ndo.append(text);
324 | deferred.resolve()
325 | },
326 | error: function () {
327 | //console.debug("initialize failed:" + url);
328 | deferred.reject();
329 | }
330 | });
331 | }
332 | }
333 |
334 | return __initedComponents[normUrl].promise();
335 | }
336 |
337 |
338 | /**
339 | * callback receive event, data
340 | * data.response contiene la response json arrivata dal controller
341 | * E.G.:
342 | * $("body").trigger("worklogEvent",[{type:"delete",response:response}])
343 | *
344 | * in caso di delete di solito c'è il response.deletedId
345 | */
346 | function registerEvent(eventName,callback) {
347 | $("body").off(eventName).on(eventName, callback);
348 | }
349 |
350 |
351 | function openPersistentFile(file) {
352 | //console.debug("openPersistentFile",file);
353 | var t=window.self;
354 | try{
355 | if(window.top != window.self)
356 | t=window.top;
357 | } catch(e) {}
358 |
359 | if (file.mime.indexOf("image") >= 0) {
360 | var img = $("
![]()
").prop("src", file.url).css({position: "absolute", top: "-10000px", left: "-10000px"}).one("load", function () {
361 | //console.debug("image loaded");
362 | var img = $(this);
363 | var w = img.width();
364 | var h = img.height();
365 | //console.debug("image loaded",w,h);
366 | var f=w/h;
367 | var ww = $(t).width()*.8;
368 | var wh = $(t).height()*.8;
369 | if (w>ww){
370 | w=ww;
371 | h=w/f;
372 | }
373 | if (h>wh){
374 | h=wh;
375 | w=h*f;
376 | }
377 |
378 | var hasTop=false;
379 | img.width(w).height(h).css({position: "static", top: 0, left: 0});
380 |
381 | t.createModalPopup(w+100,h+100).append(img);
382 | });
383 | t.$("body").append(img);
384 | } else if (file.mime.indexOf("pdf") >= 0) {
385 | t.openBlackPopup(file.url, $(t).width()*.8, $(t).height()*.8);
386 | } else {
387 | window.open(file.url + "&TREATASATTACH=yes");
388 | }
389 | }
390 |
391 |
392 | function wrappedEvaluer(toEval){
393 | eval(toEval);
394 | }
395 |
396 | function evalInContext(stringToEval,context){
397 | wrappedEvaluer.apply(context,[stringToEval]);
398 | }
399 |
400 |
401 | Storage.prototype.setObject = function(key, value) {
402 | this.setItem(key, JSON.stringify(value));
403 | };
404 |
405 | Storage.prototype.getObject = function(key) {
406 | return this.getItem(key) && JSON.parse(this.getItem(key));
407 | };
408 |
409 | function objectSize(size) {
410 | var divisor = 1;
411 | var unit = "bytes";
412 | if (size >= 1024 * 1024) {
413 | divisor = 1024 * 1024;
414 | unit = "MB";
415 | } else if (size >= 1024) {
416 | divisor = 1024;
417 | unit = "KB";
418 | }
419 | if (divisor == 1)
420 | return size + " " + unit;
421 |
422 | return (size / divisor).toFixed(2) + ' ' + unit;
423 | }
424 |
425 |
426 | function htmlEncode(value){
427 | //create a in-memory div, set it's inner text(which jQuery automatically encodes)
428 | //then grab the encoded contents back out. The div never exists on the page.
429 | return $('
').text(value).html();
430 | }
431 |
432 | function htmlLinearize(value, length){
433 | value = value.replace(/(\r\n|\n|\r)/gm,"").replace(/
/g, " - ");
434 | value = value.replace(/- -/g, "-");
435 |
436 | var ret = $('
').text(value).text();
437 |
438 | if(length){
439 | var ellips = ret.length > length ? "..." : "";
440 | ret = ret.substring(0,length) + ellips;
441 | }
442 |
443 | return ret;
444 | }
445 |
446 | function htmlDecode(value){
447 | return $('
').html(value).text();
448 | }
449 |
450 |
451 |
452 | function createCookie(name,value,days) {
453 | if (days) {
454 | var date = new Date();
455 | date.setTime(date.getTime()+(days*24*60*60*1000));
456 | var expires = "; expires="+date.toGMTString();
457 | }
458 | else var expires = "";
459 | document.cookie = name+"="+value+expires+"; path=/";
460 | }
461 |
462 | function readCookie(name) {
463 | var nameEQ = name + "=";
464 | var ca = document.cookie.split(';');
465 | for(var i=0;i < ca.length;i++) {
466 | var c = ca[i];
467 | while (c.charAt(0)==' ') c = c.substring(1,c.length);
468 | if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
469 | }
470 | return null;
471 | }
472 |
473 | function eraseCookie(name) {
474 | createCookie(name,"",-1);
475 | }
476 |
477 |
478 |
479 | function getParameterByName(name, url) {
480 | if (!url) url = window.location.href;
481 | name = name.replace(/[\[\]]/g, "\\$&");
482 | var regex = new RegExp("[?&]" + name + "(=([^]*)|&|#|$)"),
483 | results = regex.exec(url);
484 | if (!results) return null;
485 | if (!results[2]) return '';
486 | return decodeURIComponent(results[2].replace(/\+/g, " "));
487 | }
488 |
489 | $.fn.isEmptyElement = function( ){
490 | return !$.trim($(this).html())
491 | };
492 |
493 | //workaround for jquery 3.x
494 | if (typeof ($.fn.size)!="funcion")
495 | $.fn.size=function(){return this.length};
--------------------------------------------------------------------------------
/platform.css:
--------------------------------------------------------------------------------
1 | @font-face {
2 | font-family: 'TeamworkRegular';
3 | src: url('res/icons.eot?5qjga5');
4 | src: url('res/icons.eot?#iefix5qjga5') format('embedded-opentype'),
5 | url('res/icons.woff?5qjga5') format('woff'),
6 | url('res/icons.ttf?5qjga5') format('truetype'),
7 | url('res/icons.svg?5qjga5#icons') format('svg');
8 | font-weight: normal !important;
9 | font-style: normal;
10 | }
11 |
12 | * {
13 | -webkit-box-sizing: border-box;
14 | -moz-box-sizing: border-box;
15 | -o-box-sizing: border-box;
16 | box-sizing: border-box;
17 | }
18 |
19 | /*
20 | -------------------------------------------------------
21 | body styles
22 | -------------------------------------------------------
23 | */
24 | BODY, TBODY {
25 | font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif;
26 | /*font-family: 'Open Sans', sans-serif;*/
27 | font-size: 14px;
28 | margin: 0;
29 | color: #1e2f41;
30 | text-decoration: none;
31 | }
32 |
33 | a {
34 | text-decoration: none;
35 | font-weight: bold;
36 | /*color: #16ABDD;*/
37 | color: #2b9af3;
38 | text-rendering: optimizelegibility;
39 | -webkit-font-smoothing: antialiased;
40 | -moz-font-smoothing: antialiased;
41 |
42 | }
43 |
44 | a:hover, a.aHover {
45 | color: #0C85AD;
46 | color: #2575be;
47 | text-decoration: underline;
48 | }
49 |
50 | h1 {
51 | font-size: 32px;
52 | line-height: 34px;
53 | color: #91B4B7;
54 | font-weight: normal;
55 | margin: 0 0 10px 0
56 | }
57 |
58 | h2 {
59 | font-size: 28px;
60 | color: #34495e;
61 | font-weight: normal;
62 | margin: 0 0 10px 0
63 | }
64 |
65 | h3 {
66 | text-decoration: none;
67 | color: #1e2f41;
68 | font-size: 16px;
69 | margin: 0;
70 | }
71 |
72 | h4 {
73 | font-size: 16px;
74 | padding: 5px 0;
75 | color: #617777;
76 | margin: 0
77 | }
78 |
79 | #savingMessage {
80 | background-color: #E3EDED;
81 | display: none;
82 | color: #617777;
83 | font-weight: bolder;
84 | position: fixed;
85 | top: 0;
86 | left: 50%;
87 | width: 200px;
88 | text-align: center;
89 | margin-left: -100px;
90 | padding: 5px 0;
91 | z-index: 1000000;
92 | box-shadow: 0 3px 2px rgba(0, 0, 0, 0.4);
93 | -moz-box-shadow: 0 3px 2px rgba(0, 0, 0, 0.4);
94 | -webkit-box-shadow: 0 3px 2px rgba(0, 0, 0, 0.4);
95 | -o-box-shadow: 0 3px 2px rgba(0, 0, 0, 0.4);
96 | }
97 |
98 | .waiting {
99 | cursor: progress;
100 | }
101 |
102 | /*
103 | -------------------------------------------------------
104 | teamwork icon
105 | -------------------------------------------------------
106 | */
107 |
108 | .teamworkIcon {
109 | font-family: 'TeamworkRegular' !important;
110 | color: #34495e;
111 | font-weight: normal;
112 | font-size: 120%;
113 | font-style: normal !important;
114 | text-rendering: optimizelegibility;
115 | -webkit-font-smoothing: antialiased;
116 | -moz-font-smoothing: antialiased;
117 |
118 | }
119 |
120 | .teamworkIcon:hover {
121 | opacity: .8
122 | }
123 |
124 | .teamworkIcon.withLabel {
125 | padding-right: 5px;
126 | }
127 |
128 | .button:hover .teamworkIcon {
129 | opacity: 0.8
130 | }
131 |
132 | .teamworkIcon.alert {
133 | color: #B61E2D;
134 | }
135 |
136 | .del {
137 | color: #ff7271
138 | }
139 |
140 | .cvcColorSquare {
141 | display: inline-block;
142 | text-align: left;
143 | border: #fff 0px solid;
144 | box-shadow: 0px 0px 5px #999;
145 | -moz-box-shadow: 2px 2px 2px #999;
146 | -webkit-box-shadow: 0px 0px 5px #999;
147 | -o-box-shadow: 0px 0px 5px #999;
148 | text-indent: 10px;
149 | border-radius: 5px;
150 | cursor: pointer;
151 | }
152 |
153 | .cvcColorSquare:hover {
154 | opacity: .7;
155 | }
156 |
157 | .unselectable {
158 | -webkit-user-select: none;
159 | -khtml-user-select: none;
160 | -moz-user-select: none;
161 | -o-user-select: none;
162 | user-select: none;
163 | }
164 |
165 | .ui-resizable {
166 | position: relative;
167 | }
168 |
169 | .ui-resizable-handle {
170 | position: absolute;
171 | font-size: 0.1px;
172 | z-index: 99999;
173 | display: block;
174 | }
175 |
176 | .ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle {
177 | display: none;
178 | }
179 |
180 | .ui-resizable-n {
181 | cursor: n-resize;
182 | height: 7px;
183 | width: 100%;
184 | top: -5px;
185 | left: 0;
186 | }
187 |
188 | .ui-resizable-s {
189 | cursor: s-resize;
190 | height: 7px;
191 | width: 100%;
192 | bottom: -5px;
193 | left: 0;
194 | }
195 |
196 | .ui-resizable-e {
197 | cursor: e-resize;
198 | width: 7px;
199 | right: -5px;
200 | top: 0;
201 | height: 100%;
202 | }
203 |
204 | .ui-resizable-w {
205 | cursor: w-resize;
206 | width: 7px;
207 | left: -5px;
208 | top: 0;
209 | height: 100%;
210 | }
211 |
212 | .ui-resizable-se {
213 | cursor: se-resize;
214 | width: 12px;
215 | height: 12px;
216 | right: 1px;
217 | bottom: 1px;
218 | }
219 |
220 | .ui-resizable-sw {
221 | cursor: sw-resize;
222 | width: 9px;
223 | height: 9px;
224 | left: -5px;
225 | bottom: -5px;
226 | }
227 |
228 | .ui-resizable-nw {
229 | cursor: nw-resize;
230 | width: 9px;
231 | height: 9px;
232 | left: -5px;
233 | top: -5px;
234 | }
235 |
236 | .ui-resizable-ne {
237 | cursor: ne-resize;
238 | width: 9px;
239 | height: 9px;
240 | right: -5px;
241 | top: -5px;
242 | }
243 |
244 | /*
245 | -------------------------------------------------------
246 | table styles
247 | -------------------------------------------------------
248 | */
249 |
250 | .table {
251 | width: 100%;
252 | }
253 |
254 | TH, .tableHeader {
255 | font-weight: normal;
256 | color: #555;
257 | border: none;
258 | background-color: #f0f0f0;
259 | padding: 2px
260 | }
261 |
262 | .list td{
263 | border-bottom: 1px solid #dedede;
264 | padding: 5px 0;
265 | }
266 |
267 | .list th {
268 | padding: 5px 2px
269 | }
270 |
271 | .row em {font-style: normal;color: #a2a2a2}
272 |
273 |
274 | .ganttTaskEditor h2 {
275 | text-transform: capitalize
276 |
277 | }
278 |
279 | .ganttTaskEditor .formElements,
280 | .resourceEditor .formElements {
281 | background-color: #F5F5F5;
282 | border-color: #CECECE
283 | }
284 |
285 | table .resRow td, table .assigEditRow td {
286 | border-bottom: 1px solid #cecece;
287 | padding: 5px 0
288 | }
289 |
290 |
291 |
292 |
293 | /*
294 | -------------------------------------------------------
295 | Gantt Online
296 | -------------------------------------------------------
297 | */
298 |
299 |
300 | .servicesEnroll h2 {
301 | margin-bottom: 20px
302 | }
303 |
304 | .heading {
305 | text-align: center;
306 | }
307 | .heading img {
308 | display:block;
309 | margin: -20px auto 30px;
310 | }
311 |
312 |
313 | .twAds {
314 | height: 38px;
315 | background-color: #5ACADF;
316 | width: 100%;
317 | /*background-image: url("../../img/twAdBg.png");*/
318 | text-align: center;
319 | color: #fff;
320 | z-index: 1000;
321 | }
322 |
323 | .twAds.light {
324 | padding-top: 8px
325 | }
326 |
327 | .twAds .twitterButton {
328 | vertical-align: middle;
329 | display: inline-block;
330 | margin-left: 15px
331 | }
332 |
333 | .twAds .remove {
334 | display: inline-block;
335 | line-height: 38px;
336 | color: #fff;
337 | cursor: pointer;
338 | position: absolute;
339 | top:0;
340 | right: 12px
341 | }
342 |
343 | .twAds a {
344 | color: #fff;
345 | border-bottom: 1px solid rgba(255, 255, 255, 0.40)
346 | }
347 |
348 | .twAds a:hover {
349 | text-decoration: none
350 | }
351 |
352 | .servicesEnroll .oauth {
353 | width: 90px;
354 | height: auto;
355 | }
356 |
357 | .servicesEnroll .oauth:hover {
358 | opacity: .8
359 | }
360 |
361 | .errImg img {
362 | width: 25px;
363 | height: auto;
364 | vertical-align: middle;
365 | }
366 |
367 | #__FEEDBACKMESSAGEPLACE {
368 | position: absolute;
369 | background-color: #fafad2;
370 | }
371 |
372 | .adminLogin .formElements {
373 | width: 120px;
374 | }
375 |
376 | .adminLogin {
377 | width: 350px;
378 | margin: 0 auto;
379 | position: absolute;
380 | bottom: 10px;
381 | left: 20px;
382 | }
383 |
384 | .lastMod {
385 | font-style: italic;
386 | margin-right: 10px;
387 | vertical-align: middle;
388 | display: block;
389 | color: #D37E00;
390 | font-size: 12px;
391 | position: fixed;
392 | bottom: 25px;
393 | z-index: 20;
394 | padding: 5px 10px;
395 | background-color: rgba(255, 255, 0, 0.16);
396 | }
397 |
398 | .lastMod .teamworkIcon {
399 | color: #34495e;
400 | font-size: 160%;
401 | vertical-align: middle;
402 | }
403 |
404 | .button.textual,
405 | .button.buttonImg,
406 | .ganttButtonSeparator {
407 | vertical-align: middle;
408 | }
409 |
410 | .button span.teamworkIcon {
411 | font-size: .95em;
412 | }
413 |
414 | .clearfix:after {
415 | visibility: hidden;
416 | display: block;
417 | font-size: 0;
418 | content: " ";
419 | clear: both;
420 | height: 0;
421 | }
422 |
423 |
424 | .embedCode {
425 | font-family: Consolas,monospace!important;
426 | font-size: 100%;
427 | width: 100%;
428 | color: #2792E6;
429 | padding: 10px;
430 | border: 4px solid #d0d0d0
431 | }
432 |
433 | .ruler {
434 | width: 100%;
435 | display: block;
436 | padding: 35px 0 35px;
437 | height: 1px;
438 | }
439 |
440 | .ruler.short span {
441 | width: 100px;
442 | height: 1px;
443 | display: block;
444 | margin: 0 auto;
445 | border-bottom:1px solid #ccc
446 | }
447 |
448 |
449 | .clearfix { display: inline-block; }
450 | /* start commented backslash hack \*/
451 | * html .clearfix { height: 1%; }
452 | .clearfix { display: block; }
453 | /* close commented backslash hack */
454 |
455 |
456 |
457 | /*
458 | -------------------------------------------------------
459 | Buttons
460 | -------------------------------------------------------
461 | */
462 |
463 | .buttonBar {
464 | }
465 |
466 | .buttonBar.centered {
467 | text-align: center
468 | }
469 |
470 | .buttonBar.block .button {
471 | margin: 0 0 20px
472 | }
473 |
474 |
475 | .button {
476 | display: inline-block;
477 | font-size: 110%;
478 | color: #fff;
479 | cursor: pointer;
480 | background-color: #34495e;
481 | -moz-border-radius: 5px;
482 | -webkit-border-radius: 5px;
483 | -o-border-radius: 5px;
484 | border-radius: 5px;
485 | border: 1px solid rgba(0, 0, 0, 0.2);
486 | padding: 5px 12px 8px;
487 | margin-bottom: 10px;
488 | margin-right: 10px;
489 | text-align: center;
490 | -webkit-transition: background-color 500ms ease-out 1s;
491 | -moz-transition: background-color 500ms ease-out 1s;
492 | -o-transition: background-color 500ms ease-out 1s;
493 | transition: background-color 500ms ease-out 1s;
494 | }
495 |
496 | .button.first {
497 | background-color: #75a800;
498 | font-weight: bold;
499 | }
500 |
501 | .button.small {
502 | font-size: 100%;
503 | padding: 2px 7px 4px;
504 | margin-bottom: 0
505 |
506 | }
507 |
508 | .large {
509 | font-size: 160%;
510 | padding: 5px 14px 8px;
511 | border-radius: 6px
512 | }
513 |
514 |
515 |
516 | .button.first:hover {
517 | background-color: #2F2F2F;
518 | }
519 |
520 | .button[disabled] {
521 | cursor: default;
522 | opacity: 0.4
523 | }
524 |
525 | .button:hover[disabled] {
526 | background-color: #BABABA
527 | }
528 |
529 | .button.textual, .button.buttonImg {
530 | border: none;
531 | background-color: transparent;
532 | color: #68979B;
533 | -moz-border-radius: 0;
534 | -webkit-border-radius: 0;
535 | -o-border-radius: 0;
536 | border-radius: 0;
537 | padding: 0;
538 | margin: 0;
539 | text-align: left
540 | }
541 |
542 | .button.opt {
543 | background-color: #009E94;
544 | background-color: #2792E6;
545 | }
546 |
547 | .button.edit {
548 | color: #009E94;
549 | padding: 0;
550 | margin: 0
551 | }
552 |
553 | .button.delete {
554 | color: #B61E2D;
555 | padding: 0;
556 | margin: 0
557 | }
558 |
559 | .button:hover {
560 | background-color: #506b84;
561 | color: rgba(255, 255, 255, 0.75);
562 | }
563 |
564 | a.button:hover {
565 | text-decoration: none
566 | }
567 |
568 | .button.textual:hover, .button.buttonImg:hover {
569 | background-color: transparent;
570 | }
571 |
572 | span.separator {
573 | display: inline-block;
574 | }
575 |
576 | .button.add {
577 | color: #009E94;
578 | }
579 |
580 | .button.add .teamworkIcon {
581 | color: #009E94;
582 | }
583 |
584 | form {
585 | margin: 0;
586 | padding: 0;
587 | }
588 |
589 | select {
590 | border: 1px solid #91B4B7;
591 | padding: 4px;
592 | font-size: 16px;
593 | font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif;
594 | }
595 |
596 | .formElements {
597 | background-color: white;
598 | padding: 4px;
599 | font-size: 16px;
600 | border: 1px solid #91B4B7;
601 | -moz-border-radius: 3px;
602 | -webkit-border-radius: 3px;
603 | -o-border-radius: 3px;
604 | border-radius: 3px;
605 | font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif;
606 | }
607 |
608 | .formElementsError {
609 | border: 1px solid #ff0000;
610 | }
611 |
612 | .formElementExclamation {
613 | width: 15px;
614 | height: 25px;
615 | mmmargin-left: -20px;
616 | mmmposition: absolute;
617 | background: url("../../applications/gantt/distrib/res/alert.gif") no-repeat;
618 | }
619 |
620 | span#FLD_LOGIN_NAMEerror, span#FLD_PWDerror {
621 | margin-left: -23px;
622 | margin-top: 2px;
623 | }
624 |
625 | input {
626 | background-color: white;
627 | padding: 4px;
628 | font-size: 16px;
629 | border: 1px solid #91B4B7;
630 | -moz-border-radius: 3px;
631 | -webkit-border-radius: 3px;
632 | -o-border-radius: 3px;
633 | border-radius: 3px;
634 | font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif;
635 | }
636 |
637 | .confirmBox {
638 | display: inline;
639 | z-index: 10000;
640 | vertical-align: middle;
641 | text-align: center;
642 | font-style: italic;
643 | color: #777;
644 | background: #fff;
645 | position: absolute;
646 | margin: 0 auto
647 | }
648 |
649 |
650 |
651 | .confirmBox .confirmNo {
652 | color: #e06060;
653 | cursor: pointer;
654 | font-weight: bolder;
655 | }
656 |
657 | .confirmBox .confirmYes {
658 | color: #68af6c;
659 | cursor: pointer;
660 | font-weight: bolder;
661 | }
662 |
663 | .blackpopup {
664 | padding: 20px;
665 | border-radius: 10px;
666 | }
667 |
668 | .smallPopUp {
669 | top:0!important;
670 | margin-top:0!important;
671 | }
672 |
673 | iframe#bwinPopup {
674 | border-radius: 10px;
675 | }
676 |
677 | .mainWrap {
678 | padding: 20px
679 | }
680 |
681 | .mainWrap > h2:first-of-type {
682 | text-transform: capitalize
683 | }
684 |
685 |
686 | /******** SHARE BOX *********/
687 |
688 | .shareBar {
689 | position: absolute;
690 | right: 100px;
691 | top: 0;
692 | }
693 |
694 | .shareBar img:hover {
695 | opacity: 0.8;
696 | }
697 |
698 | .shareBtn {
699 | background: none repeat scroll 0 0 #F9F7F7;
700 | border: 1px solid rgba(0, 0, 0, 0.24);
701 | border-radius: 3px;
702 | color: #878686;
703 | display: inline-block;
704 | font-family: sans-serif;
705 | font-size: 12px;
706 | padding: 4px 8px 4px 14px;
707 | text-decoration: none;
708 | }
709 |
710 | .shareBtn {
711 | cursor: pointer;
712 | }
713 |
714 | .shareBtn:hover {
715 | border: 1px solid rgba(0, 0, 0, 0.24);
716 | color: #878686;
717 | opacity: .7;
718 | }
719 |
720 | .shareBtn img {
721 | border: 0 none;
722 | padding-right: 5px;
723 | vertical-align: middle;
724 | }
725 |
726 | .shareBtn a {
727 | color: #888;
728 | text-decoration: none;
729 | }
730 |
731 | #shareBox {
732 | text-align: center
733 | }
734 |
735 | #shareBox h2 {
736 | margin-bottom: 30px;
737 | }
738 |
739 |
740 | #shareBox .shareBtn {
741 | padding: 15px 20px;
742 | font-size: 30px;
743 | }
744 |
745 | #shareBox .shareBtn.icon-facebook {
746 | background-color:#3b5998;
747 | color: #fff;
748 | }
749 |
750 | #shareBox .shareBtn.icon-twitter {
751 | background-color:#00aced;
752 | color: #fff;
753 | }
754 |
755 | #shareBox .shareBtn.icon-linkedin {
756 | background-color:#007bb6;
757 | color: #fff;
758 | }
759 | #shareBox .shareBtn.icon-gplus {
760 | background-color:#dd4b39;
761 | color: #fff;
762 | }
763 |
764 | #shareBox .shareBtn span {
765 | display: none;
766 | }
767 |
768 |
769 | /*------------------------------------------------- MODAL POPUP (ex blackPopup) ------------------------------------------------------*/
770 | .modalPopup {
771 | position:fixed;
772 | top:0;
773 | left:0;
774 | width:100%;
775 | height:100%;
776 | background-color:rgba(255,255,255,.8);
777 | z-index: 100;
778 | }
779 |
780 | .modalPopup.upgradeMessage {
781 | top:40px;
782 | text-align: center;
783 | }
784 |
785 | .modalPopup.upgradeMessage p {
786 | margin-bottom: 20px;
787 | line-height: 1.6em;
788 | }
789 |
790 | .modalPopup.inIframe {
791 | background-color:rgba(255,255,255,0);
792 | }
793 |
794 | .modalPopup.black {
795 | background-color: rgba(75, 75, 75, 0.6);
796 | }
797 |
798 | .modalPopup .bwinPopupd{
799 | position: relative;
800 | box-shadow: 0 0 0 4px rgba(46, 186, 255, 0.3);
801 | border: 1px solid rgba(127, 127, 127, 0.3);
802 | background-color:#fff;
803 | margin:auto;
804 | padding: 30px 30px;
805 | border-radius: 5px;
806 | }
807 |
808 | .modalPopup .popUpClose{
809 | z-index: 9;
810 | color: #2f2f2f;
811 | width: 20px;
812 | height: 20px;
813 | text-align: center;
814 | line-height: 20px;
815 | right: 15px;
816 | top:15px;
817 | }
818 |
819 | .modalPopup.black .bwinPopupd .popUpClose{
820 | color: #ffffff;
821 | }
822 |
823 | .modalPopup.iframe .bwinPopupd {
824 | overflow: hidden;
825 | padding: 0;
826 | }
827 |
828 | .modalPopup.iframe .bwinPopupd iframe {
829 | position: absolute;
830 | border-radius: 5px;
831 | }
832 |
833 | .modalPopup.inIframe .bwinPopupd {
834 | background-color: #f9f9f9;
835 | border-radius: 0 0 5px 5px;
836 | }
837 |
838 | .offScreen {
839 | position: absolute;
840 | left: -5000px;
841 | }
842 |
843 |
--------------------------------------------------------------------------------
/gantt.css:
--------------------------------------------------------------------------------
1 |
2 | body{
3 | /*overflow: hidden;*/
4 | }
5 |
6 | .TWGanttWorkSpace.ganttFullScreen{
7 | position: fixed;
8 | top:0;
9 | left:0;
10 | bottom:0;
11 | right: 0;
12 | margin: auto;
13 | z-index: 1000;
14 | background-color: #fff;
15 | }
16 |
17 | /* -------------------------------------- GRIDIFY -----------------------------------*/
18 | .gdfTable {
19 | table-layout: fixed;
20 | border-collapse: separate;
21 | border-spacing: 0;
22 | background-color: #fff;
23 | }
24 |
25 | .gdfTable td, .gdfTable th {
26 | vertical-align: middle;
27 | overflow: hidden;
28 | text-overflow: clip;
29 | white-space: nowrap;
30 | font-size: 14px
31 | }
32 |
33 | .gdfCell {
34 | overflow: hidden;
35 | padding:4px 2px;
36 | border-bottom: 1px solid #eee;
37 | border-right: 1px solid #eee;
38 | font-family: arial, helvetica, sans-serif;
39 | }
40 |
41 | .gdfCell.noClip{
42 | overflow: visible;
43 | }
44 |
45 | .gdfColHeader {
46 | min-width: 5px;
47 | height: 30px;
48 | background-color: #eee;
49 | border-bottom:2px solid #bbb;
50 | border-right: 1px solid #bbb;
51 | }
52 |
53 | .gdfColHeader:last-of-type {
54 | border-right: none;
55 | }
56 |
57 | .gdfCell:last-of-type {
58 | border-right: none;
59 | }
60 |
61 |
62 | .gdfCellInput {
63 | border: 0 none;
64 | font-size: 12px;
65 | height: 20px;
66 | margin: 0;
67 | padding: 0;
68 | width: 100%;
69 | background-color: #d4fbe8;
70 | }
71 |
72 | .gdfCellWrap {
73 | border: 0 none;
74 | font-size: 12px;
75 | height: 17px;
76 | margin: 0;
77 | padding: 0;
78 | width: 100%;
79 | overflow: hidden;
80 |
81 | background-color: #ffcccc;
82 | }
83 |
84 | .gdfHResizing {
85 | cursor: w-resize;
86 | }
87 |
88 |
89 | /* -------------------------------------- SPLITTER -----------------------------------*/
90 | .splitterContainer {
91 | width: 100%;
92 | height: 100%;
93 | }
94 |
95 | .splitBox1{
96 | overflow-x: scroll;
97 | overflow-y: hidden;
98 | }
99 |
100 | .splitBox2 {
101 | overflow-x: scroll;
102 | overflow-y: auto;
103 | }
104 |
105 |
106 | .splitElement {
107 | outline-style: none;
108 | position: absolute;
109 | height: 100%;
110 | background-color: #f3f3f3;
111 | }
112 |
113 | .vSplitBar {
114 | position: relative;
115 | width: 5px;
116 | /*background-color: rgba(170, 170, 170, .2);*/
117 | cursor: ew-resize;
118 | text-align: center;
119 | color: white;
120 | box-shadow: 0 0 3px rgba(0, 0, 0, .4);
121 | background: rgba(170, 170, 170, .2) url("res/ganttSplitterGrip.png") no-repeat center center;
122 | z-index: 5;
123 | }
124 |
125 | .unselectable .vSplitBar, .vSplitBar:hover {
126 | background-color: rgba(170, 170, 170, .5);
127 | box-shadow: 0 0 5px rgba(0, 0, 0, .5);
128 |
129 | }
130 |
131 | .vSplitBar .toLeft,.vSplitBar .toRight,.vSplitBar .toCenter{
132 | font-family: icons,TeamworkRegular;
133 | cursor: pointer;
134 | position: absolute;
135 | top: 0;
136 | margin-top: 0;
137 | /*background-color: rgba(170, 170, 170, .2);*/
138 | /*background-color: rgba(0, 126, 221, 0.3);*/
139 | background-color: rgba(47, 170, 201, 0.3);
140 | z-index: 2;
141 | font-size: 10px;
142 | width: 15px;
143 | /*box-shadow: 0 0 1px rgba(0, 0, 0, .5);*/
144 | }
145 |
146 | .unselectable .vSplitBar .toLeft,.unselectable .vSplitBar .toCenter,.unselectable .vSplitBar .toRight, .vSplitBar:hover .toLeft, .vSplitBar:hover .toRight, .vSplitBar:hover .toCenter{
147 | /*background-color: rgba(170, 170, 170, 1);*/
148 | /*background-color: rgba(0, 126, 221, 1);*/
149 | background-color: rgba(47, 170, 201, 1);
150 |
151 | box-shadow: 0 0 1px rgba(0, 0, 0, .4);
152 | }
153 |
154 | .vSplitBar .toLeft {
155 | left: -19px;
156 | text-align: left;
157 | }
158 | .vSplitBar .toCenter{
159 | left:-4px;
160 | text-align: center;
161 | }
162 | .vSplitBar .toRight{
163 | left:10px;
164 | text-align: right;
165 | }
166 |
167 | .ganttFixHead{
168 | position: absolute;
169 | z-index: 2;
170 | top:0;
171 | /*background: #EEEEEE;*/
172 | height: 42px;
173 |
174 | }
175 |
176 | /* -------------------------------------- GANTT -----------------------------------*/
177 |
178 | .ganttTable{
179 | table-layout:fixed;
180 | background-color: #ffffff;
181 | }
182 |
183 | .ganttTable td,.ganttTable th{
184 | overflow: hidden;
185 | text-overflow: clip;
186 | white-space: nowrap;
187 | }
188 |
189 | .ganttHead1,.ganttHead2{
190 | height:20px;
191 | }
192 |
193 | .ganttHead1 th{
194 | border-left:1px solid #b0b0b0;
195 | padding: 0;
196 | margin: 0;
197 | /*border-right: 1px solid #bbb;*/
198 | border-bottom:1px solid #bbb;
199 | background: #EEEEEE;
200 | white-space: pre-line;
201 | word-break: break-all;
202 | }
203 |
204 | .ganttHead1 th,
205 | .ganttHead2 th{
206 | white-space: nowrap;
207 | overflow: hidden;
208 | }
209 |
210 | .ganttHead2 th{
211 | padding: 0;
212 | margin: 0;
213 | border-left:1px solid #b0b0b0;
214 | /*border-right: 1px solid #bbb;*/
215 | border-bottom:2px solid #bbb;
216 | background: #EEEEEE;
217 | }
218 |
219 | .ganttHead1 th.headSmall,.ganttHead2 th.headSmall{
220 | font-size: 10px;
221 | }
222 |
223 | .ganttToday{
224 | position:absolute;
225 | top:0;
226 | width:1px;
227 | height:100%;
228 | border-left:2px dotted #13AFA5;
229 | }
230 |
231 | .ganttTitle img {
232 | max-width: 150px;
233 | }
234 |
235 | .ganttButtonBar{
236 | position:relative;
237 | z-index: 2;
238 | /*background-color: #fff;*/
239 | border-bottom: 1px solid #959595;
240 | padding: 5px 0 5px 10px;
241 | }
242 |
243 | .dataTable .ganttButtonBar{
244 | border-bottom: none;
245 | }
246 |
247 | .ganttButtonBar .buttons {
248 | position: relative;
249 | display:inline-block;
250 | width: 100%;
251 | margin-top: 0;
252 | height: 45px;
253 | }
254 |
255 | .dataTable .ganttButtonBar .buttons {
256 | display:inline-block;
257 | width: 100%;
258 | }
259 |
260 | .ganttButtonBar .buttons button{
261 | vertical-align: middle;
262 | margin:0;
263 | outline: none;
264 | }
265 |
266 | .ganttButtonBar .buttons .button.textual.icon {
267 | height: 45px;
268 | }
269 |
270 |
271 | .button span.teamworkIcon {
272 | text-indent: -10px;
273 | }
274 |
275 |
276 | .button.textual span.teamworkIcon {
277 | font-size: 140%
278 | }
279 |
280 | #saveGanttButton {
281 | margin-left:20px;
282 | padding: 5px 12px;
283 | margin-bottom: 0;
284 | vertical-align: middle;
285 | }
286 |
287 |
288 | .ganttButtonSeparator{
289 | border-left:1px solid #dadada;
290 | margin:0 10px;
291 | font-size: 130%;
292 | vertical-align: middle;
293 | }
294 |
295 | .ganttLines{
296 | position:absolute;
297 | width:100%;
298 | height:1px;
299 | border-top:1px solid #eee;
300 | z-index:1;
301 | }
302 |
303 | .ganttLinks{
304 | z-index:10;
305 | }
306 |
307 |
308 | .ganttTable td.end{
309 | border-right: 2px dotted #ddd;
310 | }
311 |
312 | .ganttHead2 th.holyH{
313 | background-color: rgba(236, 195, 176, 0.40);
314 | }
315 | .ganttBodyCell.holy{
316 | background-color: rgba(255, 245, 230, 0.51);
317 | }
318 |
319 |
320 | /* -------------------------------------- TASK -----------------------------------*/
321 |
322 | .taskBoxDiv{
323 | position:absolute;
324 | height:25px;
325 | margin-top:3px;
326 | z-index:100;
327 | }
328 |
329 | .taskBoxDiv .layout {
330 | height:100%;
331 | color:#DB2727;
332 | border-radius:2px;
333 | background: #eee; /* Old browsers */
334 | border:1px solid #bbb;
335 | }
336 |
337 | .taskBoxDiv .taskStatus {
338 | left:5px;
339 | top:10px;
340 | position:absolute;
341 | width:10px;
342 | height:10px;
343 | }
344 |
345 | .taskBoxDiv .layout .milestone{
346 | top:0;
347 | position:absolute;
348 | width:18px;
349 | background: url(res/milestone.png) no-repeat;
350 | height:18px;
351 | display:none;
352 | }
353 | .taskBoxDiv .layout .milestone.end{
354 | right:0;
355 | }
356 | .taskBoxDiv .layout .milestone.active{
357 | display:block;
358 | }
359 |
360 | .taskBoxDiv.hasChild .layout{
361 | border-top:2px solid black;
362 | }
363 |
364 | .taskBoxDiv .taskProgress{
365 | height:5px;
366 | position:absolute;
367 | }
368 |
369 | .taskBoxDiv .layout.extDep{
370 | background-image:url(res/hasExternalDeps.png);
371 | }
372 |
373 |
374 | .taskLabel{
375 | position:absolute;
376 | height:28px;
377 | color:black;
378 | text-align:right;
379 | padding-right:5px;
380 | overflow:hidden;
381 | left:-200px;
382 | width:195px;
383 | white-space:nowrap;
384 | }
385 |
386 |
387 | .taskDepLine {
388 | border: 1px solid #9999ff;
389 | overflow: hidden;
390 | position: absolute;
391 | }
392 |
393 |
394 | .taskEditRow,.emptyRow {
395 | height:30px;
396 | }
397 |
398 | .taskEditRow input, .columnWidthTest{
399 | border: 0 none;
400 | font-size: 14px;
401 | height: 20px;
402 | margin: 0;
403 | padding:0;
404 | outline: 0;
405 | width: 100%;
406 | border-radius: 0;
407 | vertical-align: text-bottom;
408 | }
409 |
410 | .taskEditRow input[type=checkbox]{
411 | transform:scale(.7);
412 | width:15px;
413 | height: 15px;
414 | }
415 |
416 | .columnWidthTest{
417 | width: auto;
418 | }
419 |
420 | .taskEditRow input:focus{
421 | font-weight: bold;
422 | }
423 |
424 | .taskEditRow input{
425 | background-color: transparent;
426 | }
427 |
428 | .taskEditRow.rowSelected td{
429 | background-color:rgb(234, 248, 255);
430 | }
431 |
432 |
433 | .isGanttList .taskEditRow:nth-child(odd), .assigEditRow:nth-child(odd){
434 | background-color: #ffffff;
435 | }
436 | .isGanttList .taskEditRow:nth-child(even), .assigEditRow:nth-child(even){
437 | background-color: #ffffff;
438 | }
439 |
440 | input[readonly]{
441 | color: #c0c0c0;
442 | }
443 |
444 | .taskStatusBox{
445 | position:absolute;
446 | /*width:100px;*/
447 | height:26px;
448 | border:1px solid #a0a0a0;
449 | background-color:#fff;
450 | margin-top:-21px;
451 | margin-left:-2px;
452 | padding: 4px;
453 | z-index: 100;
454 | }
455 | .taskStatus{
456 | width:15px;
457 | height:15px;
458 | display:inline-block;
459 | text-indent: 0;
460 | position:relative;
461 | box-shadow: none;
462 | border-radius: 50%;
463 | border:0;
464 | cursor: pointer;
465 | }
466 | .taskStatus[status=STATUS_ACTIVE]{
467 | background-color: #3BBF67;
468 | color: #fff;
469 | }
470 | .taskStatus[status=STATUS_DONE]{
471 | background-color: #6EBEF4;
472 | color:#000;
473 | }
474 | .taskStatus[status=STATUS_FAILED]{
475 | background-color: #763A96;
476 | color: #fff;
477 | }
478 | .taskStatus[status=STATUS_SUSPENDED]{
479 | background-color: #F9C154;
480 | color:#000;
481 | }
482 | .taskStatus[status=STATUS_UNDEFINED]{
483 | background-color: #dededf;
484 | color:#000;
485 | }
486 | .taskStatus.selected{
487 | border:#666 2px solid;
488 | }
489 |
490 | select.taskStatus{
491 | width: auto;
492 | height: auto;
493 | border-radius: 2px;
494 | }
495 |
496 | .assigsTableWrapper{
497 | position: relative;
498 | height: 150px;
499 | overflow: auto;
500 | margin-top: -20px;
501 | }
502 |
503 | .unselectable {
504 | -webkit-user-select: none;
505 | -khtml-user-select: none;
506 | -moz-user-select: none;
507 | -o-user-select: none;
508 | user-select: none;
509 | }
510 |
511 |
512 | .exp-controller{
513 | display:inline-block;
514 | width:16px;
515 | height:16px;
516 | position: relative;
517 | top: 2px;
518 | margin-left: -18px;
519 | }
520 |
521 | .isParent .exp-controller{
522 | background-image: url(res/toggle_collapse.png);
523 | }
524 |
525 | .isParent.collapsed .exp-controller{
526 | cursor: pointer;
527 | background-image: url(res/toggle-expand.png);
528 | }
529 |
530 | .ui-resizable-helper { border: 1px dotted #00F; }
531 | .ui-resizable-e, .ui-resizable-w {width: 5px;}
532 | .ui-draggable{
533 | cursor:move;
534 | }
535 |
536 | /*--------------------------------------------------- SVG --------------------------------------------------*/
537 | .ganttSVGBox{
538 | position: absolute;
539 | top:0;
540 | left: 0;
541 | height: 100%;
542 | background-color: transparent;
543 | width: 100%;
544 | overflow-y: hidden; /*IE11 bug*/
545 | }
546 |
547 | .taskBoxSVG{
548 | overflow: visible;
549 | }
550 |
551 | .taskBoxSVG .taskLayout{
552 | stroke-width:0;
553 | stroke:#999;
554 | }
555 |
556 | .taskLinkPathSVG{
557 | stroke: rgba(47, 151, 198, 1);
558 | /*stroke:#9999ff;*/
559 | stroke-width:2.5px;
560 | fill:none;
561 | cursor:pointer;
562 | }
563 |
564 | .ganttLinesSVG{
565 | fill:transparent;
566 | stroke-width:1;
567 | stroke:#eee;
568 | }
569 |
570 | .isGanttList .ganttLinesSVG:nth-child(even){
571 | fill:transparent;
572 | stroke-width:1;
573 | stroke:#fff;
574 |
575 | }
576 | .isGanttList .ganttLinesSVG:nth-child(odd){
577 | fill:transparent;
578 | stroke-width:1;
579 | stroke:#eee;
580 | }
581 |
582 | .ganttLinesSVG.rowSelected{
583 | fill: rgb(234, 248, 255) !important;
584 | /*fill: rgba(255, 255, 153, 0.50) !important;*/
585 | }
586 |
587 | .ganttTodaySVG{
588 | stroke-width:2px;
589 | stroke:#e06671;
590 | stroke-linecap:"round";
591 | stroke-dasharray:2,2;
592 | }
593 |
594 | .colorByStatus .taskStatusSVG[status=STATUS_ACTIVE]{
595 | fill: #3BBF67;
596 | }
597 | .colorByStatus .taskStatusSVG[status=STATUS_DONE]{
598 | fill: #6EBEF4;
599 | }
600 | .colorByStatus .taskStatusSVG[status=STATUS_FAILED]{
601 | fill: #763A96;
602 | }
603 | .colorByStatus .taskStatusSVG[status=STATUS_SUSPENDED]{
604 | fill: #f9c154;
605 | }
606 | .colorByStatus .taskStatusSVG[status=STATUS_UNDEFINED]{
607 | fill: #dededf;
608 | }
609 | .colorByStatus .taskStatusSVG[status=STATUS_UNDEFINED] .taskLayout{
610 | stroke: #ccc;
611 | stroke-width:1;
612 | }
613 |
614 | .colorByStatus .taskStatusSVG[status=STATUS_DONE] .textPerc,
615 | .colorByStatus .taskStatusSVG[status=STATUS_ACTIVE] .textPerc,
616 | .colorByStatus .taskStatusSVG[status=STATUS_FAILED] .textPerc{
617 | fill: #fff;
618 | }
619 |
620 | .deSVG.deSVGdrag {
621 | cursor: move;
622 | }
623 |
624 | .deSVG.deSVGhand {
625 | cursor: ew-resize;
626 | }
627 |
628 | .linkHandleSVG{
629 | display:none;
630 | stroke:transparent;
631 | stroke-width:5;
632 | fill: rgba(47, 151, 198, 0.7);
633 | cursor: pointer;
634 | }
635 |
636 | .linkLineSVG{
637 | stroke-width:5px;
638 | stroke: rgba(47, 151, 198, 0.7);
639 | stroke-linecap:"round";
640 | opacity: .5;
641 | }
642 |
643 | .linkOnProgress .deSVG.taskBoxSVG {
644 | cursor:cell;
645 | }
646 |
647 | .taskBoxSVG.linkOver .taskLayout{
648 | stroke-width:1px;
649 | stroke:rgba(47, 151, 198, 0.7);
650 | opacity: 1;
651 | }
652 |
653 | .taskLabelSVG {
654 | stroke: none;
655 | fill:#999;
656 | font-size: 12px;
657 | }
658 |
659 | .critical .taskLinkPathSVG{
660 | stroke:red;
661 | }
662 |
663 | .taskBoxSVG.critical .taskLayout{
664 | stroke:red;
665 | }
666 |
667 | .focused .taskLinkPathSVG{
668 | stroke-width:5px;
669 | stroke: rgba(47, 151, 198, 0.7);
670 | }
671 |
672 | .taskBoxSVG.focused .taskLayout{
673 | stroke-width:3px;
674 | stroke: rgba(47, 151, 198, 0.7);
675 | }
676 |
677 | .taskBoxSVG.critical .taskLayout{
678 | stroke-width:3px;
679 | stroke: rgba(255, 0, 0, 0.7);
680 | }
681 |
682 |
683 |
684 | /*--------------------------------------------------- RESOURCE ADD --------------------------------------------------*/
685 | .ganttAddResource{
686 | position: absolute;
687 | width: 660px;
688 | height: 300px;
689 | border: 1px solid red;
690 | background-color: white;
691 | box-shadow: 0 0 5px rgba(0,0,0,0.3);
692 | top:120px;
693 | left:70px;
694 | z-index: 200;
695 | padding: 10px;
696 | }
697 |
698 | .ganttAddResource tr.isCompany{
699 | display:none;
700 | }
701 |
702 | .ganttAddResource.isCompany tr.isCompany{
703 | display:table-row;
704 | }
705 | .ganttAddResource.isCompany tr.isPerson{
706 | display:none;
707 | }
708 | .ganttAddResourceBG {
709 | position: absolute;
710 | width: 100%;
711 | height: 100%;
712 | top: 0;
713 | left: 0;
714 | background-color: rgba(0, 0, 0, .3);
715 | z-index: 200;
716 | }
717 |
718 |
719 | /*---------------------------------#LOG_CHANGES_CONTAINER --------------------------------------------*/
720 | #LOG_CHANGES_CONTAINER{
721 | display: none;
722 | width: 300px;
723 | top:-130px;
724 | margin-left: -35px
725 | }
726 |
727 |
728 | .userProfile {
729 | font-size: 16px;
730 | vertical-align: middle;
731 | text-align: right;
732 | margin: 0 5px 0 0;
733 | padding: 5px;
734 | float: right;
735 | position: relative;
736 | z-index: 50;
737 | line-height: 40px;
738 | vertical-align: middle;
739 | position: absolute;
740 | right: 0;
741 | }
742 |
743 | .userLine {
744 | max-width: 150px;
745 | display: inline-block;
746 | text-overflow: ellipsis;
747 | overflow: hidden;
748 | white-space: nowrap;
749 | margin: 0;padding: 0;
750 | vertical-align: middle;
751 | }
752 |
753 | .avatar {
754 | vertical-align: middle;
755 | padding: 1px;
756 | width: 27px;
757 | height: 27px;
758 | border: 1px solid #dedede
759 | }
760 |
761 | /*--------------------------------------------------- Media queries --------------------------------------------------*/
762 |
763 | /* Large screens */
764 |
765 | @media only screen and (max-width : 1260px) {
766 |
767 | .ganttButtonBar .button span.teamworkIcon {
768 | font-size: 130%;
769 | }
770 | .userLine {
771 | display: none;
772 | }
773 |
774 | }
775 |
776 | @media only screen and (min-width : 1261px) and (max-width : 1320px) {
777 |
778 | .ganttButtonBar .button span.teamworkIcon {
779 | font-size: 130%;
780 | }
781 |
782 | .button {
783 | font-size: 100%;
784 | padding: 3px 9px 6px;
785 | margin-right: 5px;
786 | margin-bottom: 5px
787 | }
788 |
789 | .userLine {
790 | display: none;
791 | }
792 |
793 | }
794 |
795 | @media only screen and (max-width : 1160px) {
796 |
797 | .userProfile {
798 | float: none;
799 | position: absolute;
800 | top:0;
801 | right: 10px;
802 | }
803 |
804 | .userProfile .teamworkIcon {
805 | color: rgb(255, 255, 255);
806 | }
807 | .userProfile .ganttButtonSeparator, .userProfile .avatar {
808 | border-color: rgb(127, 154, 170);
809 | }
810 |
811 | }
812 |
813 | /* Ipad */
814 |
815 | @media only screen and (min-width: 768px) and (max-width: 1024px){
816 | .ganttButtonSeparator {
817 | margin-left: 2px;
818 | padding-right: 6px;
819 | font-size: 100%;
820 | }
821 | .button {
822 | padding: 5px 6px 6px;
823 | }
824 | }
825 |
826 | /* Mobile TODO */
827 |
828 | @media only screen and (max-width: 767px) {
829 | .button {
830 | font-size: 50%;
831 | }
832 | }
833 |
--------------------------------------------------------------------------------
/libs/jquery/svg/jquery.svg.min.js:
--------------------------------------------------------------------------------
1 | /* http://keith-wood.name/svg.html
2 | SVG for jQuery v1.4.5.
3 | Written by Keith Wood (kbwood{at}iinet.com.au) August 2007.
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 | (function($){function SVGManager(){this._settings=[];this._extensions=[];this.regional=[];this.regional['']={errorLoadingText:'Error loading',notSupportedText:'This browser does not support SVG'};this.local=this.regional[''];this._uuid=new Date().getTime();this._renesis=detectActiveX('RenesisX.RenesisCtrl')}function detectActiveX(a){try{return!!(window.ActiveXObject&&new ActiveXObject(a))}catch(e){return false}}var q='svgwrapper';$.extend(SVGManager.prototype,{markerClassName:'hasSVG',svgNS:'http://www.w3.org/2000/svg',xlinkNS:'http://www.w3.org/1999/xlink',_wrapperClass:SVGWrapper,_attrNames:{class_:'class',in_:'in',alignmentBaseline:'alignment-baseline',baselineShift:'baseline-shift',clipPath:'clip-path',clipRule:'clip-rule',colorInterpolation:'color-interpolation',colorInterpolationFilters:'color-interpolation-filters',colorRendering:'color-rendering',dominantBaseline:'dominant-baseline',enableBackground:'enable-background',fillOpacity:'fill-opacity',fillRule:'fill-rule',floodColor:'flood-color',floodOpacity:'flood-opacity',fontFamily:'font-family',fontSize:'font-size',fontSizeAdjust:'font-size-adjust',fontStretch:'font-stretch',fontStyle:'font-style',fontVariant:'font-variant',fontWeight:'font-weight',glyphOrientationHorizontal:'glyph-orientation-horizontal',glyphOrientationVertical:'glyph-orientation-vertical',horizAdvX:'horiz-adv-x',horizOriginX:'horiz-origin-x',imageRendering:'image-rendering',letterSpacing:'letter-spacing',lightingColor:'lighting-color',markerEnd:'marker-end',markerMid:'marker-mid',markerStart:'marker-start',stopColor:'stop-color',stopOpacity:'stop-opacity',strikethroughPosition:'strikethrough-position',strikethroughThickness:'strikethrough-thickness',strokeDashArray:'stroke-dasharray',strokeDashOffset:'stroke-dashoffset',strokeLineCap:'stroke-linecap',strokeLineJoin:'stroke-linejoin',strokeMiterLimit:'stroke-miterlimit',strokeOpacity:'stroke-opacity',strokeWidth:'stroke-width',textAnchor:'text-anchor',textDecoration:'text-decoration',textRendering:'text-rendering',underlinePosition:'underline-position',underlineThickness:'underline-thickness',vertAdvY:'vert-adv-y',vertOriginY:'vert-origin-y',wordSpacing:'word-spacing',writingMode:'writing-mode'},_attachSVG:function(a,b){var c=(a.namespaceURI==this.svgNS?a:null);var a=(c?null:a);if($(a||c).hasClass(this.markerClassName)){return}if(typeof b=='string'){b={loadURL:b}}else if(typeof b=='function'){b={onLoad:b}}$(a||c).addClass(this.markerClassName);try{if(!c){c=document.createElementNS(this.svgNS,'svg');c.setAttribute('version','1.1');if(a.clientWidth>0){c.setAttribute('width',a.clientWidth)}if(a.clientHeight>0){c.setAttribute('height',a.clientHeight)}a.appendChild(c)}this._afterLoad(a,c,b||{})}catch(e){if($.browser.msie){if(!a.id){a.id='svg'+(this._uuid++)}this._settings[a.id]=b;a.innerHTML='
'}else{a.innerHTML='
'+this.local.notSupportedText+'
'}}},_registerSVG:function(){for(var i=0;i
=0;i--){var d=a.attributes.item(i);if(!(d.nodeName=='onload'||d.nodeName=='version'||d.nodeName.substring(0,5)=='xmlns')){a.attributes.removeNamedItem(d.nodeName)}}}for(var e in b){a.setAttribute($.svg._attrNames[e]||e,b[e])}return this},getElementById:function(a){return this._svg.ownerDocument.getElementById(a)},change:function(a,b){if(a){for(var c in b){if(b[c]==null){a.removeAttribute($.svg._attrNames[c]||c)}else{a.setAttribute($.svg._attrNames[c]||c,b[c])}}}return this},_args:function(b,c,d){c.splice(0,0,'parent');c.splice(c.length,0,'settings');var e={};var f=0;if(b[0]!=null&&b[0].jquery){b[0]=b[0][0]}if(b[0]!=null&&!(typeof b[0]=='object'&&b[0].nodeName)){e['parent']=null;f=1}for(var i=0;i'+d.styles+'')}return e},script:function(a,b,c,d){var e=this._args(arguments,['script','type'],['type']);var f=this._makeNode(e.parent,'script',$.extend({type:e.type||'text/javascript'},e.settings||{}));f.appendChild(this._svg.ownerDocument.createTextNode(e.script));if(!$.browser.mozilla){$.globalEval(e.script)}return f},linearGradient:function(a,b,c,d,e,f,g,h){var i=this._args(arguments,['id','stops','x1','y1','x2','y2'],['x1']);var j=$.extend({id:i.id},(i.x1!=null?{x1:i.x1,y1:i.y1,x2:i.x2,y2:i.y2}:{}));return this._gradient(i.parent,'linearGradient',$.extend(j,i.settings||{}),i.stops)},radialGradient:function(a,b,c,d,e,r,f,g,h){var i=this._args(arguments,['id','stops','cx','cy','r','fx','fy'],['cx']);var j=$.extend({id:i.id},(i.cx!=null?{cx:i.cx,cy:i.cy,r:i.r,fx:i.fx,fy:i.fy}:{}));return this._gradient(i.parent,'radialGradient',$.extend(j,i.settings||{}),i.stops)},_gradient:function(a,b,c,d){var e=this._makeNode(a,b,c);for(var i=0;i/g,'>'))}}}return b},_checkName:function(a){a=(a.substring(0,1)>='A'&&a.substring(0,1)<='Z'?a.toLowerCase():a);return(a.substring(0,4)=='svg:'?a.substring(4):a)},load:function(j,k){k=(typeof k=='boolean'?{addTo:k}:(typeof k=='function'?{onLoad:k}:(typeof k=='string'?{parent:k}:(typeof k=='object'&&k.nodeName?{parent:k}:(typeof k=='object'&&k.jquery?{parent:k}:k||{})))));if(!k.parent&&!k.addTo){this.clear(false)}var l=[this._svg.getAttribute('width'),this._svg.getAttribute('height')];var m=this;var n=function(a){a=$.svg.local.errorLoadingText+': '+a;if(k.onLoad){k.onLoad.apply(m._container||m._svg,[m,a])}else{m.text(null,10,20,a)}};var o=function(a){var b=new ActiveXObject('Microsoft.XMLDOM');b.validateOnParse=false;b.resolveExternals=false;b.async=false;b.loadXML(a);if(b.parseError.errorCode!=0){n(b.parseError.reason);return null}return b};var p=function(a){if(!a){return}if(a.documentElement.nodeName!='svg'){var b=a.getElementsByTagName('parsererror');var c=(b.length?b[0].getElementsByTagName('div'):[]);n(!b.length?'???':(c.length?c[0]:b[0]).firstChild.nodeValue);return}var d=(k.parent?$(k.parent)[0]:m._svg);var f={};for(var i=0;i'}else{b='<'+a.nodeName;if(a.attributes){for(var i=0;i';var d=a.firstChild;while(d){b+=this._toSVG(d);d=d.nextSibling}b+=''+a.nodeName+'>'}else{b+='/>'}}return b}});function SVGPath(){this._path=''}$.extend(SVGPath.prototype,{reset:function(){this._path='';return this},move:function(x,y,a){a=(isArray(x)?y:a);return this._coords((a?'m':'M'),x,y)},line:function(x,y,a){a=(isArray(x)?y:a);return this._coords((a?'l':'L'),x,y)},horiz:function(x,a){this._path+=(a?'h':'H')+(isArray(x)?x.join(' '):x);return this},vert:function(y,a){this._path+=(a?'v':'V')+(isArray(y)?y.join(' '):y);return this},curveC:function(a,b,c,d,x,y,e){e=(isArray(a)?b:e);return this._coords((e?'c':'C'),a,b,c,d,x,y)},smoothC:function(a,b,x,y,c){c=(isArray(a)?b:c);return this._coords((c?'s':'S'),a,b,x,y)},curveQ:function(a,b,x,y,c){c=(isArray(a)?b:c);return this._coords((c?'q':'Q'),a,b,x,y)},smoothQ:function(x,y,a){a=(isArray(x)?y:a);return this._coords((a?'t':'T'),x,y)},_coords:function(a,b,c,d,e,f,g){if(isArray(b)){for(var i=0;i").addClass("gdfWrapper");
32 | box.append(table);
33 |
34 | var head = table.clone();
35 | head.addClass("table ganttFixHead");
36 | //remove non head
37 | head.find("tbody").remove();
38 | box.append(head);
39 |
40 | box.append(table);
41 |
42 | var hTh = head.find(".gdfColHeader");
43 | var cTh = table.find(".gdfColHeader");
44 | for (var i = 0; i < hTh.length; i++) {
45 | hTh.eq(i).data("fTh", cTh.eq(i));
46 | }
47 |
48 | //--------- set table to 0 to prevent a strange 100%
49 | table.width(0);
50 | head.width(0);
51 |
52 |
53 | //---------------------- header management start
54 | head.find("th.gdfColHeader:not(.gdfied)").mouseover(function () {
55 | $(this).addClass("gdfColHeaderOver");
56 |
57 | }).on("mouseout.gdf", function () {
58 | $(this).removeClass("gdfColHeaderOver");
59 | if (!$.gridify.columInResize) {
60 | $("body").removeClass("gdfHResizing");
61 | }
62 |
63 | }).on("mousemove.gdf", function (e) {
64 | if (!$.gridify.columInResize) {
65 | var colHeader = $(this);
66 | var nextCol = colHeader.next();
67 | if (nextCol.length > 0 && nextCol.width() < options.resizeZoneWidth)
68 | colHeader = nextCol;
69 |
70 | if (!colHeader.is(".gdfResizable"))
71 | return;
72 |
73 | var mousePos = e.pageX - colHeader.offset().left;
74 |
75 | if (colHeader.width() - mousePos < options.resizeZoneWidth) {
76 | $("body").addClass("gdfHResizing");
77 | } else {
78 | $("body").removeClass("gdfHResizing");
79 | }
80 | }
81 |
82 | }).on("mousedown.gdf", function (e) {
83 | //console.debug("mousedown.gdf")
84 | var colHeader = $(this);
85 |
86 | var nextCol = colHeader.next();
87 | if (nextCol.length > 0 && nextCol.width() < options.resizeZoneWidth)
88 | colHeader = nextCol;
89 |
90 | if (!colHeader.is(".gdfResizable"))
91 | return;
92 |
93 | var mousePos = e.pageX - colHeader.offset().left;
94 | if (colHeader.width() - mousePos < options.resizeZoneWidth) {
95 | $("body").unselectable();
96 | $.gridify.columInResize = colHeader;
97 | //on event for start resizing
98 | //console.debug("start resizing");
99 | $(document).on("mousemove.gdf", function (e) {
100 |
101 | e.preventDefault();
102 | $("body").addClass("gdfHResizing");
103 |
104 | //manage resizing
105 | var w = e.pageX - $.gridify.columInResize.offset().left;
106 | w = w <= 1 ? 1 : w;
107 | $.gridify.columInResize.width(w);
108 | $.gridify.columInResize.data("fTh").width(w);
109 |
110 |
111 | //on mouse up on body to stop resizing
112 | }).on("mouseup.gdf", function () {
113 | //console.debug("mouseup.gdf")
114 |
115 | //$("body").css({cursor: "auto"});
116 |
117 | $(this).off("mousemove.gdf").off("mouseup.gdf").clearUnselectable();
118 | $("body").removeClass("gdfHResizing");
119 | delete $.gridify.columInResize;
120 |
121 | //save columns dimension
122 | storeGridState();
123 |
124 | });
125 | }
126 |
127 | }).on("dblclick.gdf", function () {
128 | //console.debug("dblclick.gdf")
129 | var col = $(this);
130 |
131 | if (!col.is(".gdfResizable"))
132 | return;
133 |
134 | var idx = $("th", col.parents("table")).index(col);
135 | var columnTd = $("td:nth-child(" + (idx + 1) + ")", table);
136 | var w = 0;
137 | columnTd.each(function () {
138 | var td = $(this);
139 | var content = td.children("input").length ? td.children("input").val() : td.html();
140 | var tmp = $("").addClass("columnWidthTest").html(content).css({position: "absolute"});
141 | $("body").append(tmp);
142 | w = Math.max(w, tmp.width() + parseFloat(td.css("padding-left")));
143 | tmp.remove();
144 | });
145 |
146 | w = w + 5;
147 | col.width(w);
148 | col.data("fTh").width(w);
149 |
150 | //save columns dimension
151 | storeGridState();
152 | return false;
153 |
154 | }).addClass("gdfied unselectable").attr("unselectable", "true");
155 |
156 |
157 | function storeGridState() {
158 | //console.debug("storeGridState");
159 | if (localStorage) {
160 | var gridState = {};
161 |
162 | var colSizes = [];
163 | $(".gdfTable .gdfColHeader").each(function () {
164 | colSizes.push($(this).outerWidth());
165 | });
166 |
167 | gridState.colSizes = colSizes;
168 |
169 | localStorage.setObject("TWPGanttGridState", gridState);
170 | //console.debug("gridState",localStorage.getItem("TWPGanttGridState"));
171 | }
172 | }
173 |
174 | function loadGridState() {
175 | //console.debug("loadGridState")
176 | if (localStorage) {
177 | if (localStorage.getObject("TWPGanttGridState")) {
178 | var gridState = localStorage.getObject("TWPGanttGridState");
179 | if (gridState.colSizes) {
180 | box.find(".gdfTable .gdfColHeader").each(function (i) {
181 | $(this).width(gridState.colSizes[i]);
182 | });
183 | }
184 | }
185 | }
186 | }
187 |
188 | loadGridState();
189 | return box;
190 | };
191 |
192 |
193 |
194 |
195 | $.splittify = {
196 | init: function (where, first, second, perc) {
197 |
198 | //perc = perc || 50;
199 |
200 | var element = $("").addClass("splitterContainer");
201 | var firstBox = $("
").addClass("splitElement splitBox1");
202 | var splitterBar = $("
").addClass("splitElement vSplitBar").attr("unselectable", "on").css("padding-top", where.height() / 2 + "px");
203 | var secondBox = $("
").addClass("splitElement splitBox2");
204 |
205 |
206 | var splitter = new Splitter(element, firstBox, secondBox, splitterBar);
207 | splitter.perc = perc;
208 |
209 | //override with saved one
210 | loadPosition();
211 |
212 | var toLeft = $("
").addClass("toLeft").html("{").click(function () {splitter.resize(0.001, 300);});
213 | splitterBar.append(toLeft);
214 |
215 | var toCenter = $("
").addClass("toCenter").html("©").click(function () {splitter.resize(50, 300);});
216 | splitterBar.append(toCenter);
217 |
218 | var toRight = $("
").addClass("toRight").html("}").click(function () {splitter.resize(99.9999, 300);});
219 | splitterBar.append(toRight);
220 |
221 |
222 | firstBox.append(first);
223 | secondBox.append(second);
224 |
225 | element.append(firstBox).append(secondBox).append(splitterBar);
226 |
227 | where.append(element);
228 |
229 | var totalW = where.innerWidth();
230 | var splW = splitterBar.width();
231 | var fbw = totalW * perc / 100 - splW;
232 | //var realW = firstBox.get(0).scrollWidth;
233 | //fbw = fbw > realW? realW: fbw;
234 | fbw = fbw > totalW - splW - splitter.secondBoxMinWidth ? totalW - splW - splitter.secondBoxMinWidth : fbw;
235 | firstBox.width(fbw).css({left: 0});
236 | splitterBar.css({left: firstBox.width()});
237 | secondBox.width(totalW - fbw - splW).css({left: firstBox.width() + splW});
238 |
239 | splitterBar.on("mousedown.gdf", function (e) {
240 |
241 | e.preventDefault();
242 | $("body").addClass("gdfHResizing");
243 |
244 | $.splittify.splitterBar = $(this);
245 | //on event for start resizing
246 | //console.debug("start splitting");
247 | //var realW = firstBox.get(0).scrollWidth;
248 | $("body").unselectable().on("mousemove.gdf", function (e) {
249 | //manage resizing
250 | //console.debug(e.pageX - $.gridify.columInResize.offset().left)
251 |
252 | e.preventDefault();
253 |
254 | var sb = $.splittify.splitterBar;
255 | var pos = e.pageX - sb.parent().offset().left;
256 | var w = sb.parent().width();
257 | var fbw = firstBox;
258 |
259 | pos = pos > splitter.firstBoxMinWidth ? pos : splitter.firstBoxMinWidth;
260 | //pos = pos < realW - 10 ? pos : realW - 10;
261 | pos = pos > totalW - splW - splitter.secondBoxMinWidth ? totalW - splW - splitter.secondBoxMinWidth : pos;
262 | sb.css({left: pos});
263 | firstBox.width(pos);
264 | secondBox.css({left: pos + sb.width(), width: w - pos - sb.width()});
265 | splitter.perc = (firstBox.width() / splitter.element.width()) * 100;
266 |
267 | //on mouse up on body to stop resizing
268 | }).on("mouseup.gdf", function () {
269 | //console.debug("stop splitting");
270 | $(this).off("mousemove.gdf").off("mouseup.gdf").clearUnselectable();
271 | delete $.splittify.splitterBar;
272 |
273 | $("body").removeClass("gdfHResizing");
274 |
275 | storePosition();
276 | });
277 | });
278 |
279 |
280 | // keep both side in synch when scroll
281 | var stopScroll = false;
282 | var fs = firstBox.add(secondBox);
283 | fs.scroll(function (e) {
284 | var el = $(this);
285 | var top = el.scrollTop();
286 |
287 | var firstBoxHeader = firstBox.find(".ganttFixHead");
288 | var secondBoxHeader = secondBox.find(".ganttFixHead");
289 |
290 | if (el.is(".splitBox1") && stopScroll != "splitBox2") {
291 | stopScroll = "splitBox1";
292 | secondBox.scrollTop(top);
293 | } else if (el.is(".splitBox2") && stopScroll != "splitBox1") {
294 | stopScroll = "splitBox2";
295 | firstBox.scrollTop(top);
296 | }
297 |
298 | firstBoxHeader.css('top', top).hide();
299 | secondBoxHeader.css('top', top).hide();
300 |
301 | where.stopTime("reset").oneTime(100, "reset", function () {
302 |
303 | stopScroll = "";
304 | top = el.scrollTop();
305 |
306 | firstBoxHeader.css('top', top).fadeIn();
307 | secondBoxHeader.css('top', top).fadeIn();
308 |
309 | });
310 |
311 | });
312 |
313 |
314 | firstBox.on('mousewheel MozMousePixelScroll', function (event) {
315 |
316 | event.preventDefault();
317 |
318 | var deltaY = event.originalEvent.wheelDeltaY;
319 | if(!deltaY)
320 | deltaY=event.originalEvent.wheelDelta;
321 |
322 | var deltaX = event.originalEvent.wheelDeltaX;
323 |
324 | if (event.originalEvent.axis) {
325 | deltaY = event.originalEvent.axis == 2 ? -event.originalEvent.detail : null;
326 | deltaX = event.originalEvent.axis == 1 ? -event.originalEvent.detail : null;
327 | }
328 |
329 | deltaY = Math.abs(deltaY) < 40 ? 40 * (Math.abs(deltaY) / deltaY) : deltaY;
330 | deltaX = Math.abs(deltaX) < 40 ? 40 * (Math.abs(deltaX) / deltaX) : deltaX;
331 |
332 | var scrollToY = secondBox.scrollTop() - deltaY;
333 | var scrollToX = firstBox.scrollLeft() - deltaX;
334 |
335 | // console.debug( firstBox.scrollLeft(), Math.abs(deltaX), Math.abs(deltaY));
336 |
337 | if (deltaY) secondBox.scrollTop(scrollToY);
338 | if (deltaX) firstBox.scrollLeft(scrollToX);
339 |
340 | return false;
341 | });
342 |
343 |
344 | function Splitter(element, firstBox, secondBox, splitterBar) {
345 | this.element = element;
346 | this.firstBox = firstBox;
347 | this.secondBox = secondBox;
348 | this.splitterBar = splitterBar;
349 | this.perc = 0;
350 | this.firstBoxMinWidth = 0;
351 | this.secondBoxMinWidth = 30;
352 |
353 | this.resize = function (newPerc, anim) {
354 | var animTime = anim ? anim : 0;
355 | this.perc = newPerc ? newPerc : this.perc;
356 | var totalW = this.element.width();
357 | var splW = this.splitterBar.width();
358 | var newW = totalW * this.perc / 100;
359 | newW = newW > this.firstBoxMinWidth ? newW : this.firstBoxMinWidth;
360 | newW = newW > totalW - splW - splitter.secondBoxMinWidth ? totalW - splW - splitter.secondBoxMinWidth : newW;
361 | this.firstBox.animate({width: newW}, animTime, function () {$(this).css("overflow-x", "auto")});
362 | this.splitterBar.animate({left: newW}, animTime);
363 | this.secondBox.animate({left: newW + this.splitterBar.width(), width: totalW - newW - splW}, animTime, function () {$(this).css("overflow", "auto")});
364 |
365 | storePosition();
366 | };
367 |
368 | var self = this;
369 | this.splitterBar.on("dblclick", function () {
370 | self.resize(50, true);
371 | })
372 | }
373 |
374 |
375 | function storePosition () {
376 | //console.debug("storePosition",splitter.perc);
377 | if (localStorage) {
378 | localStorage.setItem("TWPGanttSplitPos",splitter.perc);
379 | }
380 | }
381 |
382 | function loadPosition () {
383 | //console.debug("loadPosition");
384 | if (localStorage) {
385 | if (localStorage.getItem("TWPGanttSplitPos")) {
386 | splitter.perc=parseFloat(localStorage.getItem("TWPGanttSplitPos"));
387 | }
388 | }
389 | }
390 |
391 |
392 |
393 | return splitter;
394 | }
395 |
396 | };
397 |
398 |
399 | //<%------------------------------------------------------------------------ UTILITIES ---------------------------------------------------------------%>
400 | function computeStart(start) {
401 | return computeStartDate(start).getTime();
402 | }
403 | function computeStartDate(start) {
404 | var d = new Date(start + 3600000 * 12);
405 | d.setHours(0, 0, 0, 0);
406 | //move to next working day
407 | while (isHoliday(d)) {
408 | d.setDate(d.getDate() + 1);
409 | }
410 | d.setHours(0, 0, 0, 0);
411 | return d;
412 | }
413 |
414 | function computeEnd(end) {
415 | return computeEndDate(end).getTime()
416 | }
417 | function computeEndDate(end) {
418 | var d = new Date(end - 3600000 * 12);
419 | d.setHours(23, 59, 59, 999);
420 | //move to next working day
421 | while (isHoliday(d)) {
422 | d.setDate(d.getDate() + 1);
423 | }
424 | d.setHours(23, 59, 59, 999);
425 | return d;
426 | }
427 |
428 | function computeEndByDuration(start, duration) {
429 | var d = new Date(start);
430 | //console.debug("computeEndByDuration start ",d,duration)
431 | var q = duration - 1;
432 | while (q > 0) {
433 | d.setDate(d.getDate() + 1);
434 | if (!isHoliday(d))
435 | q--;
436 | }
437 | d.setHours(23, 59, 59, 999);
438 | return d.getTime();
439 | }
440 |
441 |
442 | function incrementDateByWorkingDays(date, days) {
443 | var d = new Date(date);
444 | d.incrementDateByWorkingDays(days);
445 | return d.getTime();
446 | }
447 |
448 |
449 | function recomputeDuration(start, end) {
450 | //console.debug("recomputeDuration");
451 | return new Date(start).distanceInWorkingDays(new Date(end)) + 1;
452 | }
453 |
454 |
455 | function resynchDates(leavingField, startField, startMilesField, durationField, endField, endMilesField) {
456 | //console.debug("resynchDates",leavingField.prop("name"), startField.prop("name"), startMilesField.prop("name"), durationField.prop("name"), endField.prop("name"), endMilesField.prop("name"));
457 | function resynchDatesSetFields(command) {
458 | //console.debug("resynchDatesSetFields",command);
459 | //var duration = parseInt(durationField.val());
460 | var duration = daysFromString(durationField.val(), true);
461 | if (!duration || duration < 1)
462 | duration = 1;
463 |
464 | var start = computeStart(Date.parseString(startField.val()).getTime());
465 |
466 | var end = endField.val();
467 | if (end.length > 0) {
468 | end = Date.parseString(end);
469 | end.setHours(23, 59, 59, 999);
470 | end = computeEnd(end.getTime());
471 | }
472 |
473 | var date = new Date();
474 | if ("CHANGE_END" == command) {
475 | date.setTime(start);
476 | var workingDays = duration - 1;
477 | date.incrementDateByWorkingDays(workingDays);
478 | date.setHours(23, 59, 59, 999);
479 | end = computeEnd(date.getTime());
480 | } else if ("CHANGE_START" == command) {
481 | date.setTime(end);
482 | var workingDays = duration - 1;
483 | date.incrementDateByWorkingDays(-workingDays);
484 | date.setHours(0, 0, 0, 0);
485 | start = computeStart(date.getTime());
486 | } else if ("CHANGE_DURATION" == command) {
487 | //console.debug("CHANGE_DURATION",new Date(start),new Date(end))
488 | duration = new Date(start).distanceInWorkingDays(new Date(end)) + 1;
489 | }
490 |
491 | startField.val(new Date(start).format());
492 | endField.val(new Date(end).format());
493 | durationField.val(duration);
494 |
495 | return {start: start, end: end, duration: duration};
496 | }
497 |
498 | var leavingFieldName = leavingField.prop("name");
499 | var durIsFilled = durationField.val().length > 0;
500 | var startIsFilled = startField.val().length > 0;
501 | var endIsFilled = endField.val().length > 0;
502 | var startIsMilesAndFilled = startIsFilled && (startMilesField.prop("checked") || startField.is("[readOnly]"));
503 | var endIsMilesAndFilled = endIsFilled && (endMilesField.prop("checked") || endField.is("[readOnly]"));
504 |
505 | if (durIsFilled) {
506 | if (parseInt(durationField.val()) == NaN || parseInt(durationField.val()) < 1)
507 | durationField.val(1);
508 | }
509 |
510 | if (leavingFieldName.indexOf("Milestone") > 0) {
511 | if (startIsMilesAndFilled && endIsMilesAndFilled) {
512 | durationField.prop("readOnly", true);
513 | } else {
514 | durationField.prop("readOnly", false);
515 | }
516 | return;
517 | }
518 |
519 | //need at least two values to resynch the third
520 | if ((durIsFilled ? 1 : 0) + (startIsFilled ? 1 : 0) + (endIsFilled ? 1 : 0) < 2)
521 | return;
522 |
523 | var ret;
524 | if (leavingFieldName == 'start' && startIsFilled) {
525 | if (endIsMilesAndFilled && durIsFilled) {
526 | ret = resynchDatesSetFields("CHANGE_DURATION");
527 | } else if (durIsFilled) {
528 | ret = resynchDatesSetFields("CHANGE_END");
529 | }
530 |
531 | } else if (leavingFieldName == 'duration' && durIsFilled && !(endIsMilesAndFilled && startIsMilesAndFilled)) {
532 | if (endIsMilesAndFilled && !startIsMilesAndFilled) {
533 | ret = resynchDatesSetFields("CHANGE_START");
534 | } else if (!endIsMilesAndFilled) {
535 | //document.title=('go and change end!!');
536 | ret = resynchDatesSetFields("CHANGE_END");
537 | }
538 |
539 | } else if (leavingFieldName == 'end' && endIsFilled) {
540 | ret = resynchDatesSetFields("CHANGE_DURATION");
541 | }
542 | return ret;
543 | }
544 |
545 |
546 | //This prototype is provided by the Mozilla foundation and
547 | //is distributed under the MIT license.
548 | //http://www.ibiblio.org/pub/Linux/LICENSES/mit.license
549 |
550 | if (!Array.prototype.filter) {
551 | Array.prototype.filter = function (fun) {
552 | var len = this.length;
553 | if (typeof fun != "function")
554 | throw new TypeError();
555 |
556 | var res = new Array();
557 | var thisp = arguments[1];
558 | for (var i = 0; i < len; i++) {
559 | if (i in this) {
560 | var val = this[i]; // in case fun mutates this
561 | if (fun.call(thisp, val, i, this))
562 | res.push(val);
563 | }
564 | }
565 | return res;
566 | };
567 | }
568 |
569 |
570 | function goToPage(url) {
571 | if (!canILeave()) return;
572 | window.location.href = url;
573 | }
574 |
--------------------------------------------------------------------------------
/libs/forms.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2012-2017 Open Lab
3 | Permission is hereby granted, free of charge, to any person obtaining
4 | a copy of this software and associated documentation files (the
5 | "Software"), to deal in the Software without restriction, including
6 | without limitation the rights to use, copy, modify, merge, publish,
7 | distribute, sublicense, and/or sell copies of the Software, and to
8 | permit persons to whom the Software is furnished to do so, subject to
9 | the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be
12 | included in all copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 | */
22 |
23 | var muteAlertOnChange = false;
24 |
25 |
26 | // isRequired ----------------------------------------------------------------------------
27 |
28 | //return true if every mandatory field is filled and highlight empty ones
29 | jQuery.fn.isFullfilled = function () {
30 | var canSubmit = true;
31 | var firstErrorElement = "";
32 |
33 | this.each(function () {
34 | var theElement = $(this);
35 | theElement.removeClass("formElementsError");
36 | //if (theElement.val().trim().length == 0 || theElement.attr("invalid") == "true") { //robicch 13/2/15
37 | if (theElement.is("[required]") && theElement.val().trim().length == 0 || theElement.attr("invalid") == "true") {
38 | if (theElement.attr("type") == "hidden") {
39 | theElement = theElement.prevAll("#" + theElement.prop("id") + "_txt:first");
40 | } else if (theElement.is("[withTinyMCE]")){
41 | if (tinymce.activeEditor.getContent()=="")
42 | theElement=$("#"+theElement.attr("name")+"_tbl");
43 | else
44 | return true;// in order to continue the loop
45 | }
46 | theElement.addClass("formElementsError");
47 | canSubmit = false;
48 |
49 | if (firstErrorElement == "")
50 | firstErrorElement = theElement;
51 | }
52 | });
53 |
54 | if (!canSubmit) {
55 | // get the tabdiv
56 | var theTabDiv = firstErrorElement.closest(".tabBox");
57 | if (theTabDiv.length > 0)
58 | clickTab(theTabDiv.attr("tabId"));
59 |
60 | // highlight element
61 | firstErrorElement.effect("highlight", { color:"red" }, 1500);
62 | }
63 | return canSubmit;
64 |
65 | };
66 |
67 | function canSubmitForm(formOrId) {
68 | //console.debug("canSubmitForm",formOrId);
69 | if (typeof formOrId != "object")
70 | formOrId=$("#" + formOrId);
71 | return formOrId.find(":input[required],:input[invalid=true]").isFullfilled();
72 | }
73 |
74 | function showSavingMessage() {
75 | $("#savingMessage:hidden").fadeIn();
76 | $("body").addClass("waiting");
77 | $(window).resize();
78 | }
79 | function hideSavingMessage() {
80 | $("#savingMessage:visible").fadeOut();
81 | $("body").removeClass("waiting");
82 | $(window).resize();
83 | }
84 |
85 |
86 |
87 | /* Types Function */
88 |
89 | function isValidURL(url) {
90 | 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})*)?$/;
91 | return RegExp.test(url);
92 | }
93 |
94 | function isValidEmail(email) {
95 | //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})\])))$/;
96 | var RegExp = /^.+@\S+\.\S+$/;
97 | return RegExp.test(email);
98 | }
99 |
100 | function isValidInteger(n) {
101 | reg = new RegExp("^[-+]{0,1}[0-9]*$");
102 | return reg.test(n) || isNumericExpression(n);
103 | }
104 |
105 | function isValidDouble(n) {
106 | var sep = Number.decimalSeparator;
107 | reg = new RegExp("^[-+]{0,1}[0-9]*[" + sep + "]{0,1}[0-9]*$");
108 | return reg.test(n) || isNumericExpression(n);
109 | }
110 |
111 | function isValidTime(n) {
112 | return !isNaN(millisFromHourMinute(n));
113 | }
114 |
115 | function isValidDurationDays(n) {
116 | return !isNaN(daysFromString(n));
117 | }
118 |
119 | function isValidDurationMillis(n) {
120 | return !isNaN(millisFromString(n));
121 | }
122 |
123 | function isNumericExpression(expr) {
124 | try {
125 | var a = eval(expr);
126 | return typeof(a) == 'number';
127 | } catch (t) {
128 | return false;
129 | }
130 |
131 | }
132 |
133 | function getNumericExpression(expr) {
134 | var ret;
135 | try {
136 | var a = eval(expr);
137 | if (typeof(a) == 'number')
138 | ret = a;
139 | } catch (t) {
140 | }
141 | return ret;
142 |
143 | }
144 |
145 | /*
146 | supports almost all Java currency format e.g.: ###,##0.00EUR €#,###.00 #,###.00€ -$#,###.00 $-#,###.00
147 | */
148 | function isValidCurrency(numStr) {
149 | //first try to convert format in a regex
150 | var regex = "";
151 | var format = Number.currencyFormat + "";
152 |
153 | var minusFound = false;
154 | var numFound = false;
155 | var currencyString = "";
156 | var numberRegex = "[0-9\\" + Number.groupingSeparator + "]+[\\" + Number.decimalSeparator + "]?[0-9]*";
157 |
158 | for (var i = 0; i < format.length; i++) {
159 | var ch = format.charAt(i);
160 |
161 | if (ch == "." || ch == "," || ch == "0") {
162 | //skip it
163 | if (currencyString != "") {
164 | regex = regex + "(?:" + RegExp.quote(currencyString) + ")?";
165 | currencyString = "";
166 | }
167 |
168 | } else if (ch == "#") {
169 | if (currencyString != "") {
170 | regex = regex + "(?:" + RegExp.quote(currencyString) + ")?";
171 | currencyString = "";
172 | }
173 |
174 | if (!numFound) {
175 | numFound = true;
176 | regex = regex + numberRegex;
177 | }
178 |
179 | } else if (ch == "-") {
180 | if (currencyString != "") {
181 | regex = regex + "(?:" + RegExp.quote(currencyString) + ")?";
182 | currencyString = "";
183 | }
184 | if (!minusFound) {
185 | minusFound = true;
186 | regex = regex + "[-]?";
187 | }
188 |
189 | } else {
190 | currencyString = currencyString + ch;
191 | }
192 | }
193 | if (!minusFound)
194 | regex = "[-]?" + regex;
195 |
196 | if (currencyString != "")
197 | regex = regex + "(?:" + RegExp.quote(currencyString) + ")?";
198 |
199 | regex = "^" + regex + "$";
200 |
201 | var rg = new RegExp(regex);
202 | return rg.test(numStr) || isNumericExpression(numStr);
203 | }
204 |
205 | function getCurrencyValue(numStr) {
206 | if (!isValidCurrency(numStr))
207 | return NaN;
208 |
209 | var ripul = numStr.replaceAll(Number.groupingSeparator, "").replaceAll(Number.decimalSeparator, ".");
210 | return getNumericExpression(ripul) || parseFloat(ripul.replace(/[^-0123456789.]/, ""));
211 | }
212 |
213 |
214 | function formatCurrency(numberString) {
215 | return formatNumber(numberString, Number.currencyFormat);
216 | }
217 |
218 |
219 | function formatNumber(numberString, format) {
220 | if (!format)
221 | format = "##0.00";
222 |
223 | var dec = Number.decimalSeparator;
224 | var group = Number.groupingSeparator;
225 | var neg = Number.minusSign;
226 |
227 | var round = true;
228 |
229 | var validFormat = "0#-,.";
230 |
231 | // strip all the invalid characters at the beginning and the end
232 | // of the format, and we'll stick them back on at the end
233 | // make a special case for the negative sign "-" though, so
234 | // we can have formats like -$23.32
235 | var prefix = "";
236 | var negativeInFront = false;
237 | for (var i = 0; i < format.length; i++) {
238 | if (validFormat.indexOf(format.charAt(i)) == -1) {
239 | prefix = prefix + format.charAt(i);
240 | } else {
241 | if (i == 0 && format.charAt(i) == '-') {
242 | negativeInFront = true;
243 | } else {
244 | break;
245 | }
246 | }
247 | }
248 | var suffix = "";
249 | for (var i = format.length - 1; i >= 0; i--) {
250 | if (validFormat.indexOf(format.charAt(i)) == -1)
251 | suffix = format.charAt(i) + suffix;
252 | else
253 | break;
254 | }
255 |
256 | format = format.substring(prefix.length);
257 | format = format.substring(0, format.length - suffix.length);
258 |
259 | // now we need to convert it into a number
260 | //while (numberString.indexOf(group) > -1)
261 | // numberString = numberString.replace(group, '');
262 | //var number = new Number(numberString.replace(dec, ".").replace(neg, "-"));
263 | var number = new Number(numberString);
264 |
265 |
266 | var forcedToZero = false;
267 | if (isNaN(number)) {
268 | number = 0;
269 | forcedToZero = true;
270 | }
271 |
272 | // special case for percentages
273 | if (suffix == "%")
274 | number = number * 100;
275 |
276 | var returnString = "";
277 | if (format.indexOf(".") > -1) {
278 | var decimalPortion = dec;
279 | var decimalFormat = format.substring(format.lastIndexOf(".") + 1);
280 |
281 | // round or truncate number as needed
282 | if (round)
283 | number = new Number(number.toFixed(decimalFormat.length));
284 | else {
285 | var numStr = number.toString();
286 | numStr = numStr.substring(0, numStr.lastIndexOf('.') + decimalFormat.length + 1);
287 | number = new Number(numStr);
288 | }
289 |
290 | var decimalValue = number % 1;
291 | var decimalString = new String(decimalValue.toFixed(decimalFormat.length));
292 | decimalString = decimalString.substring(decimalString.lastIndexOf(".") + 1);
293 |
294 | for (var i = 0; i < decimalFormat.length; i++) {
295 | if (decimalFormat.charAt(i) == '#' && decimalString.charAt(i) != '0') {
296 | decimalPortion += decimalString.charAt(i);
297 | } else if (decimalFormat.charAt(i) == '#' && decimalString.charAt(i) == '0') {
298 | var notParsed = decimalString.substring(i);
299 | if (notParsed.match('[1-9]')) {
300 | decimalPortion += decimalString.charAt(i);
301 | } else {
302 | break;
303 | }
304 | } else if (decimalFormat.charAt(i) == "0") {
305 | decimalPortion += decimalString.charAt(i);
306 | }
307 | }
308 | returnString += decimalPortion;
309 | } else {
310 | number = Math.round(number);
311 | }
312 | var ones = Math.floor(number);
313 | if (number < 0)
314 | ones = Math.ceil(number);
315 |
316 | var onesFormat = "";
317 | if (format.indexOf(".") == -1)
318 | onesFormat = format;
319 | else
320 | onesFormat = format.substring(0, format.indexOf("."));
321 |
322 | var onePortion = "";
323 | if (!(ones == 0 && onesFormat.substr(onesFormat.length - 1) == '#') || forcedToZero) {
324 | // find how many digits are in the group
325 | var oneText = new String(Math.abs(ones));
326 | var groupLength = 9999;
327 | if (onesFormat.lastIndexOf(",") != -1)
328 | groupLength = onesFormat.length - onesFormat.lastIndexOf(",") - 1;
329 | var groupCount = 0;
330 | for (var i = oneText.length - 1; i > -1; i--) {
331 | onePortion = oneText.charAt(i) + onePortion;
332 | groupCount++;
333 | if (groupCount == groupLength && i != 0) {
334 | onePortion = group + onePortion;
335 | groupCount = 0;
336 | }
337 | }
338 |
339 | // account for any pre-data padding
340 | if (onesFormat.length > onePortion.length) {
341 | var padStart = onesFormat.indexOf('0');
342 | if (padStart != -1) {
343 | var padLen = onesFormat.length - padStart;
344 |
345 | // pad to left with 0's or group char
346 | var pos = onesFormat.length - onePortion.length - 1;
347 | while (onePortion.length < padLen) {
348 | var padChar = onesFormat.charAt(pos);
349 | // replace with real group char if needed
350 | if (padChar == ',')
351 | padChar = group;
352 | onePortion = padChar + onePortion;
353 | pos--;
354 | }
355 | }
356 | }
357 | }
358 |
359 | if (!onePortion && onesFormat.indexOf('0', onesFormat.length - 1) !== -1)
360 | onePortion = '0';
361 |
362 | returnString = onePortion + returnString;
363 |
364 | // handle special case where negative is in front of the invalid characters
365 | if (number < 0 && negativeInFront && prefix.length > 0)
366 | prefix = neg + prefix;
367 | else if (number < 0)
368 | returnString = neg + returnString;
369 |
370 | if (returnString.lastIndexOf(dec) == returnString.length - 1) {
371 | returnString = returnString.substring(0, returnString.length - 1);
372 | }
373 | returnString = prefix + returnString + suffix;
374 | return returnString;
375 | }
376 |
377 |
378 | //validation functions - used by textfield and datefield
379 | jQuery.fn.validateField = function () {
380 | var isValid = true;
381 |
382 | this.each(function () {
383 | var el = $(this);
384 | el.clearErrorAlert();
385 |
386 | var value = el.val();
387 | if (value) {
388 | var rett = true;
389 | var type = (el.attr('entryType')+"").toUpperCase();
390 | var errParam;
391 |
392 | if (type == "INTEGER") {
393 | rett = isValidInteger(value);
394 | } else if (type == "DOUBLE") {
395 | rett = isValidDouble(value);
396 | } else if (type == "PERCENTILE") {
397 | rett = isValidDouble(value);
398 | } else if (type == "URL") {
399 | rett = isValidURL(value);
400 | } else if (type == "EMAIL") {
401 | rett = isValidEmail(value);
402 | } else if (type == "DURATIONMILLIS") {
403 | rett = isValidDurationMillis(value);
404 | } else if (type == "DURATIONDAYS") {
405 | rett = isValidDurationDays(value);
406 | } else if (type == "DATE") {
407 | rett = Date.isValid(value, el.attr("format"), true);
408 | if (!rett)
409 | errParam = el.attr("format");
410 | } else if (type == "TIME") {
411 | rett = isValidTime(value);
412 | } else if (type == "CURRENCY") {
413 | rett = isValidCurrency(value);
414 | }
415 |
416 | if (!rett) {
417 | el.createErrorAlert(i18n.ERROR_ON_FIELD, i18n.INVALID_DATA + (errParam ? " " + errParam : ""));
418 | isValid=false;
419 | }
420 |
421 |
422 | //check limits minValue : maxValue
423 | if (rett && (el.attr("minValue") || el.attr("maxValue"))){
424 | var val=value;
425 | var min=el.attr("minValue");
426 | var max=el.attr("maxValue");
427 | if (type == "INTEGER") {
428 | val=parseInt(value);
429 | min=parseInt(min);
430 | max=parseInt(max);
431 | } else if (type == "DOUBLE" || type == "PERCENTILE") {
432 | val=parseDouble(value);
433 | min=parseDouble(min);
434 | max=parseDouble(max);
435 | } else if (type == "URL") {
436 | val=value;
437 | } else if (type == "EMAIL") {
438 | val=value;
439 | } else if (type == "DURATIONMILLIS") {
440 | val=millisFromString(value);
441 | min=millisFromString(min);
442 | max=millisFromString(max);
443 |
444 | } else if (type == "DURATIONDAYS") {
445 | val=daysFromString(value);
446 | min=daysFromString(min);
447 | max=daysFromString(max);
448 | } else if (type == "DATE") {
449 | val=Date.parseString(value, el.attr("format"),true).getTime();
450 | min=Date.parseString(min, el.attr("format"),true).getTime();
451 | max=Date.parseString(max, el.attr("format"),true).getTime();
452 | } else if (type == "TIME") {
453 | val = millisFromHourMinute(value);
454 | min = millisFromHourMinute(min);
455 | max = millisFromHourMinute(max);
456 | } else if (type == "CURRENCY") {
457 | val=getCurrencyValue(value);
458 | min=getCurrencyValue(min);
459 | max=getCurrencyValue(max);
460 | }
461 |
462 | if (el.attr("minValue") && val
max){
471 | el.createErrorAlert(i18n.ERROR_ON_FIELD, i18n.OUT_OF_BOUDARIES + " ("+(el.attr("minValue")?el.attr("minValue"):"--")+" : "+el.attr("maxValue")+")");
472 | rett=false;
473 | isValid=false;
474 | }
475 |
476 | }
477 |
478 | }
479 |
480 | });
481 |
482 | return isValid;
483 | };
484 |
485 | jQuery.fn.clearErrorAlert = function () {
486 | this.each(function () {
487 | var el = $(this);
488 | el.removeAttr("invalid").removeClass("formElementsError");
489 | $("#" + el.prop("id") + "error").remove();
490 | });
491 | return this;
492 | };
493 |
494 | jQuery.fn.createErrorAlert = function (errorCode, message) {
495 | this.each(function () {
496 | var el = $(this);
497 | el.attr("invalid", "true").addClass("formElementsError");
498 | if ($("#" + el.prop("id") + "error").length <= 0) {
499 | var errMess = (errorCode ? errorCode : "") + ": " + (message ? message : "");
500 | var err = " ";
502 | err += "\n";
503 | err = $(err);
504 | err.prop("title", errMess);
505 | el.after(err);
506 | }
507 | });
508 | return this;
509 | };
510 |
511 |
512 | // button submit support BEGIN ------------------
513 |
514 | function saveFormValues(idForm) {
515 | var formx = obj(idForm);
516 | formx.setAttribute("savedAction", formx.action);
517 | formx.setAttribute("savedTarget", formx.target);
518 | var el = formx.elements;
519 | for (i = 0; i < el.length; i++) {
520 | if (el[i].getAttribute("savedValue") != null) {
521 | el[i].setAttribute("savedValue", el[i].value);
522 | }
523 | }
524 | }
525 |
526 | function restoreFormValues(idForm) {
527 | var formx = obj(idForm);
528 | formx.action = formx.getAttribute("savedAction");
529 | formx.target = formx.getAttribute("savedTarget");
530 | var el = formx.elements;
531 | for (i = 0; i < el.length; i++) {
532 | if (el[i].getAttribute("savedValue") != null) {
533 | el[i].value = el[i].getAttribute("savedValue");
534 | }
535 | }
536 | }
537 |
538 | function changeActionAndSubmit(action,command){
539 | var f=$("form:first");
540 | f.prop("action",action);
541 | f.find("[name=CM]").val(command);
542 | f.submit();
543 | }
544 |
545 |
546 |
547 | // textarea limit size -------------------------------------------------
548 | function limitSize(ob) {
549 | if (ob.getAttribute("maxlength")) {
550 | var ml =parseInt(ob.getAttribute("maxlength"));
551 | var val = ob.value;//.replace(/\r\n/g,"\n");
552 | if (val.length > ml) {
553 | ob.value = val.substr(0, ml);
554 | $(ob).createErrorAlert("Error",i18n.ERR_FIELD_MAX_SIZE_EXCEEDED);
555 | } else {
556 | $(ob).clearErrorAlert();
557 | }
558 | }
559 | return true;
560 | }
561 |
562 |
563 | // verify before unload BEGIN ----------------------------------------------------------------------------
564 |
565 | function alertOnUnload(container) {
566 | //console.debug("alertOnUnload",container,muteAlertOnChange);
567 | if (!muteAlertOnChange) {
568 |
569 | //first try to call a function eventually defined on the page
570 | if (typeof(managePageUnload) == "function")
571 | managePageUnload();
572 |
573 | container=container||$("body");
574 | var inps= $("[alertonchange=true]",container).find("[oldValue=1]");
575 | for (var j = 0; j < inps.length; j++) {
576 | var anInput = inps.eq(j);
577 | //console.debug(j,anInput,anInput.isValueChanged())
578 | var oldValue = anInput.getOldValue() + "";
579 | if (!('true' == '' + anInput.attr('excludeFromAlert'))) {
580 | if (anInput.attr("maleficoTiny")) {
581 | if (tinymce.EditorManager.get(anInput.prop("id")).isDirty()) {
582 | return i18n.FORM_IS_CHANGED + " \"" + anInput.prop("name") + "\"";
583 | }
584 |
585 | } else if (anInput.isValueChanged()) {
586 | var inputLabel = $("label[for='" + anInput.prop("id") + "']").text(); //use label element
587 | inputLabel = inputLabel ? inputLabel : anInput.prop("name");
588 | return i18n.FORM_IS_CHANGED + " \"" + inputLabel + "\"";
589 | }
590 | }
591 | }
592 | }
593 | return undefined;
594 | }
595 |
596 | function canILeave(){
597 | var ret = window.onbeforeunload();
598 | if (typeof(ret)!="undefined" && !confirm(ret+" \n"+i18n.PROCEED))
599 | return false;
600 | else
601 | return true;
602 | }
603 |
604 | // ---------------------------------- oldvalues management
605 | // update all values selected
606 | jQuery.fn.updateOldValue = function () {
607 | this.each(function () {
608 | var el = $(this);
609 | var val=(el.is(":checkbox,:radio")?el.prop("checked"):el.val())+"";
610 | el.data("_oldvalue", val);
611 | });
612 | return this;
613 | };
614 |
615 | // return true if at least one element has changed
616 | jQuery.fn.isValueChanged = function () {
617 | var ret = false;
618 | this.each(function () {
619 | var el = $(this);
620 | var val=(el.is(":checkbox,:radio")?el.prop("checked"):el.val())+"";
621 | if (val != el.data("_oldvalue") + "") {
622 | //console.debug("io sono diverso "+el.prop("id")+ " :"+el.val()+" != "+el.data("_oldvalue"));
623 | ret = true;
624 | return false;
625 | }
626 | });
627 | return ret;
628 | };
629 |
630 | jQuery.fn.getOldValue = function () {
631 | return $(this).data("_oldvalue");
632 | };
633 |
634 | jQuery.fn.fillJsonWithInputValues = function (jsonObject) {
635 | var inputs = this.find(":input");
636 | $.each(inputs.serializeArray(),function(){
637 | if (this.name) {
638 | jsonObject[this.name] = this.value;
639 | }
640 | });
641 |
642 | inputs.filter(":checkbox[name]").each(function () {
643 | var el = $(this);
644 | jsonObject[el.attr("name")] = el.is(":checked") ? "yes" : "no";
645 |
646 | })
647 |
648 | return this;
649 | };
650 |
651 |
652 |
653 | function enlargeTextArea(immediate) {
654 | //console.debug("enlargeTextArea",immediate);
655 | var el = $(this);
656 |
657 | var delay=immediate===true?1:300;
658 | el.stopTime("taResizeApply");
659 | el.oneTime(delay,"taResizeApply",function(){
660 |
661 | var miH = el.is("[minHeight]") ? parseInt(el.attr("minHeight")) : 30;
662 | var maH = el.is("[maxHeight]") ? parseInt(el.attr("maxHeight")) : 400;
663 | var inc = el.is("[lineHeight]") ? parseInt(el.attr("lineHeight")) : 30;
664 |
665 | //si copiano nel css per sicurezza
666 | el.css({maxHeight:maH,minHeight:miH});
667 |
668 | var domEl = el.get(0);
669 | var pad = el.outerHeight()-el.height();
670 | //devo allargare
671 | if (domEl.scrollHeight>el.outerHeight() && el.outerHeight()maH-pad?maH-pad:nh;
674 | el.height(nh);
675 | } else if (el.height()>miH){
676 | //devo stringere
677 | el.height(el.height()-inc);
678 |
679 | while(el.outerHeight()-domEl.scrollHeight > 0 && el.height()>miH){
680 | el.height(el.height()-inc);
681 | }
682 | var newH=domEl.scrollHeight-pad +inc;
683 | //newH=newH5?0:5-empty);
45 |
46 | //fill with empty lines
47 | for (var i = 0; i < rowsToAdd; i++) {
48 | var emptyRow = $.JST.createFromTemplate({}, "TASKEMPTYROW");
49 | if (!master.permissions.canSeeDep)
50 | emptyRow.find(".requireCanSeeDep").hide();
51 |
52 | //click on empty row create a task and fill above
53 | emptyRow.click(function (ev) {
54 | //console.debug("emptyRow.click")
55 | var emptyRow = $(this);
56 | //add on the first empty row only
57 | if (!master.permissions.canWrite || !master.permissions.canAdd || emptyRow.prevAll(".emptyRow").length > 0)
58 | return;
59 |
60 | master.beginTransaction();
61 | var lastTask;
62 | var start = new Date().getTime();
63 | var level = 0;
64 | if (master.tasks[0]) {
65 | start = master.tasks[0].start;
66 | level = master.tasks[0].level + 1;
67 | }
68 |
69 | //fill all empty previouses
70 | var cnt=0;
71 | emptyRow.prevAll(".emptyRow").addBack().each(function () {
72 | cnt++;
73 | var ch = factory.build("tmp_fk" + new Date().getTime()+"_"+cnt, "", "", level, start, 1);
74 | var task = master.addTask(ch);
75 | lastTask = ch;
76 | });
77 | master.endTransaction();
78 | if (lastTask.rowElement) {
79 | //lastTask.rowElement.click(); removed R&S 22/03/2016 il click è bindato comunque
80 | lastTask.rowElement.find("[name=name]").focus();//focus to "name" input
81 | }
82 | });
83 | this.element.append(emptyRow);
84 | }
85 | };
86 |
87 |
88 | GridEditor.prototype.addTask = function (task, row, hideIfParentCollapsed) {
89 | //console.debug("GridEditor.addTask",task,row);
90 | //var prof = new Profiler("editorAddTaskHtml");
91 |
92 | //remove extisting row
93 | this.element.find("[taskId=" + task.id + "]").remove();
94 |
95 | var taskRow = $.JST.createFromTemplate(task, "TASKROW");
96 |
97 | if (!this.master.permissions.canSeeDep)
98 | taskRow.find(".requireCanSeeDep").hide();
99 |
100 | if (!this.master.permissions.canSeePopEdit)
101 | taskRow.find(".edit .teamworkIcon").hide();
102 |
103 | //save row element on task
104 | task.rowElement = taskRow;
105 |
106 | this.bindRowEvents(task, taskRow);
107 |
108 | if (typeof(row) != "number") {
109 | var emptyRow = this.element.find(".emptyRow:first"); //tries to fill an empty row
110 | if (emptyRow.length > 0)
111 | emptyRow.replaceWith(taskRow);
112 | else
113 | this.element.append(taskRow);
114 | } else {
115 | var tr = this.element.find("tr.taskEditRow").eq(row);
116 | if (tr.length > 0) {
117 | tr.before(taskRow);
118 | } else {
119 | this.element.append(taskRow);
120 | }
121 |
122 | }
123 |
124 | //[expand]
125 | if (hideIfParentCollapsed) {
126 | if (task.collapsed) taskRow.addClass('collapsed');
127 | var collapsedDescendant = this.master.getCollapsedDescendant();
128 | if (collapsedDescendant.indexOf(task) >= 0) taskRow.hide();
129 | }
130 |
131 | return taskRow;
132 | };
133 |
134 | GridEditor.prototype.refreshExpandStatus = function (task) {
135 | //console.debug("refreshExpandStatus",task);
136 | if (!task) return;
137 | if (task.isParent()) {
138 | task.rowElement.addClass("isParent");
139 | } else {
140 | task.rowElement.removeClass("isParent");
141 | }
142 |
143 | var par = task.getParent();
144 | if (par && !par.rowElement.is("isParent")) {
145 | par.rowElement.addClass("isParent");
146 | }
147 |
148 | };
149 |
150 | GridEditor.prototype.refreshTaskRow = function (task) {
151 | //console.debug("refreshTaskRow")
152 | //var profiler = new Profiler("editorRefreshTaskRow");
153 |
154 | var canWrite=this.master.permissions.canWrite && task.canWrite;
155 |
156 | var row = task.rowElement;
157 |
158 | row.find(".taskRowIndex").html(task.getRow() + 1);
159 | row.find(".indentCell").css("padding-left", task.level * 10 + 18);
160 | row.find("[name=name]").val(task.name);
161 | row.find("[name=code]").val(task.code);
162 | row.find("[status]").attr("status", task.status);
163 |
164 | row.find("[name=duration]").val(task.duration);
165 | row.find("[name=progress]").val(task.progress).prop("readonly",!canWrite || task.progressByWorklog==true);
166 | row.find("[name=startIsMilestone]").prop("checked", task.startIsMilestone);
167 | row.find("[name=start]").val(new Date(task.start).format()).updateOldValue().prop("readonly",!canWrite || task.depends || !task.canWrite && !this.master.permissions.canWrite ); // called on dates only because for other field is called on focus event
168 | row.find("[name=endIsMilestone]").prop("checked", task.endIsMilestone);
169 | row.find("[name=end]").val(new Date(task.end).format()).updateOldValue();
170 | row.find("[name=depends]").val(task.depends);
171 | row.find(".taskAssigs").html(task.getAssigsString());
172 |
173 | //manage collapsed
174 | if (task.collapsed)
175 | row.addClass("collapsed");
176 | else
177 | row.removeClass("collapsed");
178 |
179 |
180 | //Enhancing the function to perform own operations
181 | this.master.element.trigger('gantt.task.afterupdate.event', task);
182 | //profiler.stop();
183 | };
184 |
185 | GridEditor.prototype.redraw = function () {
186 | //console.debug("GridEditor.prototype.redraw")
187 | //var prof = new Profiler("ganttGridEditorRedraw");
188 | for (var i = 0; i < this.master.tasks.length; i++) {
189 | this.refreshTaskRow(this.master.tasks[i]);
190 | }
191 | // check if new empty rows are needed
192 | if (this.master.fillWithEmptyLines)
193 | this.fillEmptyLines();
194 |
195 | //prof.stop()
196 |
197 | };
198 |
199 | GridEditor.prototype.reset = function () {
200 | this.element.find("[taskid]").remove();
201 | };
202 |
203 |
204 | GridEditor.prototype.bindRowEvents = function (task, taskRow) {
205 | var self = this;
206 | //console.debug("bindRowEvents",this,this.master,this.master.permissions.canWrite, task.canWrite);
207 |
208 | //bind row selection
209 | taskRow.click(function (event) {
210 | var row = $(this);
211 | //console.debug("taskRow.click",row.attr("taskid"),event.target)
212 | //var isSel = row.hasClass("rowSelected");
213 | row.closest("table").find(".rowSelected").removeClass("rowSelected");
214 | row.addClass("rowSelected");
215 |
216 | //set current task
217 | self.master.currentTask = self.master.getTask(row.attr("taskId"));
218 |
219 | //move highlighter
220 | self.master.gantt.synchHighlight();
221 |
222 | //if offscreen scroll to element
223 | var top = row.position().top;
224 | if (top > self.element.parent().height()) {
225 | row.offsetParent().scrollTop(top - self.element.parent().height() + 100);
226 | } else if (top <= 40) {
227 | row.offsetParent().scrollTop(row.offsetParent().scrollTop() - 40 + top);
228 | }
229 | });
230 |
231 |
232 | if (this.master.permissions.canWrite && task.canWrite) {
233 | self.bindRowInputEvents(task, taskRow);
234 |
235 | } else { //cannot write: disable input
236 | taskRow.find("input").prop("readonly", true);
237 | taskRow.find("input:checkbox,select").prop("disabled", true);
238 | }
239 |
240 | if (!this.master.permissions.canSeeDep)
241 | taskRow.find("[name=depends]").attr("readonly", true);
242 |
243 | self.bindRowExpandEvents(task, taskRow);
244 | if (this.master.permissions.canSeePopEdit) {
245 | taskRow.find(".edit").click(function () {self.openFullEditor(task, false)});
246 | taskRow.find(".taskAssigs").dblclick(function () {self.openFullEditor(task, true)});
247 | }
248 | };
249 |
250 |
251 | GridEditor.prototype.bindRowExpandEvents = function (task, taskRow) {
252 | var self = this;
253 | //expand collapse
254 | taskRow.find(".exp-controller").click(function () {
255 | var el = $(this);
256 | var taskId = el.closest("[taskid]").attr("taskid");
257 | var task = self.master.getTask(taskId);
258 | if (task.collapsed) {
259 | self.master.expand(task,false);
260 | } else {
261 | self.master.collapse(task,false);
262 | }
263 | });
264 | };
265 |
266 | GridEditor.prototype.bindRowInputEvents = function (task, taskRow) {
267 | var self = this;
268 |
269 | //bind dateField on dates
270 | taskRow.find(".date").each(function () {
271 | var el = $(this);
272 | el.click(function () {
273 | var inp = $(this);
274 | inp.dateField({
275 | inputField: el,
276 | callback: function (d) {
277 | $(this).blur();
278 | }
279 | });
280 | });
281 |
282 | el.blur(function (date) {
283 | var inp = $(this);
284 | if (inp.isValueChanged()) {
285 | if (!Date.isValid(inp.val())) {
286 | alert(GanttMaster.messages["INVALID_DATE_FORMAT"]);
287 | inp.val(inp.getOldValue());
288 |
289 | } else {
290 | var row = inp.closest("tr");
291 | var taskId = row.attr("taskId");
292 | var task = self.master.getTask(taskId);
293 |
294 | var leavingField = inp.prop("name");
295 | var dates = resynchDates(inp, row.find("[name=start]"), row.find("[name=startIsMilestone]"), row.find("[name=duration]"), row.find("[name=end]"), row.find("[name=endIsMilestone]"));
296 | //console.debug("resynchDates",new Date(dates.start), new Date(dates.end),dates.duration)
297 | //update task from editor
298 | self.master.beginTransaction();
299 | self.master.changeTaskDates(task, dates.start, dates.end);
300 | self.master.endTransaction();
301 | inp.updateOldValue(); //in order to avoid multiple call if nothing changed
302 | }
303 | }
304 | });
305 | });
306 |
307 |
308 | //milestones checkbox
309 | taskRow.find(":checkbox").click(function () {
310 | var el = $(this);
311 | var row = el.closest("tr");
312 | var taskId = row.attr("taskId");
313 |
314 | var task = self.master.getTask(taskId);
315 |
316 | //update task from editor
317 | var field = el.prop("name");
318 |
319 | if (field == "startIsMilestone" || field == "endIsMilestone") {
320 | self.master.beginTransaction();
321 | //milestones
322 | task[field] = el.prop("checked");
323 | resynchDates(el, row.find("[name=start]"), row.find("[name=startIsMilestone]"), row.find("[name=duration]"), row.find("[name=end]"), row.find("[name=endIsMilestone]"));
324 | self.master.endTransaction();
325 | }
326 |
327 | });
328 |
329 |
330 | //binding on blur for task update (date exluded as click on calendar blur and then focus, so will always return false, its called refreshing the task row)
331 | taskRow.find("input:text:not(.date)").focus(function () {
332 | $(this).updateOldValue();
333 |
334 | }).blur(function (event) {
335 | var el = $(this);
336 | var row = el.closest("tr");
337 | var taskId = row.attr("taskId");
338 | var task = self.master.getTask(taskId);
339 | //update task from editor
340 | var field = el.prop("name");
341 | //console.debug("blur",field)
342 |
343 | if (el.isValueChanged()) {
344 | self.master.beginTransaction();
345 |
346 | if (field == "depends") {
347 |
348 | var oldDeps = task.depends;
349 | task.depends = el.val();
350 |
351 |
352 | // update links
353 | var linkOK = self.master.updateLinks(task);
354 | if (linkOK) {
355 | //synchronize status from superiors states
356 | var sups = task.getSuperiors();
357 |
358 |
359 | /*
360 | for (var i = 0; i < sups.length; i++) {
361 | if (!sups[i].from.synchronizeStatus())
362 | break;
363 | }
364 | */
365 |
366 | var oneFailed=false;
367 | var oneUndefined=false;
368 | var oneActive=false;
369 | var oneSuspended=false;
370 | for (var i = 0; i < sups.length; i++) {
371 | oneFailed=oneFailed|| sups[i].from.status=="STATUS_FAILED";
372 | oneUndefined=oneUndefined|| sups[i].from.status=="STATUS_UNDEFINED";
373 | oneActive=oneActive|| sups[i].from.status=="STATUS_ACTIVE";
374 | oneSuspended=oneSuspended|| sups[i].from.status=="STATUS_SUSPENDED";
375 | }
376 |
377 | if (oneFailed){
378 | task.changeStatus("STATUS_FAILED")
379 | } else if (oneUndefined){
380 | task.changeStatus("STATUS_UNDEFINED")
381 | } else if (oneActive){
382 | task.changeStatus("STATUS_SUSPENDED")
383 | } else if (oneSuspended){
384 | task.changeStatus("STATUS_SUSPENDED")
385 | } else {
386 | task.changeStatus("STATUS_ACTIVE")
387 | }
388 |
389 |
390 | self.master.changeTaskDeps(task); //dates recomputation from dependencies
391 | }
392 |
393 | } else if (field == "duration") {
394 | var dates = resynchDates(el, row.find("[name=start]"), row.find("[name=startIsMilestone]"), row.find("[name=duration]"), row.find("[name=end]"), row.find("[name=endIsMilestone]"));
395 | self.master.changeTaskDates(task, dates.start, dates.end);
396 |
397 | } else if (field == "name" && el.val() == "") { // remove unfilled task
398 | var par = task.getParent();
399 | task.deleteTask();
400 | self.fillEmptyLines();
401 |
402 | if (par) self.refreshExpandStatus(par);
403 | self.master.gantt.synchHighlight();
404 |
405 |
406 | } else if (field == "progress" ) {
407 | task[field]=parseFloat(el.val())||0;
408 | el.val(task[field]);
409 |
410 | } else {
411 | task[field] = el.val();
412 | }
413 | self.master.endTransaction();
414 |
415 | } else if (field == "name" && el.val() == "") { // remove unfilled task even if not changed
416 | if (task.getRow()!=0) {
417 | var par = task.getParent();
418 | task.deleteTask();
419 | self.fillEmptyLines();
420 | if (par) self.refreshExpandStatus(par);
421 | self.master.gantt.synchHighlight();
422 | }else {
423 | el.oneTime(1,"foc",function(){$(this).focus()}); //
424 | event.preventDefault();
425 | //return false;
426 | }
427 |
428 | }
429 | });
430 |
431 | //cursor key movement
432 | taskRow.find("input").keydown(function (event) {
433 | var theCell = $(this);
434 | var theTd = theCell.parent();
435 | var theRow = theTd.parent();
436 | var col = theTd.prevAll("td").length;
437 |
438 | var ret = true;
439 | if (!event.ctrlKey) {
440 | switch (event.keyCode) {
441 |
442 | case 37: //left arrow
443 | if (!theCell.is(":text") || (!this.selectionEnd || this.selectionEnd == 0))
444 | theTd.prev().find("input").focus();
445 | break;
446 | case 39: //right arrow
447 | if (!theCell.is(":text") || (!this.selectionEnd || this.selectionEnd == this.value.length))
448 | theTd.next().find("input").focus();
449 | break;
450 |
451 | case 38: //up arrow
452 | //var prevRow = theRow.prev();
453 | var prevRow = theRow.prevAll(":visible:first");
454 | var td = prevRow.find("td").eq(col);
455 | var inp = td.find("input");
456 |
457 | if (inp.length > 0)
458 | inp.focus();
459 | break;
460 | case 40: //down arrow
461 | //var nextRow = theRow.next();
462 | var nextRow = theRow.nextAll(":visible:first");
463 | var td = nextRow.find("td").eq(col);
464 | var inp = td.find("input");
465 | if (inp.length > 0)
466 | inp.focus();
467 | else
468 | nextRow.click(); //create a new row
469 | break;
470 | case 36: //home
471 | break;
472 | case 35: //end
473 | break;
474 |
475 | case 9: //tab
476 | case 13: //enter
477 | break;
478 | }
479 | }
480 | return ret;
481 |
482 | }).focus(function () {
483 | $(this).closest("tr").click();
484 | });
485 |
486 |
487 | //change status
488 | taskRow.find(".taskStatus").click(function () {
489 | var el = $(this);
490 | var tr = el.closest("[taskid]");
491 | var taskId = tr.attr("taskid");
492 | var task = self.master.getTask(taskId);
493 |
494 | var changer = $.JST.createFromTemplate({}, "CHANGE_STATUS");
495 | changer.find("[status=" + task.status + "]").addClass("selected");
496 | changer.find(".taskStatus").click(function (e) {
497 | e.stopPropagation();
498 | var newStatus = $(this).attr("status");
499 | changer.remove();
500 | self.master.beginTransaction();
501 | task.changeStatus(newStatus);
502 | self.master.endTransaction();
503 | el.attr("status", task.status);
504 | });
505 | el.oneTime(3000, "hideChanger", function () {
506 | changer.remove();
507 | });
508 | el.after(changer);
509 | });
510 |
511 | };
512 |
513 |
514 | GridEditor.prototype.openFullEditor = function (task, editOnlyAssig) {
515 | var self = this;
516 |
517 | if (!self.master.permissions.canSeePopEdit)
518 | return;
519 |
520 | var taskRow=task.rowElement;
521 |
522 | //task editor in popup
523 | var taskId = taskRow.attr("taskId");
524 | //console.debug(task);
525 |
526 | //make task editor
527 | var taskEditor = $.JST.createFromTemplate(task, "TASK_EDITOR");
528 |
529 | //hide task data if editing assig only
530 | if (editOnlyAssig) {
531 | taskEditor.find(".taskData").hide();
532 | taskEditor.find(".assigsTableWrapper").height(455);
533 | taskEditor.prepend("\""+task.name+"\"
");
534 | }
535 |
536 | //got to extended editor
537 | if (task.isNew()|| !self.master.permissions.canSeeFullEdit){
538 | taskEditor.find("#taskFullEditor").remove();
539 | } else {
540 | taskEditor.bind("openFullEditor.gantt",function () {
541 | window.location.href=contextPath+"/applications/teamwork/task/taskEditor.jsp?CM=ED&OBJID="+task.id;
542 | });
543 | }
544 |
545 |
546 | taskEditor.find("#name").val(task.name);
547 | taskEditor.find("#description").val(task.description);
548 | taskEditor.find("#code").val(task.code);
549 | taskEditor.find("#progress").val(task.progress ? parseFloat(task.progress) : 0).prop("readonly",task.progressByWorklog==true);
550 | taskEditor.find("#progressByWorklog").prop("checked",task.progressByWorklog);
551 | taskEditor.find("#status").val(task.status);
552 | taskEditor.find("#type").val(task.typeId);
553 | taskEditor.find("#type_txt").val(task.type);
554 | taskEditor.find("#relevance").val(task.relevance);
555 | //cvc_redraw(taskEditor.find(".cvcComponent"));
556 |
557 |
558 | if (task.startIsMilestone)
559 | taskEditor.find("#startIsMilestone").prop("checked", true);
560 | if (task.endIsMilestone)
561 | taskEditor.find("#endIsMilestone").prop("checked", true);
562 |
563 | taskEditor.find("#duration").val(task.duration);
564 | var startDate = taskEditor.find("#start");
565 | startDate.val(new Date(task.start).format());
566 | //start is readonly in case of deps
567 | if (task.depends || !this.master.permissions.canWrite && !task.canWrite) {
568 | startDate.attr("readonly", "true");
569 | } else {
570 | startDate.removeAttr("readonly");
571 | }
572 |
573 | taskEditor.find("#end").val(new Date(task.end).format());
574 |
575 | //make assignments table
576 | var assigsTable = taskEditor.find("#assigsTable");
577 | assigsTable.find("[assId]").remove();
578 | // loop on assignments
579 | for (var i = 0; i < task.assigs.length; i++) {
580 | var assig = task.assigs[i];
581 | var assigRow = $.JST.createFromTemplate({task: task, assig: assig}, "ASSIGNMENT_ROW");
582 | assigsTable.append(assigRow);
583 | }
584 |
585 | if (!self.master.permissions.canWrite || !task.canWrite) {
586 | taskEditor.find("input,textarea").prop("readOnly", true);
587 | taskEditor.find("input:checkbox,select").prop("disabled", true);
588 | taskEditor.find("#saveButton").remove();
589 | taskEditor.find(".button").addClass("disabled");
590 |
591 | } else {
592 |
593 | //bind dateField on dates, duration
594 | taskEditor.find("#start,#end,#duration").click(function () {
595 | var input = $(this);
596 | if (input.is("[entrytype=DATE]")) {
597 | input.dateField({
598 | inputField: input,
599 | callback: function (d) {$(this).blur();}
600 | });
601 | }
602 | }).blur(function () {
603 | var inp = $(this);
604 | if (inp.validateField()) {
605 | resynchDates(inp, taskEditor.find("[name=start]"), taskEditor.find("[name=startIsMilestone]"), taskEditor.find("[name=duration]"), taskEditor.find("[name=end]"), taskEditor.find("[name=endIsMilestone]"));
606 | //workload computation
607 | if (typeof(workloadDatesChanged)=="function")
608 | workloadDatesChanged();
609 | }
610 | });
611 |
612 | taskEditor.find("#startIsMilestone,#endIsMilestone").click(function () {
613 | var inp = $(this);
614 | resynchDates(inp, taskEditor.find("[name=start]"), taskEditor.find("[name=startIsMilestone]"), taskEditor.find("[name=duration]"), taskEditor.find("[name=end]"), taskEditor.find("[name=endIsMilestone]"));
615 | });
616 |
617 | //bind add assignment
618 | var cnt=0;
619 | taskEditor.find("#addAssig").click(function () {
620 | cnt++;
621 | var assigsTable = taskEditor.find("#assigsTable");
622 | var assigRow = $.JST.createFromTemplate({task: task, assig: {id: "tmp_" + new Date().getTime()+"_"+cnt}}, "ASSIGNMENT_ROW");
623 | assigsTable.append(assigRow);
624 | $("#bwinPopupd").scrollTop(10000);
625 | }).click();
626 |
627 | //save task
628 | taskEditor.bind("saveFullEditor.gantt",function () {
629 | //console.debug("saveFullEditor");
630 | var task = self.master.getTask(taskId); // get task again because in case of rollback old task is lost
631 |
632 | self.master.beginTransaction();
633 | task.name = taskEditor.find("#name").val();
634 | task.description = taskEditor.find("#description").val();
635 | task.code = taskEditor.find("#code").val();
636 | task.progress = parseFloat(taskEditor.find("#progress").val());
637 | //task.duration = parseInt(taskEditor.find("#duration").val()); //bicch rimosso perchè devono essere ricalcolata dalla start end, altrimenti sbaglia
638 | task.startIsMilestone = taskEditor.find("#startIsMilestone").is(":checked");
639 | task.endIsMilestone = taskEditor.find("#endIsMilestone").is(":checked");
640 |
641 | task.type = taskEditor.find("#type_txt").val();
642 | task.typeId = taskEditor.find("#type").val();
643 | task.relevance = taskEditor.find("#relevance").val();
644 | task.progressByWorklog= taskEditor.find("#progressByWorklog").is(":checked");
645 |
646 | //set assignments
647 | var cnt=0;
648 | taskEditor.find("tr[assId]").each(function () {
649 | var trAss = $(this);
650 | var assId = trAss.attr("assId");
651 | var resId = trAss.find("[name=resourceId]").val();
652 | var resName = trAss.find("[name=resourceId_txt]").val(); // from smartcombo text input part
653 | var roleId = trAss.find("[name=roleId]").val();
654 | var effort = millisFromString(trAss.find("[name=effort]").val(),true);
655 |
656 | //check if the selected resource exists in ganttMaster.resources
657 | var res= self.master.getOrCreateResource(resId,resName);
658 |
659 | //if resource is not found nor created
660 | if (!res)
661 | return;
662 |
663 | //check if an existing assig has been deleted and re-created with the same values
664 | var found = false;
665 | for (var i = 0; i < task.assigs.length; i++) {
666 | var ass = task.assigs[i];
667 |
668 | if (assId == ass.id) {
669 | ass.effort = effort;
670 | ass.roleId = roleId;
671 | ass.resourceId = res.id;
672 | ass.touched = true;
673 | found = true;
674 | break;
675 |
676 | } else if (roleId == ass.roleId && res.id == ass.resourceId) {
677 | ass.effort = effort;
678 | ass.touched = true;
679 | found = true;
680 | break;
681 |
682 | }
683 | }
684 |
685 | if (!found && resId && roleId) { //insert
686 | cnt++;
687 | //console.debug("adding assig row:", assId,resId,resName,roleId,effort)
688 | var ass = task.createAssignment("tmp_" + new Date().getTime()+"_"+cnt, resId, roleId, effort);
689 | ass.touched = true;
690 | }
691 |
692 | });
693 |
694 | //console.debug("task.assigs",task.assigs,task.assigs.length)
695 | //remove untouched assigs
696 | task.assigs = task.assigs.filter(function (ass) {
697 | var ret = ass.touched;
698 | delete ass.touched;
699 | return ret;
700 | });
701 | //console.debug("task.assigs",task.assigs,task.assigs.length)
702 |
703 | //change dates
704 | task.setPeriod(Date.parseString(taskEditor.find("#start").val()).getTime(), Date.parseString(taskEditor.find("#end").val()).getTime() + (3600000 * 22));
705 |
706 | //change status
707 | task.changeStatus(taskEditor.find("#status").val());
708 |
709 | if (self.master.endTransaction()) {
710 | taskEditor.find(":input").updateOldValue();
711 | closeBlackPopup();
712 | }
713 |
714 | });
715 | }
716 |
717 | taskEditor.attr("alertonchange","true");
718 | var ndo = createModalPopup(800, 450).append(taskEditor);//.append("")
719 | //var ndo = createModalPopup(800, 650).append("")
720 |
721 | //workload computation
722 | if (typeof(workloadDatesChanged)=="function")
723 | workloadDatesChanged();
724 |
725 |
726 |
727 | };
728 |
--------------------------------------------------------------------------------