GanttTaskItem.js 51 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362
  1. // wrapped by build app
  2. define("dojox/gantt/GanttTaskItem", ["dijit","dojo","dojox","dojo/require!dojo/date/locale,dijit/focus"], function(dijit,dojo,dojox){
  3. dojo.provide("dojox.gantt.GanttTaskItem");
  4. dojo.require("dojo.date.locale");
  5. dojo.require("dijit.focus"); // dijit.focus()
  6. dojo.declare("dojox.gantt.GanttTaskControl", null, {
  7. constructor: function(taskInfo, project, chart){
  8. this.ganttChart = chart;
  9. this.project = project;
  10. this.taskItem = taskInfo;
  11. //control variables
  12. this.checkMove = false;
  13. this.checkResize = false;
  14. this.moveChild = false;
  15. this.maxPosXMove = -1;
  16. this.minPosXMove = -1;
  17. this.maxWidthResize = -1;
  18. this.minWidthResize = -1;
  19. this.posX = 0;
  20. this.posY = 0;
  21. this.mouseX = 0;
  22. this.taskItemWidth = 0;
  23. this.isHide = false;
  24. this.hideTasksHeight = 0;
  25. this.isExpanded = true;
  26. this.descrTask = null;
  27. this.cTaskItem = null;
  28. this.cTaskNameItem = null;
  29. this.parentTask = null;
  30. this.predTask = null;
  31. this.childTask = [];
  32. this.childPredTask = [];
  33. this.nextChildTask = null;
  34. this.previousChildTask = null;
  35. this.nextParentTask = null;
  36. this.previousParentTask = null;
  37. },
  38. createConnectingLinesPN: function(){
  39. var arrConnectingLinesNames = [];
  40. var lineVerticalLeft = dojo.create("div", {
  41. innerHTML: " ",
  42. className: "ganttTaskLineVerticalLeft"
  43. }, this.ganttChart.panelNames.firstChild);
  44. var cTaskName = this.cTaskNameItem[0], pcTaskName = this.parentTask.cTaskNameItem[0];
  45. dojo.style(lineVerticalLeft, {
  46. height: (cTaskName.offsetTop - pcTaskName.offsetTop) + "px",
  47. top: (pcTaskName.offsetTop + 5) + "px",
  48. left: (pcTaskName.offsetLeft - 9) + "px"
  49. });
  50. var LineHorizontalLeft = dojo.create("div", {
  51. noShade: true,
  52. color: "#000000",
  53. className: "ganttTaskLineHorizontalLeft"
  54. }, this.ganttChart.panelNames.firstChild);
  55. dojo.style(LineHorizontalLeft, {
  56. left: (pcTaskName.offsetLeft - 9) + "px",
  57. top: (cTaskName.offsetTop + 5) + "px",
  58. height: "1px",
  59. width: (cTaskName.offsetLeft - pcTaskName.offsetLeft + 4) + "px"
  60. });
  61. arrConnectingLinesNames.push(lineVerticalLeft);
  62. arrConnectingLinesNames.push(LineHorizontalLeft);
  63. return arrConnectingLinesNames;
  64. },
  65. createConnectingLinesDS: function(){
  66. var contentData = this.ganttChart.contentData.firstChild;
  67. var arrLines = [];
  68. var arrowImg = new Image();
  69. var arrowImg = dojo.create("div", {
  70. className: "ganttImageArrow"
  71. });
  72. //vertical line
  73. var lineVerticalRight = document.createElement("div");
  74. //horizontal line
  75. var lineHorizontal = document.createElement("div");
  76. var posXPreviousTask = dojo.style(this.predTask.cTaskItem[0], "left");
  77. var posYPreviousTask = dojo.style(this.predTask.cTaskItem[0], "top");
  78. var posXChildTask = dojo.style(this.cTaskItem[0], "left");
  79. var posYChildTask = this.posY + 2;
  80. //width task item
  81. var widthChildTask = parseInt(this.predTask.cTaskItem[0].firstChild.firstChild.width);
  82. var widthPreviousTask = parseInt(this.predTask.cTaskItem[0].firstChild.firstChild.width);
  83. if(posYPreviousTask < posYChildTask){
  84. dojo.addClass(lineVerticalRight, "ganttTaskLineVerticalRight");
  85. dojo.style(lineVerticalRight, {
  86. height: (posYChildTask - this.ganttChart.heightTaskItem / 2 - posYPreviousTask - 3) + "px",
  87. width: "1px",
  88. left: (posXPreviousTask + widthPreviousTask - 20) + "px",
  89. top: (posYPreviousTask + this.ganttChart.heightTaskItem) + "px"
  90. });
  91. dojo.addClass(lineHorizontal, "ganttTaskLineHorizontal");
  92. dojo.style(lineHorizontal, {
  93. width: (15 + (posXChildTask - (widthPreviousTask + posXPreviousTask))) + "px",
  94. left: (posXPreviousTask + widthPreviousTask - 20) + "px",
  95. top: (posYChildTask + 2) + "px"
  96. });
  97. dojo.addClass(arrowImg, "ganttTaskArrowImg");
  98. dojo.style(arrowImg, {
  99. left: (posXChildTask - 7) + "px",
  100. top: (posYChildTask - 1) + "px"
  101. });
  102. }else{
  103. dojo.addClass(lineVerticalRight, "ganttTaskLineVerticalRightPlus");
  104. dojo.style(lineVerticalRight, {
  105. height: (posYPreviousTask + 2 - posYChildTask) + "px",
  106. width: "1px",
  107. left: (posXPreviousTask + widthPreviousTask - 20) + "px",
  108. top: (posYChildTask + 2) + "px"
  109. });
  110. dojo.addClass(lineHorizontal, "ganttTaskLineHorizontalPlus");
  111. dojo.style(lineHorizontal, {
  112. width: (15 + (posXChildTask - (widthPreviousTask + posXPreviousTask))) + "px",
  113. left: (posXPreviousTask + widthPreviousTask - 20) + "px",
  114. top: (posYChildTask + 2) + "px"
  115. });
  116. dojo.addClass(arrowImg, "ganttTaskArrowImgPlus");
  117. dojo.style(arrowImg, {
  118. left: (posXChildTask - 7) + "px",
  119. top: (posYChildTask - 1) + "px"
  120. });
  121. }
  122. contentData.appendChild(lineVerticalRight);
  123. contentData.appendChild(lineHorizontal);
  124. contentData.appendChild(arrowImg);
  125. arrLines.push(lineVerticalRight);
  126. arrLines.push(arrowImg);
  127. arrLines.push(lineHorizontal);
  128. return arrLines;
  129. },
  130. showChildTasks: function(task, isOpen){
  131. if(isOpen){
  132. for(var i = 0; i < task.childTask.length; i++){
  133. var cTask = task.childTask[i],
  134. cTaskItem0 = cTask.cTaskItem[0], cTaskName0 = cTask.cTaskNameItem[0],
  135. cTaskItem1 = cTask.cTaskItem[1], cTaskName1 = cTask.cTaskNameItem[1],
  136. cTaskItem2 = cTask.cTaskItem[2], cTaskName2 = cTask.cTaskNameItem[2];
  137. if(cTaskItem0.style.display == "none"){
  138. cTaskItem0.style.display = "inline";
  139. cTaskName0.style.display = "inline";
  140. cTask.showDescTask();
  141. task.isHide = false;
  142. if(cTaskName2){
  143. cTaskName2.style.display = "inline";
  144. isOpen = cTask.isExpanded;
  145. }
  146. for(var k = 0; k < cTaskItem1.length; k++){
  147. cTaskItem1[k].style.display = "inline";
  148. }
  149. for(var k = 0; k < cTaskName1.length; k++){
  150. cTaskName1[k].style.display = "inline";
  151. }
  152. (cTask.taskIdentifier) && (cTask.taskIdentifier.style.display = "inline");
  153. this.hideTasksHeight += this.ganttChart.heightTaskItem + this.ganttChart.heightTaskItemExtra;
  154. if(cTask.childTask.length > 0){
  155. this.showChildTasks(cTask, isOpen);
  156. }
  157. }
  158. }
  159. }
  160. },
  161. hideChildTasks: function(task){
  162. for(var i = 0; i < task.childTask.length; i++){
  163. var cTask = task.childTask[i],
  164. cTaskItem0 = cTask.cTaskItem[0], cTaskName0 = cTask.cTaskNameItem[0],
  165. cTaskItem1 = cTask.cTaskItem[1], cTaskName1 = cTask.cTaskNameItem[1],
  166. cTaskItem2 = cTask.cTaskItem[2], cTaskName2 = cTask.cTaskNameItem[2];
  167. if(cTaskItem0.style.display != "none"){
  168. cTaskItem0.style.display = "none";
  169. cTaskName0.style.display = "none";
  170. cTask.hideDescTask();
  171. task.isHide = true;
  172. if(cTaskName2){
  173. cTaskName2.style.display = "none";
  174. }
  175. for(var k = 0; k < cTaskItem1.length; k++){
  176. cTaskItem1[k].style.display = "none";
  177. }
  178. for(var k = 0; k < cTaskName1.length; k++){
  179. cTaskName1[k].style.display = "none";
  180. }
  181. (cTask.taskIdentifier) && (cTask.taskIdentifier.style.display = "none");
  182. this.hideTasksHeight += (this.ganttChart.heightTaskItem + this.ganttChart.heightTaskItemExtra);
  183. if(cTask.childTask.length > 0){
  184. this.hideChildTasks(cTask);
  185. }
  186. }
  187. }
  188. },
  189. shiftCurrentTasks: function(task, height){
  190. this.shiftNextTask(this, height);
  191. task.project.shiftNextProject(task.project, height);
  192. },
  193. shiftTask: function(task, height){
  194. task.posY = task.posY + height;
  195. var taskItem0 = task.cTaskItem[0], taskName0 = task.cTaskNameItem[0],
  196. taskItem1 = task.cTaskItem[1], taskName1 = task.cTaskNameItem[1],
  197. taskItem2 = task.cTaskItem[2], taskName2 = task.cTaskNameItem[2];
  198. taskName0.style.top = parseInt(taskName0.style.top) + height + "px";
  199. if(taskName2){
  200. taskName2.style.top = parseInt(taskName2.style.top) + height + "px";
  201. }
  202. if(task.parentTask){
  203. if(parseInt(this.cTaskNameItem[0].style.top) > parseInt(task.parentTask.cTaskNameItem[0].style.top) &&
  204. (taskName1[0].style.display != "none")){
  205. taskName1[0].style.height = parseInt(taskName1[0].style.height) + height + "px";
  206. }else{
  207. taskName1[0].style.top = parseInt(taskName1[0].style.top) + height + "px";
  208. }
  209. taskName1[1].style.top = parseInt(taskName1[1].style.top) + height + "px";
  210. }
  211. taskItem0.style.top = parseInt(taskItem0.style.top) + height + "px";
  212. task.descrTask.style.top = parseInt(task.descrTask.style.top) + height + "px";
  213. if(task.predTask){
  214. if(((parseInt(this.cTaskItem[0].style.top) > parseInt(task.predTask.cTaskItem[0].style.top)) ||
  215. (this.cTaskItem[0].id == task.predTask.taskItem.id)) &&
  216. taskItem1[0].style.display != "none"){
  217. taskItem1[0].style.height = parseInt(taskItem1[0].style.height) + height + "px";
  218. }else{
  219. taskItem1[0].style.top = parseInt(taskItem1[0].style.top) + height + "px";
  220. }
  221. taskItem1[1].style.top = parseInt(taskItem1[1].style.top) + height + "px";
  222. taskItem1[2].style.top = parseInt(taskItem1[2].style.top) + height + "px";
  223. }
  224. },
  225. shiftNextTask: function(task, height){
  226. if(task.nextChildTask){
  227. this.shiftTask(task.nextChildTask, height);
  228. this.shiftChildTask(task.nextChildTask, height);
  229. this.shiftNextTask(task.nextChildTask, height);
  230. }else if(task.parentTask){
  231. this.shiftNextTask(task.parentTask, height);
  232. }else if(task.nextParentTask){
  233. this.shiftTask(task.nextParentTask, height);
  234. this.shiftChildTask(task.nextParentTask, height);
  235. this.shiftNextTask(task.nextParentTask, height);
  236. }
  237. },
  238. shiftChildTask: function(task, height){
  239. dojo.forEach(task.childTask, function(cTask){
  240. this.shiftTask(cTask, height);
  241. if(cTask.childTask.length > 0){
  242. this.shiftChildTask(cTask, height);
  243. }
  244. }, this);
  245. },
  246. endMove: function(){
  247. var cTask0 = this.cTaskItem[0];
  248. var width = dojo.style(cTask0, "left") - this.posX;
  249. var startTime = this.getDateOnPosition(dojo.style(cTask0, "left"));
  250. startTime = this.checkPos(startTime);
  251. if(this.checkMove){
  252. width = this.ganttChart.getPosOnDate(startTime) - this.posX;
  253. this.moveCurrentTaskItem(width, this.moveChild);
  254. this.project.shiftProjectItem();
  255. }
  256. this.checkMove = false;
  257. this.posX = 0;
  258. this.maxPosXMove = -1;
  259. this.minPosXMove = -1;
  260. cTask0.childNodes[1].firstChild.rows[0].cells[0].innerHTML = "";
  261. this.adjustPanelTime();
  262. if(this.ganttChart.resource){
  263. this.ganttChart.resource.refresh();
  264. }
  265. },
  266. checkPos: function(startTime){
  267. var cTask0 = this.cTaskItem[0];
  268. var h = startTime.getHours();
  269. if(h >= 12){
  270. startTime.setDate(startTime.getDate() + 1);
  271. startTime.setHours(0);
  272. if((parseInt(cTask0.firstChild.firstChild.width) + this.ganttChart.getPosOnDate(startTime) > this.maxPosXMove) && (this.maxPosXMove != -1)){
  273. startTime.setDate(startTime.getDate() - 1);
  274. startTime.setHours(0);
  275. }
  276. }else if((h < 12) && (h != 0)){
  277. startTime.setHours(0);
  278. if((this.ganttChart.getPosOnDate(startTime) < this.minPosXMove)){
  279. startTime.setDate(startTime.getDate() + 1);
  280. }
  281. }
  282. cTask0.style.left = this.ganttChart.getPosOnDate(startTime) + "px";
  283. return startTime;
  284. },
  285. getMaxPosPredChildTaskItem: function(){
  286. var posPredChildTaskItem = 0;
  287. var nextPosPredChildTaskItem = 0;
  288. for(var i = 0; i < this.childPredTask.length; i++){
  289. nextPosPredChildTaskItem = this.getMaxPosPredChildTaskItemInTree(this.childPredTask[i]);
  290. if(nextPosPredChildTaskItem > posPredChildTaskItem){
  291. posPredChildTaskItem = nextPosPredChildTaskItem;
  292. }
  293. }
  294. return posPredChildTaskItem;
  295. },
  296. getMaxPosPredChildTaskItemInTree: function(task){
  297. var cTask0 = task.cTaskItem[0];
  298. var currentPos = parseInt(cTask0.firstChild.firstChild.width) + dojo.style(cTask0, "left");
  299. var posPredChildTaskItem = 0;
  300. var nextPosPredChildTaskItem = 0;
  301. dojo.forEach(task.childPredTask, function(cpTask){
  302. nextPosPredChildTaskItem = this.getMaxPosPredChildTaskItemInTree(cpTask);
  303. if(nextPosPredChildTaskItem > posPredChildTaskItem){
  304. posPredChildTaskItem = nextPosPredChildTaskItem;
  305. }
  306. }, this);
  307. return posPredChildTaskItem > currentPos ? posPredChildTaskItem : currentPos;
  308. },
  309. moveCurrentTaskItem: function(width, moveChild){
  310. var taskItem = this.cTaskItem[0];
  311. this.taskItem.startTime = new Date(this.ganttChart.startDate);
  312. this.taskItem.startTime.setHours(this.taskItem.startTime.getHours() + (parseInt(taskItem.style.left) / this.ganttChart.pixelsPerHour));
  313. this.showDescTask();
  314. var cTask1 = this.cTaskItem[1];
  315. if(cTask1.length > 0){
  316. cTask1[2].style.width = parseInt(cTask1[2].style.width) + width + "px";
  317. cTask1[1].style.left = parseInt(cTask1[1].style.left) + width + "px";
  318. }
  319. dojo.forEach(this.childTask, function(cTask){
  320. if(!cTask.predTask){
  321. this.moveChildTaskItems(cTask, width, moveChild);
  322. }
  323. }, this);
  324. dojo.forEach(this.childPredTask, function(cpTask){
  325. this.moveChildTaskItems(cpTask, width, moveChild);
  326. }, this);
  327. },
  328. moveChildTaskItems: function(task, width, moveChild){
  329. var taskItem = task.cTaskItem[0];
  330. if(moveChild){
  331. taskItem.style.left = parseInt(taskItem.style.left) + width + "px";
  332. task.adjustPanelTime();
  333. task.taskItem.startTime = new Date(this.ganttChart.startDate);
  334. task.taskItem.startTime.setHours(task.taskItem.startTime.getHours() + (parseInt(taskItem.style.left) / this.ganttChart.pixelsPerHour));
  335. var ctItem = task.cTaskItem[1];
  336. dojo.forEach(ctItem, function(item){
  337. item.style.left = parseInt(item.style.left) + width + "px";
  338. }, this);
  339. dojo.forEach(task.childTask, function(cTask){
  340. if(!cTask.predTask){
  341. this.moveChildTaskItems(cTask, width, moveChild);
  342. }
  343. }, this);
  344. dojo.forEach(task.childPredTask, function(cpTask){
  345. this.moveChildTaskItems(cpTask, width, moveChild);
  346. }, this);
  347. }else{
  348. var ctItem = task.cTaskItem[1];
  349. if(ctItem.length > 0){
  350. var item0 = ctItem[0], item2 = ctItem[2];
  351. item2.style.left = parseInt(item2.style.left) + width + "px";
  352. item2.style.width = parseInt(item2.style.width) - width + "px";
  353. item0.style.left = parseInt(item0.style.left) + width + "px";
  354. }
  355. }
  356. task.moveDescTask();
  357. },
  358. adjustPanelTime: function(){
  359. var taskItem = this.cTaskItem[0];
  360. var width = parseInt(taskItem.style.left) + parseInt(taskItem.firstChild.firstChild.width) + this.ganttChart.panelTimeExpandDelta;
  361. width += this.descrTask.offsetWidth;
  362. this.ganttChart.adjustPanelTime(width);
  363. },
  364. getDateOnPosition: function(position){
  365. var date = new Date(this.ganttChart.startDate);
  366. date.setHours(date.getHours() + (position / this.ganttChart.pixelsPerHour));
  367. return date;
  368. },
  369. moveItem: function(event){
  370. var pageX = event.screenX;
  371. var posTaskItem = (this.posX + (pageX - this.mouseX));
  372. var widthTaskItem = parseInt(this.cTaskItem[0].childNodes[0].firstChild.width);
  373. var posTaskItemR = posTaskItem + widthTaskItem;
  374. if(this.checkMove){
  375. if(((this.minPosXMove <= posTaskItem)) &&
  376. ((posTaskItemR <= this.maxPosXMove) || (this.maxPosXMove == -1))){
  377. this.moveTaskItem(posTaskItem);
  378. }
  379. }
  380. },
  381. moveTaskItem: function(posX){
  382. var cTask = this.cTaskItem[0];
  383. cTask.style.left = posX + "px";
  384. cTask.childNodes[1].firstChild.rows[0].cells[0].innerHTML = this.getDateOnPosition(posX).getDate() + '.' + (this.getDateOnPosition(posX).getMonth() + 1) + '.' + this.getDateOnPosition(posX).getUTCFullYear();
  385. },
  386. resizeItem: function(event){
  387. if(this.checkResize){
  388. var taskItem = this.cTaskItem[0];
  389. var mouseX = event.screenX;
  390. var width = (mouseX - this.mouseX);
  391. var widthTaskItem = this.taskItemWidth + (mouseX - this.mouseX);
  392. if(widthTaskItem >= this.taskItemWidth){
  393. if((widthTaskItem <= this.maxWidthResize) || (this.maxWidthResize == -1)){
  394. this.resizeTaskItem(widthTaskItem);
  395. }else if((this.maxWidthResize != -1) && (widthTaskItem > this.maxWidthResize)){
  396. this.resizeTaskItem(this.maxWidthResize);
  397. }
  398. }else if(widthTaskItem <= this.taskItemWidth){
  399. if(widthTaskItem >= this.minWidthResize){
  400. this.resizeTaskItem(widthTaskItem);
  401. }else if(widthTaskItem < this.minWidthResize){
  402. this.resizeTaskItem(this.minWidthResize);
  403. }
  404. }
  405. }
  406. },
  407. resizeTaskItem: function(width){
  408. var taskItem = this.cTaskItem[0];
  409. var countHours = Math.round(width / this.ganttChart.pixelsPerWorkHour);
  410. var trow = taskItem.childNodes[0].firstChild.rows[0],
  411. rc0 = trow.cells[0], rc1 = trow.cells[1];
  412. rc0 && (rc0.firstChild.style.width = parseInt(rc0.width) * width / 100 + "px");
  413. rc1 && (rc1.firstChild.style.width = parseInt(rc1.width) * width / 100 + "px");
  414. taskItem.childNodes[0].firstChild.width = width + "px";
  415. taskItem.childNodes[1].firstChild.width = width + "px";
  416. //resize info
  417. this.cTaskItem[0].childNodes[1].firstChild.rows[0].cells[0].innerHTML = countHours;
  418. var tcNode2 = taskItem.childNodes[2];
  419. tcNode2.childNodes[0].style.width = width + "px";
  420. tcNode2.childNodes[1].style.left = width - 10 + "px";
  421. },
  422. endResizeItem: function(){
  423. var taskItem = this.cTaskItem[0];
  424. if((this.taskItemWidth != parseInt(taskItem.childNodes[0].firstChild.width))){
  425. var posXL = taskItem.offsetLeft;
  426. var posXR = taskItem.offsetLeft + parseInt(taskItem.childNodes[0].firstChild.width);
  427. var countHours = Math.round((posXR - posXL) / this.ganttChart.pixelsPerWorkHour);
  428. this.taskItem.duration = countHours;
  429. if(this.childPredTask.length > 0){
  430. for(var j = 0; j < this.childPredTask.length; j++){
  431. var cpctItem = this.childPredTask[j].cTaskItem[1],
  432. item0 = cpctItem[0], item2 = cpctItem[2], tcNode0 = taskItem.childNodes[0];
  433. item2.style.width = parseInt(item2.style.width) - (parseInt(tcNode0.firstChild.width) - this.taskItemWidth) + "px";
  434. item2.style.left = parseInt(item2.style.left) + (parseInt(tcNode0.firstChild.width) - this.taskItemWidth) + "px";
  435. item0.style.left = parseInt(item0.style.left) + (parseInt(tcNode0.firstChild.width) - this.taskItemWidth) + "px";
  436. }
  437. }
  438. }
  439. this.cTaskItem[0].childNodes[1].firstChild.rows[0].cells[0].innerHTML = "";
  440. this.checkResize = false;
  441. this.taskItemWidth = 0;
  442. this.mouseX = 0;
  443. this.showDescTask();
  444. this.project.shiftProjectItem();
  445. this.adjustPanelTime();
  446. if(this.ganttChart.resource){
  447. this.ganttChart.resource.refresh();
  448. }
  449. },
  450. startMove: function(event){
  451. this.moveChild = event.ctrlKey;
  452. this.mouseX = event.screenX;
  453. this.getMoveInfo();
  454. this.checkMove = true;
  455. this.hideDescTask();
  456. },
  457. showDescTask: function(){
  458. var posX = (parseInt(this.cTaskItem[0].style.left) + this.taskItem.duration * this.ganttChart.pixelsPerWorkHour + 10);
  459. this.descrTask.style.left = posX + "px";
  460. this.descrTask.innerHTML = this.objKeyToStr(this.getTaskOwner());
  461. this.descrTask.style.visibility = 'visible';
  462. },
  463. hideDescTask: function(){
  464. dojo.style(this.descrTask, "visibility", "hidden");
  465. },
  466. buildResourceInfo: function(resourceInfo){
  467. if(this.childTask && this.childTask.length > 0){
  468. for(var i = 0; i < this.childTask.length; i++){
  469. var cTask = this.childTask[i];
  470. cTask.buildResourceInfo(resourceInfo);
  471. }
  472. }
  473. if(dojo.trim(this.taskItem.taskOwner).length > 0){
  474. var owners = this.taskItem.taskOwner.split(";");
  475. for(var i = 0; i < owners.length; i++){
  476. var o = owners[i];
  477. if(dojo.trim(o).length <= 0){
  478. continue;
  479. }
  480. resourceInfo[o] ? (resourceInfo[o].push(this)) : (resourceInfo[o] = [this]);
  481. }
  482. }
  483. },
  484. objKeyToStr: function(obj, delm){
  485. var returnStr = "";
  486. delm = delm || " ";
  487. if(obj){
  488. for(var key in obj){
  489. returnStr += delm + key;
  490. }
  491. }
  492. return returnStr;
  493. },
  494. getTaskOwner: function(){
  495. var tOwner = {};
  496. if(dojo.trim(this.taskItem.taskOwner).length > 0){
  497. var owners = this.taskItem.taskOwner.split(";");
  498. for(var i = 0; i < owners.length; i++){
  499. var o = owners[i];
  500. tOwner[o] = 1;
  501. }
  502. }
  503. dojo.forEach(this.childTask, function(ctask){
  504. dojo.mixin(tOwner, ctask.getTaskOwner());
  505. }, this);
  506. return tOwner;
  507. },
  508. moveDescTask: function(){
  509. var posX = (parseInt(this.cTaskItem[0].style.left) + this.taskItem.duration * this.ganttChart.pixelsPerWorkHour + 10);
  510. this.descrTask.style.left = posX + "px";
  511. },
  512. getMoveInfo: function(){
  513. this.posX = parseInt(this.cTaskItem[0].style.left);
  514. var widthTaskItem = parseInt(this.cTaskItem[0].childNodes[0].firstChild.width);
  515. var posParentTaskItem = !this.parentTask ? 0 : parseInt(this.parentTask.cTaskItem[0].style.left);
  516. var posPredTaskItem = !this.predTask ? 0 : parseInt(this.predTask.cTaskItem[0].style.left) + parseInt(this.predTask.cTaskItem[0].childNodes[0].firstChild.width);
  517. var widthParentTaskItem = !this.parentTask ? 0 : parseInt(this.parentTask.cTaskItem[0].childNodes[0].firstChild.width);
  518. var childPredPosX = 0;
  519. var childParentPosX = 0;
  520. var childParentPosXR = 0;
  521. if(this.childPredTask.length > 0){
  522. var posChildTaskItem = null;
  523. dojo.forEach(this.childPredTask, function(cpTask){
  524. if((!posChildTaskItem) || ((posChildTaskItem) && (posChildTaskItem > parseInt(cpTask.cTaskItem[0].style.left)))){
  525. posChildTaskItem = parseInt(cpTask.cTaskItem[0].style.left);
  526. }
  527. }, this);
  528. childPredPosX = posChildTaskItem;
  529. }
  530. if(this.childTask.length > 0){
  531. var posChildTaskItemR = null;
  532. dojo.forEach(this.childTask, function(cTask){
  533. if((!posChildTaskItemR) || ((posChildTaskItemR) && (posChildTaskItemR > (parseInt(cTask.cTaskItem[0].style.left))))){
  534. posChildTaskItemR = parseInt(cTask.cTaskItem[0].style.left);
  535. }
  536. }, this);
  537. childParentPosXR = posChildTaskItemR;
  538. var posChildTaskItem = null;
  539. dojo.forEach(this.childTask, function(cTask){
  540. if((!posChildTaskItem) || ((posChildTaskItem)
  541. && (posChildTaskItem < (parseInt(cTask.cTaskItem[0].style.left) + parseInt(cTask.cTaskItem[0].firstChild.firstChild.width))))){
  542. posChildTaskItem = parseInt(cTask.cTaskItem[0].style.left) + parseInt(cTask.cTaskItem[0].firstChild.firstChild.width);
  543. }
  544. }, this);
  545. childParentPosX = posChildTaskItem;
  546. }
  547. if(!this.moveChild){
  548. if(this.childPredTask.length > 0){
  549. if(this.maxPosXMove < childPredPosX) this.maxPosXMove = childPredPosX;
  550. }
  551. if(this.childTask.length > 0){
  552. if((this.childPredTask.length > 0) && (this.maxPosXMove - widthTaskItem) > childParentPosXR){
  553. this.maxPosXMove = this.maxPosXMove - ((this.maxPosXMove - widthTaskItem) - childParentPosXR);
  554. }
  555. if(!(this.childPredTask.length > 0)){
  556. this.maxPosXMove = childParentPosXR + widthTaskItem;
  557. }
  558. this.minPosXMove = (childParentPosX - widthTaskItem);
  559. }
  560. if(posParentTaskItem > 0){
  561. if((!(this.childPredTask.length > 0)) && (this.childTask.length > 0)){
  562. if(this.maxPosXMove > posParentTaskItem + widthParentTaskItem){
  563. this.maxPosXMove = posParentTaskItem + widthParentTaskItem;
  564. }
  565. }
  566. if(this.minPosXMove <= posParentTaskItem){
  567. this.minPosXMove = posParentTaskItem;
  568. }
  569. if((!(this.childTask.length > 0)) && (!(this.childPredTask.length > 0))){
  570. this.maxPosXMove = posParentTaskItem + widthParentTaskItem;
  571. }else if((!(this.childTask.length > 0)) && (this.childPredTask.length > 0)){
  572. if((posParentTaskItem + widthParentTaskItem) > posPredTaskItem){
  573. this.maxPosXMove = childPredPosX;
  574. }
  575. }
  576. }
  577. if(posPredTaskItem > 0){
  578. if(this.minPosXMove <= posPredTaskItem){
  579. this.minPosXMove = posPredTaskItem;
  580. }
  581. }
  582. if((posPredTaskItem == 0) && (posParentTaskItem == 0)){
  583. if(this.minPosXMove <= this.ganttChart.initialPos){
  584. this.minPosXMove = this.ganttChart.initialPos;
  585. }
  586. }
  587. }else{
  588. if((posParentTaskItem > 0) && (posPredTaskItem == 0)){
  589. this.minPosXMove = posParentTaskItem;
  590. this.maxPosXMove = posParentTaskItem + widthParentTaskItem;
  591. }else if((posParentTaskItem == 0) && (posPredTaskItem == 0)){
  592. this.minPosXMove = this.ganttChart.initialPos;
  593. this.maxPosXMove = -1;
  594. }else if((posParentTaskItem > 0) && (posPredTaskItem > 0)){
  595. this.minPosXMove = posPredTaskItem;
  596. this.maxPosXMove = posParentTaskItem + widthParentTaskItem;
  597. }else if((posParentTaskItem == 0) && (posPredTaskItem > 0)){
  598. this.minPosXMove = posPredTaskItem;
  599. this.maxPosXMove = -1;
  600. }
  601. if((this.parentTask) && (this.childPredTask.length > 0)){
  602. var posChildTaskItem = this.getMaxPosPredChildTaskItem(this);
  603. var posParentTaskItem = parseInt(this.parentTask.cTaskItem[0].style.left) + parseInt(this.parentTask.cTaskItem[0].firstChild.firstChild.width);
  604. this.maxPosXMove = this.posX + widthTaskItem + posParentTaskItem - posChildTaskItem;
  605. }
  606. }
  607. },
  608. startResize: function(event){
  609. this.mouseX = event.screenX;
  610. this.getResizeInfo();
  611. this.hideDescTask();
  612. this.checkResize = true;
  613. this.taskItemWidth = parseInt(this.cTaskItem[0].firstChild.firstChild.width);
  614. },
  615. getResizeInfo: function(){
  616. var cTask = this.cTaskItem[0];
  617. var posParentTaskItem = !this.parentTask ? 0 : parseInt(this.parentTask.cTaskItem[0].style.left);
  618. var widthParentTaskItem = !this.parentTask ? 0 : parseInt(this.parentTask.cTaskItem[0].childNodes[0].firstChild.width);
  619. var posTaskItem = parseInt(cTask.style.left);
  620. var childPredPosX = 0;
  621. var childParentPosX = 0;
  622. if(this.childPredTask.length > 0){
  623. var posChildTaskItem = null;
  624. dojo.forEach(this.childPredTask, function(cpTask){
  625. if((!posChildTaskItem) || ((posChildTaskItem) && (posChildTaskItem > parseInt(cpTask.cTaskItem[0].style.left)))){
  626. posChildTaskItem = parseInt(cpTask.cTaskItem[0].style.left);
  627. }
  628. }, this);
  629. childPredPosX = posChildTaskItem;
  630. }
  631. if(this.childTask.length > 0){
  632. var posChildTaskItem = null;
  633. dojo.forEach(this.childTask, function(cTask){
  634. if((!posChildTaskItem) || ((posChildTaskItem) && (posChildTaskItem < (parseInt(cTask.cTaskItem[0].style.left) + parseInt(cTask.cTaskItem[0].firstChild.firstChild.width))))){
  635. posChildTaskItem = parseInt(cTask.cTaskItem[0].style.left) + parseInt(cTask.cTaskItem[0].firstChild.firstChild.width);
  636. }
  637. }, this);
  638. childParentPosX = posChildTaskItem;
  639. }
  640. this.minWidthResize = this.ganttChart.pixelsPerDay;
  641. if(this.childTask.length > 0){
  642. this.minWidthResize = childParentPosX - posTaskItem;
  643. }
  644. if((this.childPredTask.length > 0) && (!this.parentTask)){
  645. this.maxWidthResize = childPredPosX - posTaskItem;
  646. }else if((this.childPredTask.length > 0) && (this.parentTask)){
  647. var w1 = posParentTaskItem + widthParentTaskItem - posTaskItem;
  648. var w2 = childPredPosX - posTaskItem;
  649. this.maxWidthResize = Math.min(w1, w2);
  650. }else if((this.childPredTask.length == 0) && (this.parentTask)){
  651. this.maxWidthResize = posParentTaskItem + widthParentTaskItem - posTaskItem;
  652. }
  653. },
  654. createTaskItem: function(){
  655. this.posX = this.ganttChart.getPosOnDate(this.taskItem.startTime);
  656. var itemControl = dojo.create("div", {
  657. id: this.taskItem.id,
  658. className: "ganttTaskItemControl"
  659. });
  660. dojo.style(itemControl, {
  661. left: this.posX + "px",
  662. top: this.posY + "px"
  663. });
  664. var divTaskItem = dojo.create("div", {className: "ganttTaskDivTaskItem"}, itemControl);
  665. var tblTaskItem = dojo.create("table", {
  666. cellPadding: "0",
  667. cellSpacing: "0",
  668. width: this.taskItem.duration * this.ganttChart.pixelsPerWorkHour + "px",
  669. className: "ganttTaskTblTaskItem"
  670. }, divTaskItem);
  671. var rowTblTask = tblTaskItem.insertRow(tblTaskItem.rows.length);
  672. if(this.taskItem.percentage != 0){
  673. var cellTblTask = dojo.create("td", {
  674. height: this.ganttChart.heightTaskItem + "px",
  675. width: this.taskItem.percentage + "%"
  676. }, rowTblTask);
  677. cellTblTask.style.lineHeight = "1px";
  678. var imageProgress = dojo.create("div", {
  679. className: "ganttImageTaskProgressFilled"
  680. }, cellTblTask);
  681. dojo.style(imageProgress, {
  682. width: (this.taskItem.percentage * this.taskItem.duration * this.ganttChart.pixelsPerWorkHour) / 100 + "px",
  683. height: this.ganttChart.heightTaskItem + "px"
  684. });
  685. }
  686. if(this.taskItem.percentage != 100){
  687. var cellTblTask = dojo.create("td", {
  688. height: this.ganttChart.heightTaskItem + "px",
  689. width: (100 - this.taskItem.percentage) + "%"
  690. }, rowTblTask);
  691. cellTblTask.style.lineHeight = "1px";
  692. var imageProgressFill = dojo.create("div", {
  693. className: "ganttImageTaskProgressBg"
  694. }, cellTblTask);
  695. dojo.style(imageProgressFill, {
  696. width: ((100 - this.taskItem.percentage) * this.taskItem.duration * this.ganttChart.pixelsPerWorkHour) / 100 + "px",
  697. height: this.ganttChart.heightTaskItem + "px"
  698. });
  699. }
  700. if(this.ganttChart.isContentEditable){
  701. var divTaskInfo = dojo.create("div", {className: "ganttTaskDivTaskInfo"}, itemControl);
  702. var tblTaskInfo = dojo.create("table", {
  703. cellPadding: "0",
  704. cellSpacing: "0",
  705. height: this.ganttChart.heightTaskItem + "px",
  706. width: this.taskItem.duration * this.ganttChart.pixelsPerWorkHour + "px"
  707. }, divTaskInfo);
  708. var rowTaskInfo = tblTaskInfo.insertRow(0);
  709. var cellTaskInfo = dojo.create("td", {
  710. align: "center",
  711. vAlign: "top",
  712. height: this.ganttChart.heightTaskItem + "px",
  713. className: "ganttMoveInfo"
  714. }, rowTaskInfo);
  715. var divTaskName = dojo.create("div", {className: "ganttTaskDivTaskName"}, itemControl);
  716. var divMove = dojo.create("div", {}, divTaskName);
  717. dojo.create("input", {
  718. className: "ganttTaskDivMoveInput",
  719. type: "text"
  720. }, divMove);
  721. dojo.isIE && dojo.style(divMove, {
  722. background: "#000000",
  723. filter: "alpha(opacity=0)"
  724. });
  725. dojo.style(divMove, {
  726. height: this.ganttChart.heightTaskItem + "px",
  727. width: this.taskItem.duration * this.ganttChart.pixelsPerWorkHour + "px"
  728. });
  729. //Creation resize area
  730. var divResize = dojo.create("div", {className: "ganttTaskDivResize"}, divTaskName);
  731. dojo.create("input", {
  732. className: "ganttTaskDivResizeInput",
  733. type: "text"
  734. }, divResize);
  735. dojo.style(divResize, {
  736. left: (this.taskItem.duration * this.ganttChart.pixelsPerWorkHour - 10) + "px",
  737. height: this.ganttChart.heightTaskItem + "px",
  738. width: "10px"
  739. });
  740. this.ganttChart._events.push(
  741. dojo.connect(divMove, "onmousedown", this, function(event){
  742. //start move
  743. this.moveMoveConn = dojo.connect(document, "onmousemove", this, function(e){
  744. this.checkMove && this.moveItem(e);
  745. });
  746. this.moveUpConn = dojo.connect(document, "onmouseup", this, function(e){
  747. if(this.checkMove){
  748. this.endMove();
  749. this.ganttChart.isMoving = false;
  750. document.body.releaseCapture && document.body.releaseCapture();
  751. dojo.disconnect(this.moveMoveConn);
  752. dojo.disconnect(this.moveUpConn);
  753. }
  754. });
  755. this.startMove(event);
  756. this.ganttChart.isMoving = true;
  757. document.body.setCapture && document.body.setCapture(false);
  758. })
  759. );
  760. this.ganttChart._events.push(
  761. dojo.connect(divMove, "onmouseover", this, function(event){
  762. event.target && (event.target.style.cursor = "move");
  763. })
  764. );
  765. this.ganttChart._events.push(
  766. dojo.connect(divMove, "onmouseout", this, function(event){
  767. event.target.style.cursor = "";
  768. })
  769. );
  770. this.ganttChart._events.push(
  771. dojo.connect(divResize, "onmousedown", this, function(event){
  772. //start resize
  773. this.resizeMoveConn = dojo.connect(document, "onmousemove", this, function(e){
  774. this.checkResize && this.resizeItem(e);
  775. });
  776. this.resizeUpConn = dojo.connect(document, "onmouseup", this, function(e){
  777. if(this.checkResize){
  778. this.endResizeItem();
  779. this.ganttChart.isResizing = false;
  780. document.body.releaseCapture && document.body.releaseCapture();
  781. dojo.disconnect(this.resizeMoveConn);
  782. dojo.disconnect(this.resizeUpConn);
  783. }
  784. });
  785. this.startResize(event);
  786. this.ganttChart.isResizing = true;
  787. document.body.setCapture && document.body.setCapture(false);
  788. })
  789. );
  790. this.ganttChart._events.push(
  791. dojo.connect(divResize, "onmouseover", this, function(event){
  792. (!this.ganttChart.isMoving) && (!this.ganttChart.isResizing) && event.target && (event.target.style.cursor = "e-resize");
  793. })
  794. );
  795. this.ganttChart._events.push(
  796. dojo.connect(divResize, "onmouseout", this, function(event){
  797. !this.checkResize && event.target && (event.target.style.cursor = "");
  798. })
  799. );
  800. }
  801. return itemControl;
  802. },
  803. createTaskNameItem: function(){
  804. var divName = dojo.create("div", {
  805. id: this.taskItem.id,
  806. className: "ganttTaskTaskNameItem",
  807. title: this.taskItem.name + ", id: " + this.taskItem.id + " ",
  808. innerHTML: this.taskItem.name
  809. });
  810. dojo.style(divName, "top", this.posY + "px");
  811. dojo.attr(divName, "tabIndex", 0);
  812. if(this.ganttChart.isShowConMenu){
  813. this.ganttChart._events.push(
  814. dojo.connect(divName, "onmouseover", this, function(event){
  815. dojo.addClass(divName, "ganttTaskTaskNameItemHover");
  816. clearTimeout(this.ganttChart.menuTimer);
  817. this.ganttChart.tabMenu.clear();
  818. this.ganttChart.tabMenu.show(event.target, this);
  819. })
  820. );
  821. this.ganttChart._events.push(
  822. dojo.connect(divName, "onkeydown", this, function(event){
  823. if(event.keyCode == dojo.keys.ENTER){
  824. this.ganttChart.tabMenu.clear();
  825. this.ganttChart.tabMenu.show(event.target, this);
  826. }
  827. if(this.ganttChart.tabMenu.isShow && (event.keyCode == dojo.keys.LEFT_ARROW || event.keyCode == dojo.keys.RIGHT_ARROW)){
  828. dijit.focus(this.ganttChart.tabMenu.menuPanel.firstChild.rows[0].cells[0]);
  829. }
  830. if(this.ganttChart.tabMenu.isShow && event.keyCode == dojo.keys.ESCAPE){
  831. this.ganttChart.tabMenu.hide();
  832. }
  833. })
  834. );
  835. this.ganttChart._events.push(
  836. dojo.connect(divName, "onmouseout", this, function(){
  837. dojo.removeClass(divName, "ganttTaskTaskNameItemHover");
  838. clearTimeout(this.ganttChart.menuTimer);
  839. this.ganttChart.menuTimer = setTimeout(dojo.hitch(this, function(){
  840. this.ganttChart.tabMenu.hide();
  841. }), 200);
  842. })
  843. );
  844. this.ganttChart._events.push(
  845. dojo.connect(this.ganttChart.tabMenu.menuPanel, "onmouseover", this, function(){
  846. clearTimeout(this.ganttChart.menuTimer);
  847. })
  848. );
  849. this.ganttChart._events.push(
  850. dojo.connect(this.ganttChart.tabMenu.menuPanel, "onkeydown", this, function(event){
  851. if(this.ganttChart.tabMenu.isShow && event.keyCode == dojo.keys.ESCAPE){
  852. this.ganttChart.tabMenu.hide();
  853. }
  854. })
  855. );
  856. this.ganttChart._events.push(
  857. dojo.connect(this.ganttChart.tabMenu.menuPanel, "onmouseout", this, function(){
  858. clearTimeout(this.ganttChart.menuTimer);
  859. this.ganttChart.menuTimer = setTimeout(dojo.hitch(this, function(){
  860. this.ganttChart.tabMenu.hide();
  861. }), 200);
  862. })
  863. );
  864. }
  865. return divName;
  866. },
  867. createTaskDescItem: function(){
  868. var posX = (this.posX + this.taskItem.duration * this.ganttChart.pixelsPerWorkHour + 10);
  869. var divDesc = dojo.create("div", {
  870. innerHTML: this.objKeyToStr(this.getTaskOwner()),
  871. className: "ganttTaskDescTask"
  872. });
  873. dojo.style(divDesc, {
  874. left: posX + "px",
  875. top: this.posY + "px"
  876. });
  877. return this.descrTask = divDesc;
  878. },
  879. checkWidthTaskNameItem: function(){
  880. if(this.cTaskNameItem[0].offsetWidth + this.cTaskNameItem[0].offsetLeft > this.ganttChart.maxWidthTaskNames){
  881. var width = this.cTaskNameItem[0].offsetWidth + this.cTaskNameItem[0].offsetLeft - this.ganttChart.maxWidthTaskNames;
  882. var countChar = Math.round(width / (this.cTaskNameItem[0].offsetWidth / this.cTaskNameItem[0].firstChild.length));
  883. var tName = this.taskItem.name.substring(0, this.cTaskNameItem[0].firstChild.length - countChar - 3);
  884. tName += "...";
  885. this.cTaskNameItem[0].innerHTML = tName;
  886. }
  887. },
  888. refreshTaskItem: function(itemControl){
  889. this.posX = this.ganttChart.getPosOnDate(this.taskItem.startTime);
  890. dojo.style(itemControl, {
  891. "left": this.posX + "px"
  892. });
  893. var divTaskItem = itemControl.childNodes[0];
  894. var tblTaskItem = divTaskItem.firstChild;
  895. tblTaskItem.width = (!this.taskItem.duration ? 1 : this.taskItem.duration * this.ganttChart.pixelsPerWorkHour) + "px";
  896. var rowTblTask = tblTaskItem.rows[0];
  897. if(this.taskItem.percentage != 0){
  898. var cellTblTask = rowTblTask.firstChild;
  899. cellTblTask.height = this.ganttChart.heightTaskItem + "px";
  900. cellTblTask.width = this.taskItem.percentage + "%";
  901. cellTblTask.style.lineHeight = "1px";
  902. var imageProgress = cellTblTask.firstChild;
  903. dojo.style(imageProgress, {
  904. width: (!this.taskItem.duration ? 1 : (this.taskItem.percentage * this.taskItem.duration * this.ganttChart.pixelsPerWorkHour / 100)) + "px",
  905. height: this.ganttChart.heightTaskItem + "px"
  906. });
  907. }
  908. if(this.taskItem.percentage != 100){
  909. var cellTblTask = rowTblTask.lastChild;
  910. cellTblTask.height = this.ganttChart.heightTaskItem + "px";
  911. cellTblTask.width = (100 - this.taskItem.percentage) + "%";
  912. cellTblTask.style.lineHeight = "1px";
  913. var imageProgressFill = cellTblTask.firstChild;
  914. dojo.style(imageProgressFill, {
  915. width: (!this.taskItem.duration ? 1 : ((100 - this.taskItem.percentage) * this.taskItem.duration * this.ganttChart.pixelsPerWorkHour / 100)) + "px",
  916. height: this.ganttChart.heightTaskItem + "px"
  917. });
  918. }
  919. if(this.ganttChart.isContentEditable){
  920. var divTaskInfo = itemControl.childNodes[1];
  921. var tblTaskInfo = divTaskInfo.firstChild;
  922. tblTaskInfo.height = this.ganttChart.heightTaskItem + "px";
  923. tblTaskInfo.width = (!this.taskItem.duration ? 1 : (this.taskItem.duration * this.ganttChart.pixelsPerWorkHour)) + "px";
  924. var rowTaskInfo = tblTaskInfo.rows[0];
  925. var cellTaskInfo = rowTaskInfo.firstChild;
  926. cellTaskInfo.height = this.ganttChart.heightTaskItem + "px";
  927. var divTaskName = itemControl.childNodes[2];
  928. var divMove = divTaskName.firstChild;
  929. divMove.style.height = this.ganttChart.heightTaskItem + "px";
  930. divMove.style.width = (!this.taskItem.duration ? 1 : (this.taskItem.duration * this.ganttChart.pixelsPerWorkHour)) + "px";
  931. //Creation resize area
  932. var divResize = divTaskName.lastChild;
  933. dojo.style(divResize, {
  934. "left": (this.taskItem.duration * this.ganttChart.pixelsPerWorkHour - 10) + "px"
  935. });
  936. divResize.style.height = this.ganttChart.heightTaskItem + "px";
  937. divResize.style.width = "10px";
  938. }
  939. return itemControl;
  940. },
  941. refreshTaskDesc: function(divDesc){
  942. var posX = (this.posX + this.taskItem.duration * this.ganttChart.pixelsPerWorkHour + 10);
  943. dojo.style(divDesc, {
  944. "left": posX + "px"
  945. });
  946. return divDesc;
  947. },
  948. refreshConnectingLinesDS: function(arrLines){
  949. var arrowImg = arrLines[1];
  950. var lineVerticalRight = arrLines[0];
  951. //horizontal line
  952. var lineHorizontal = arrLines[2];
  953. var posXPreviousTask = dojo.style(this.predTask.cTaskItem[0], "left");
  954. var posYPreviousTask = dojo.style(this.predTask.cTaskItem[0], "top");
  955. var posXChildTask = dojo.style(this.cTaskItem[0], "left");
  956. var posYChildTask = this.posY + 2;
  957. //width task item
  958. var widthChildTask = parseInt(this.predTask.cTaskItem[0].firstChild.firstChild.width);
  959. var widthPreviousTask = parseInt(this.predTask.cTaskItem[0].firstChild.firstChild.width);
  960. if(posYPreviousTask < posYChildTask){
  961. dojo.style(lineVerticalRight, {
  962. "height": (posYChildTask - this.ganttChart.heightTaskItem / 2 - posYPreviousTask - 3) + "px",
  963. "left": (posXPreviousTask + widthPreviousTask - 20) + "px"
  964. });
  965. dojo.style(lineHorizontal, {
  966. "width": (15 + (posXChildTask - (widthPreviousTask + posXPreviousTask))) + "px",
  967. "left": (posXPreviousTask + widthPreviousTask - 20) + "px"
  968. });
  969. dojo.style(arrowImg, {
  970. "left": (posXChildTask - 7) + "px"
  971. });
  972. }else{
  973. dojo.style(lineVerticalRight, {
  974. "height": (posYPreviousTask + 2 - posYChildTask) + "px",
  975. "left": (posXPreviousTask + widthPreviousTask - 20) + "px"
  976. });
  977. dojo.style(lineHorizontal, {
  978. "width": (15 + (posXChildTask - (widthPreviousTask + posXPreviousTask))) + "px",
  979. "left": (posXPreviousTask + widthPreviousTask - 20) + "px"
  980. });
  981. dojo.style(arrowImg, {
  982. "left": (posXChildTask - 7) + "px"
  983. });
  984. }
  985. return arrLines;
  986. },
  987. postLoadData: function(){
  988. //TODO e.g. task relative info...
  989. },
  990. refresh: function(){
  991. if(this.childTask && this.childTask.length > 0){
  992. dojo.forEach(this.childTask, function(cTask){
  993. cTask.refresh();
  994. }, this);
  995. }
  996. //creation task item
  997. this.refreshTaskItem(this.cTaskItem[0]);
  998. this.refreshTaskDesc(this.cTaskItem[0].nextSibling);
  999. //Create Connecting Lines
  1000. var arrConnectingLines = [];
  1001. if(this.taskItem.previousTask && this.predTask){
  1002. this.refreshConnectingLinesDS(this.cTaskItem[1]);
  1003. }
  1004. return this;
  1005. },
  1006. create: function(){
  1007. var containerTasks = this.ganttChart.contentData.firstChild;
  1008. var containerNames = this.ganttChart.panelNames.firstChild;
  1009. var previousTask = this.taskItem.previousTask;
  1010. var parentTask = this.taskItem.parentTask;
  1011. var isCParentTask = (this.taskItem.cldTasks.length > 0) ? true : false;
  1012. this.cTaskItem = [];
  1013. this.cTaskNameItem = [];
  1014. //creation arrTasks
  1015. if(!parentTask){
  1016. if(this.taskItem.previousParentTask){
  1017. this.previousParentTask = this.project.getTaskById(this.taskItem.previousParentTask.id);
  1018. var lastChildTask = this.ganttChart.getLastChildTask(this.previousParentTask);
  1019. this.posY = parseInt(lastChildTask.cTaskItem[0].style.top)
  1020. + this.ganttChart.heightTaskItem + this.ganttChart.heightTaskItemExtra;
  1021. this.previousParentTask.nextParentTask = this;
  1022. }else{
  1023. this.posY = parseInt(this.project.projectItem[0].style.top)
  1024. + this.ganttChart.heightTaskItem + this.ganttChart.heightTaskItemExtra;
  1025. }
  1026. }
  1027. if(parentTask){
  1028. var task = this.project.getTaskById(this.taskItem.parentTask.id);
  1029. this.parentTask = task;
  1030. if(this.taskItem.previousChildTask){
  1031. this.previousChildTask = this.project.getTaskById(this.taskItem.previousChildTask.id);
  1032. var lastChildTask = this.ganttChart.getLastChildTask(this.previousChildTask);
  1033. this.posY = dojo.style(lastChildTask.cTaskItem[0], "top")
  1034. + this.ganttChart.heightTaskItem + this.ganttChart.heightTaskItemExtra;
  1035. this.previousChildTask.nextChildTask = this;
  1036. }else{
  1037. this.posY = dojo.style(task.cTaskItem[0], "top")
  1038. + this.ganttChart.heightTaskItem + this.ganttChart.heightTaskItemExtra;
  1039. }
  1040. task.childTask.push(this);
  1041. }
  1042. if(previousTask){
  1043. var task = this.project.getTaskById(previousTask.id);
  1044. this.predTask = task;
  1045. task.childPredTask.push(this);
  1046. }
  1047. //creation task item
  1048. this.cTaskItem.push(this.createTaskItem());
  1049. containerTasks.appendChild(this.cTaskItem[0]);
  1050. if(this.ganttChart.panelNames){
  1051. this.cTaskNameItem.push(this.createTaskNameItem());
  1052. this.ganttChart.panelNames.firstChild.appendChild(this.cTaskNameItem[0]);
  1053. }
  1054. containerTasks.appendChild(this.createTaskDescItem());
  1055. //Create Connecting Lines
  1056. var arrConnectingLines = [];
  1057. if(previousTask){
  1058. arrConnectingLines = this.createConnectingLinesDS();
  1059. }
  1060. this.cTaskItem.push(arrConnectingLines);
  1061. if(this.ganttChart.panelNames){
  1062. //Create Connecting Lines
  1063. var arrConnectingLinesNames = [];
  1064. if(parentTask){
  1065. this.cTaskNameItem[0].style.left = dojo.style(this.parentTask.cTaskNameItem[0], "left") + 15 + "px";
  1066. arrConnectingLinesNames = this.createConnectingLinesPN();
  1067. }
  1068. this.checkWidthTaskNameItem();
  1069. //Identifier
  1070. this.checkPosition();
  1071. var treeImg = null;
  1072. if(isCParentTask){
  1073. treeImg = this.createTreeImg();
  1074. }
  1075. this.cTaskNameItem.push(arrConnectingLinesNames);
  1076. this.cTaskNameItem.push(treeImg);
  1077. }
  1078. this.adjustPanelTime();
  1079. return this;
  1080. },
  1081. checkPosition: function(){
  1082. //task name position: check Task Identifier
  1083. if(!this.ganttChart.withTaskId){
  1084. return;
  1085. }
  1086. var pos = dojo.coords(this.cTaskNameItem[0], true);
  1087. if(this.taskIdentifier){
  1088. if(this.childTask && this.childTask.length > 0){
  1089. dojo.forEach(this.childTask, function(cTask){
  1090. cTask.checkPosition();
  1091. }, this);
  1092. }
  1093. dojo.style(this.taskIdentifier, {
  1094. "left": (pos.l + pos.w + 4) + "px",
  1095. "top": (pos.t - 1) + "px"
  1096. });
  1097. }else{
  1098. this.taskIdentifier = dojo.create("div", {
  1099. id: "TaskId_" + this.taskItem.id,
  1100. className: "ganttTaskIdentifier",
  1101. title: this.taskItem.id,
  1102. innerHTML: this.taskItem.id
  1103. }, this.cTaskNameItem[0].parentNode);
  1104. dojo.style(this.taskIdentifier, {
  1105. left: (pos.l + pos.w + 4) + "px",
  1106. top: (pos.t - 1) + "px"
  1107. });
  1108. }
  1109. },
  1110. createTreeImg: function(){
  1111. var treeImg = dojo.create("div", {
  1112. id: this.taskItem.id,
  1113. className: "ganttImageTreeCollapse"
  1114. });
  1115. dojo.attr(treeImg, "tabIndex", 0);
  1116. dojo.forEach(["onclick", "onkeydown"], function(e){
  1117. this.ganttChart._events.push(
  1118. dojo.connect(treeImg, e, this, function(evt){
  1119. if(e == "onkeydown" && evt.keyCode != dojo.keys.ENTER){ return; }
  1120. if(this.isExpanded){
  1121. dojo.removeClass(treeImg, "ganttImageTreeCollapse");
  1122. dojo.addClass(treeImg, "ganttImageTreeExpand");
  1123. this.isExpanded = false;
  1124. this.hideChildTasks(this);
  1125. this.shiftCurrentTasks(this, -this.hideTasksHeight);
  1126. this.ganttChart.checkPosition();
  1127. }else{
  1128. dojo.removeClass(treeImg, "ganttImageTreeExpand");
  1129. dojo.addClass(treeImg, "ganttImageTreeCollapse");
  1130. this.isExpanded = true;
  1131. this.shiftCurrentTasks(this, this.hideTasksHeight);
  1132. this.showChildTasks(this, true);
  1133. this.hideTasksHeight = 0;
  1134. this.ganttChart.checkPosition();
  1135. }
  1136. })
  1137. );
  1138. }, this);
  1139. this.ganttChart.panelNames.firstChild.appendChild(treeImg);
  1140. dojo.addClass(treeImg, "ganttTaskTreeImage");
  1141. dojo.style(treeImg, {
  1142. left: (dojo.style(this.cTaskNameItem[0], "left") - 12) + "px",
  1143. top: (dojo.style(this.cTaskNameItem[0], "top") + 3) + "px"
  1144. });
  1145. return treeImg;
  1146. },
  1147. setPreviousTask: function(previousTaskId){
  1148. if(previousTaskId == ""){
  1149. this.clearPredTask();
  1150. }else{
  1151. var task = this.taskItem;
  1152. if(task.id == previousTaskId){
  1153. return false;
  1154. }
  1155. var predTaskObj = this.project.getTaskById(previousTaskId);
  1156. if(!predTaskObj){
  1157. return false;
  1158. }
  1159. var predTask = predTaskObj.taskItem;
  1160. var a1 = predTask.parentTask == null, a2 = task.parentTask == null;
  1161. if(a1 && !a2 || !a1 && a2 || !a1 && !a2 && (predTask.parentTask.id != task.parentTask.id)){
  1162. return false;
  1163. }
  1164. //check time
  1165. var startTime = task.startTime.getTime(),
  1166. pest = predTask.startTime.getTime(),
  1167. pdur = predTask.duration * 24 * 60 * 60 * 1000 / predTaskObj.ganttChart.hsPerDay;
  1168. if((pest+pdur) > startTime){
  1169. return false;
  1170. }
  1171. // remove current connection
  1172. this.clearPredTask();
  1173. if(!this.ganttChart.checkPosPreviousTask(predTask, task)){
  1174. this.ganttChart.correctPosPreviousTask(predTask, task, this);
  1175. }
  1176. task.previousTaskId = previousTaskId;
  1177. task.previousTask = predTask;
  1178. this.predTask = predTaskObj;
  1179. predTaskObj.childPredTask.push(this);
  1180. this.cTaskItem[1] = this.createConnectingLinesDS();
  1181. }
  1182. return true;
  1183. },
  1184. clearPredTask: function(){
  1185. if(this.predTask){
  1186. var ch = this.predTask.childPredTask;
  1187. for(var i = 0; i < ch.length; i++){
  1188. if(ch[i] == this){
  1189. ch.splice(i, 1);
  1190. break;
  1191. }
  1192. }
  1193. for(var i = 0; i < this.cTaskItem[1].length; i++){
  1194. this.cTaskItem[1][i].parentNode.removeChild(this.cTaskItem[1][i]);
  1195. }
  1196. this.cTaskItem[1] = [];
  1197. this.taskItem.previousTaskId = null;
  1198. this.taskItem.previousTask = null;
  1199. this.predTask = null;
  1200. }
  1201. },
  1202. setStartTime: function(startTime, shiftChild){
  1203. this.moveChild = shiftChild;
  1204. this.getMoveInfo();
  1205. var pos = this.ganttChart.getPosOnDate(startTime);
  1206. if((parseInt(this.cTaskItem[0].firstChild.firstChild.width) + pos > this.maxPosXMove) && (this.maxPosXMove != -1)){
  1207. this.maxPosXMove = -1;
  1208. this.minPosXMove = -1;
  1209. return false;
  1210. }
  1211. if(pos < this.minPosXMove){
  1212. this.maxPosXMove = -1;
  1213. this.minPosXMove = -1;
  1214. return false;
  1215. }
  1216. this.cTaskItem[0].style.left = pos;
  1217. var width = pos - this.posX;
  1218. this.moveCurrentTaskItem(width, shiftChild);
  1219. this.project.shiftProjectItem();
  1220. this.descrTask.innerHTML = this.objKeyToStr(this.getTaskOwner());
  1221. this.adjustPanelTime();
  1222. this.posX = 0;
  1223. this.maxPosXMove = -1;
  1224. this.minPosXMove = -1;
  1225. return true;
  1226. },
  1227. setDuration: function(duration){
  1228. this.getResizeInfo();
  1229. var width = this.ganttChart.getWidthOnDuration(duration);
  1230. if((width > this.maxWidthResize) && (this.maxWidthResize != -1)){
  1231. return false;
  1232. }else if(width < this.minWidthResize){
  1233. return false;
  1234. }else{
  1235. this.taskItemWidth = parseInt(this.cTaskItem[0].firstChild.firstChild.width);
  1236. this.resizeTaskItem(width);
  1237. this.endResizeItem();
  1238. this.descrTask.innerHTML = this.objKeyToStr(this.getTaskOwner());
  1239. return true;
  1240. }
  1241. },
  1242. setTaskOwner: function(owner){
  1243. owner = (owner == null || owner == undefined) ? "" : owner;
  1244. this.taskItem.taskOwner = owner;
  1245. this.descrTask.innerHTML = this.objKeyToStr(this.getTaskOwner());
  1246. return true;
  1247. },
  1248. setPercentCompleted: function(percentage){
  1249. percentage = parseInt(percentage);
  1250. if(isNaN(percentage) || percentage > 100 || percentage < 0){
  1251. return false;
  1252. }
  1253. var trow = this.cTaskItem[0].childNodes[0].firstChild.rows[0],
  1254. rc0 = trow.cells[0], rc1 = trow.cells[1];
  1255. if((percentage != 0) && (percentage != 100)){
  1256. if((this.taskItem.percentage != 0) && (this.taskItem.percentage != 100)){
  1257. rc0.width = percentage + "%";
  1258. rc1.width = 100 - percentage + "%";
  1259. }else if((this.taskItem.percentage == 0) || (this.taskItem.percentage == 100)){
  1260. rc0.parentNode.removeChild(rc0);
  1261. var cellTblTask = dojo.create("td", {
  1262. height: this.ganttChart.heightTaskItem + "px",
  1263. width: percentage + "%"
  1264. }, trow);
  1265. cellTblTask.style.lineHeight = "1px";
  1266. var imageProgressFill = dojo.create("div", {
  1267. className: "ganttImageTaskProgressFilled"
  1268. }, cellTblTask);
  1269. dojo.style(imageProgressFill, {
  1270. width: (percentage * this.taskItem.duration * this.ganttChart.pixelsPerWorkHour) / 100 + "px",
  1271. height: this.ganttChart.heightTaskItem + "px"
  1272. });
  1273. cellTblTask = dojo.create("td", {
  1274. height: this.ganttChart.heightTaskItem + "px",
  1275. width: (100 - percentage) + "%"
  1276. }, trow);
  1277. cellTblTask.style.lineHeight = "1px";
  1278. imageProgressFill = dojo.create("div", {
  1279. className: "ganttImageTaskProgressBg"
  1280. }, cellTblTask);
  1281. dojo.style(imageProgressFill, {
  1282. width: ((100 - percentage) * this.taskItem.duration * this.ganttChart.pixelsPerWorkHour) / 100 + "px",
  1283. height: this.ganttChart.heightTaskItem + "px"
  1284. });
  1285. }
  1286. }else if(percentage == 0){
  1287. if((this.taskItem.percentage != 0) && (this.taskItem.percentage != 100)){
  1288. rc0.parentNode.removeChild(rc0);
  1289. rc1.width = 100 + "%";
  1290. }else{
  1291. dojo.removeClass(rc0.firstChild, "ganttImageTaskProgressFilled");
  1292. dojo.addClass(rc0.firstChild, "ganttImageTaskProgressBg");
  1293. }
  1294. }else if(percentage == 100){
  1295. if((this.taskItem.percentage != 0) && (this.taskItem.percentage != 100)){
  1296. rc1.parentNode.removeChild(rc1);
  1297. rc0.width = 100 + "%";
  1298. }else{
  1299. dojo.removeClass(rc0.firstChild, "ganttImageTaskProgressBg");
  1300. dojo.addClass(rc0.firstChild, "ganttImageTaskProgressFilled");
  1301. }
  1302. }
  1303. this.taskItem.percentage = percentage;
  1304. this.taskItemWidth = parseInt(this.cTaskItem[0].firstChild.firstChild.width);
  1305. this.resizeTaskItem(this.taskItemWidth);
  1306. this.endResizeItem();
  1307. this.descrTask.innerHTML = this.objKeyToStr(this.getTaskOwner());
  1308. return true;
  1309. },
  1310. setName: function(name){
  1311. if(name){
  1312. this.taskItem.name = name;
  1313. this.cTaskNameItem[0].innerHTML = name;
  1314. this.cTaskNameItem[0].title = name;
  1315. this.checkWidthTaskNameItem();
  1316. this.checkPosition();
  1317. this.descrTask.innerHTML = this.objKeyToStr(this.getTaskOwner());
  1318. this.adjustPanelTime();
  1319. }
  1320. }
  1321. });
  1322. dojo.declare("dojox.gantt.GanttTaskItem", null, {
  1323. constructor: function(configuration){
  1324. //id is required
  1325. this.id = configuration.id;
  1326. this.name = configuration.name || this.id;
  1327. this.startTime = configuration.startTime || new Date();
  1328. this.duration = configuration.duration || 8;
  1329. this.percentage = configuration.percentage || 0;
  1330. this.previousTaskId = configuration.previousTaskId || "";
  1331. this.taskOwner = configuration.taskOwner || "";
  1332. this.cldTasks = [];
  1333. this.cldPreTasks = [];
  1334. this.parentTask = null;
  1335. this.previousTask = null;
  1336. this.project = null;
  1337. this.nextChildTask = null;
  1338. this.previousChildTask = null;
  1339. this.nextParentTask = null;
  1340. this.previousParentTask = null;
  1341. },
  1342. addChildTask: function(task){
  1343. this.cldTasks.push(task);
  1344. task.parentTask = this;
  1345. },
  1346. setProject: function(project){
  1347. this.project = project;
  1348. for(var j = 0; j < this.cldTasks.length; j++){
  1349. this.cldTasks[j].setProject(project);
  1350. }
  1351. }
  1352. });
  1353. });