common.ui.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370
  1. window.ignoreTips = {
  2. 'beyondBudgetTip' : false,
  3. 'dateTip' : false
  4. };
  5. window.toggleBudgetUnit = function(unit)
  6. {
  7. $('[data-name="budget"] > .has-prefix > .input-control-prefix > a').text(currencySymbol[unit]);
  8. $('[name="budgetUnit"]').val(unit);
  9. };
  10. var batchEditDateTips = new Array();
  11. /**
  12. * 设置计划结束时间。
  13. * Set plan end date.
  14. *
  15. * @access public
  16. * @return void
  17. */
  18. function setDate()
  19. {
  20. const delta = $('input[name=delta]:checked').val();
  21. computeEndDate(delta);
  22. }
  23. /**
  24. * 计算两个时间的天数。
  25. * Compute delta of two days.
  26. *
  27. * @param string date1
  28. * @param string date2
  29. * @access public
  30. * @return int
  31. */
  32. function computeDaysDelta(date1, date2)
  33. {
  34. date1 = zui.createDate(date1);
  35. date2 = zui.createDate(date2);
  36. delta = (date2 - date1) / (1000 * 60 * 60 * 24) + 1;
  37. if(isNaN(delta)) return;
  38. weekEnds = 0;
  39. for(i = 0; i < delta; i++)
  40. {
  41. if((weekend == 2 && date1.getDay() == 6) || date1.getDay() == 0) weekEnds ++;
  42. date1 = date1.valueOf();
  43. date1 += 1000 * 60 * 60 * 24;
  44. date1 = new Date(date1);
  45. }
  46. return delta - weekEnds;
  47. }
  48. /**
  49. * 计算可用工作日天数。
  50. * Compute work days.
  51. *
  52. * @param string currentID
  53. * @access public
  54. * @return void
  55. */
  56. window.computeWorkDays = function(e)
  57. {
  58. isBactchEdit = false;
  59. let currentID = typeof e == 'object' ? $(e.target).attr('id') : '';
  60. if(currentID)
  61. {
  62. index = currentID.replace('begins[', '');
  63. index = index.replace('ends[', '');
  64. index = index.replace(']', '');
  65. if(!isNaN(index)) isBactchEdit = true;
  66. }
  67. if(isBactchEdit)
  68. {
  69. beginDate = $('#begins\\[' + index + '\\]').val();
  70. endDate = $('#ends\\[' + index + '\\]').val();
  71. }
  72. else
  73. {
  74. beginDate = $('#begin').zui('datepicker').$.state.value;
  75. endDate = $('#end').zui('datepicker').$.state.value;
  76. var begin = zui.createDate(beginDate);
  77. var end = zui.createDate(endDate);
  78. var time = end.getTime() - begin.getTime();
  79. var days = String(parseInt(time / zui.TIME_DAY) + 1);
  80. $("#delta" + days).prop('checked', true);
  81. if(endDate === longTime) $("#delta999").prop('checked', true);
  82. }
  83. outOfDateTip(isBactchEdit ? index : 0);
  84. }
  85. /**
  86. * 计算并设置计划完成时间。
  87. * Compute the end date for project.
  88. *
  89. * @param int delta
  90. * @access public
  91. * @return void
  92. */
  93. function computeEndDate(delta)
  94. {
  95. let $begin = $('#begin').zui('datepicker');
  96. let $end = $('#end').zui('datepicker');
  97. let beginDate = $begin.$.state.value;
  98. if(!beginDate) return;
  99. delta = parseInt(delta);
  100. if(delta == 999)
  101. {
  102. $end.$.setDate('');
  103. $end.render({disabled: true});
  104. outOfDateTip();
  105. $('#end').addClass('hidden');
  106. $('#end').next().removeClass('hidden');
  107. return false;
  108. }
  109. $end.render({disabled: false});
  110. $('#days').closest('.form-row').removeClass('hidden');
  111. beginDate = zui.createDate(beginDate);
  112. if((delta == 7 || delta == 14) && (beginDate.getDay() == 1))
  113. {
  114. delta = (weekend == 2) ? (delta - 2) : (delta - 1);
  115. }
  116. $('#end').removeClass('hidden');
  117. $('#end').next().addClass('hidden');
  118. const endDate = zui.formatDate(zui.addDate(beginDate, delta - 1), 'yyyy-MM-dd');
  119. $end.$.setValue(endDate);
  120. computeWorkDays();
  121. }
  122. /**
  123. * If future is checked, disable budget input.
  124. *
  125. * @param object e
  126. * @access public
  127. * @return void
  128. */
  129. window.toggleBudget = function(e)
  130. {
  131. const future = e.target;
  132. if($(future).prop('checked'))
  133. {
  134. $('#budget').val('').attr('disabled', 'disabled');
  135. }
  136. else
  137. {
  138. $('#budget').removeAttr('disabled');
  139. }
  140. }
  141. /**
  142. * If change multiple, set delta.
  143. *
  144. * @param object e
  145. * @access public
  146. * @return void
  147. */
  148. window.toggleMultiple = function(e)
  149. {
  150. const multiple = e.target;
  151. $('#delta_999').closest('.radio-primary').toggle($(multiple).val() != 0);
  152. if($('#delta_999').prop('checked') && $(multiple).val() == 0)
  153. {
  154. $('#delta_999').prop('checked', false);
  155. $('#end').removeAttr('disabled').val('');
  156. $('#days').closest('.form-row').removeClass('hidden');
  157. }
  158. }
  159. /**
  160. * compare childlish date.
  161. *
  162. * @access public
  163. * @return void
  164. */
  165. function compareChildDate()
  166. {
  167. if(window.ignoreTips['dateTip']) return;
  168. if(page == 'create') return;
  169. let begin = $('#begin').zui('datepicker').$.state.value;
  170. let end = $('#end').zui('datepicker').$.state.value;
  171. let selectedProgramID = $('#parent').val();
  172. if($('#dateTip').length > 0) $('#dateTip').closest('.form-row').remove();
  173. if(end == longTime) end = LONG_TIME;
  174. if(end.length > 0 && begin.length > 0)
  175. {
  176. var programEnd = new Date(end);
  177. var programBegin = new Date(begin);
  178. if(typeof(programID) == 'undefined') programID = 0;
  179. $.get($.createLink('project', 'ajaxGetProjectFormInfo', 'objectType=program&objectID=' + programID + '&selectedProgramID=' + selectedProgramID), function(data)
  180. {
  181. var childInfo = JSON.parse(data);
  182. if(childInfo.maxChildEnd == '' || childInfo.minChildBegin == '') return;
  183. var childBegin = new Date(childInfo.minChildBegin);
  184. var childEnd = new Date(childInfo.maxChildEnd);
  185. if(programBegin <= childBegin && programEnd >= childEnd) return;
  186. var dateTip = '';
  187. if(programBegin > childBegin)
  188. {
  189. dateTip = "<tr><td></td><td colspan='2'><span id='dateTip' class='text-remind'><p>" + beginGreatEqualChild + childInfo.minChildBegin + "</p><p id='ignore' onclick='ignoreTip(this)'>" + ignore + "</p></span></td></tr>";
  190. }
  191. else if(programEnd < childEnd)
  192. {
  193. dateTip = "<tr><td></td><td colspan='2'><span id='dateTip' class='text-remind'><p>" + endLessThanChild + childInfo.maxChildEnd + "</p><p id='ignore' onclick='ignoreTip(this)'>" + ignore + "</p></span></td></tr>";
  194. }
  195. $('#dateBox').parent().parent().after(dateTip);
  196. $('#dateTip').parent().css('line-height', '0');
  197. });
  198. }
  199. }
  200. /**
  201. *The date is out of the range of the parent project set, and a prompt is given.
  202. *
  203. * @param string $currentID
  204. * @access public
  205. * @return void
  206. */
  207. function outOfDateTip(currentID)
  208. {
  209. if(window.ignoreTips['dateTip']) return;
  210. let begin = $('#begin').zui('datepicker').$.state.value;
  211. let end = $('#end').zui('datepicker').$.state.value;
  212. if($('#dateTip').length > 0) $('#dateTip').closest('.form-row').remove();
  213. if(end == longTime) end = LONG_TIME;
  214. if(end.length > 0 && begin.length > 0)
  215. {
  216. var selectedProgramID = $('#parent').val();
  217. var programEnd = new Date(end);
  218. var programBegin = new Date(begin);
  219. if(selectedProgramID == 0)
  220. {
  221. compareChildDate();
  222. return;
  223. }
  224. if(typeof(programID) == 'undefined') programID = 0;
  225. $.get($.createLink('project', 'ajaxGetProjectFormInfo', 'objectType=program&objectID=' + programID + "&selectedProgramID=" + selectedProgramID), function(data)
  226. {
  227. var dateTip = '';
  228. var data = JSON.parse(data);
  229. var parentEnd = new Date(data.selectedProgramEnd);
  230. var parentBegin = new Date(data.selectedProgramBegin);
  231. if(programBegin >= parentBegin && programEnd <= parentEnd)
  232. {
  233. compareChildDate();
  234. return;
  235. }
  236. if(programBegin < parentBegin)
  237. {
  238. dateTip = "<div class='form-row' id='dateTipBox'><div class='form-group'><div class='input-group'><span id='dateTip' class='text-remind'><p>" + beginLessThanParent + data.selectedProgramBegin + "</p><p id='ignore' onclick='ignoreTip(this)'>" + ignore + "</p></span></div></div></div>";
  239. }
  240. else if(programEnd > parentEnd)
  241. {
  242. dateTip = "<div class='form-row' id='dateTipBox'><div class='form-group'><div class='input-group'><span id='dateTip' class='text-remind'><p>" + endGreatThanParent + data.selectedProgramEnd + "</p><p id='ignore' onclick='ignoreTip(this)'>" + ignore + "</p></span></div></div></div>";
  243. }
  244. $('#begin').closest('.form-row').after(dateTip);
  245. });
  246. }
  247. }
  248. /**
  249. * Append prompt when the budget exceeds the parent project set.
  250. *
  251. * @access public
  252. * @return void
  253. */
  254. window.budgetOverrunTips = function(e)
  255. {
  256. if(window.ignoreTips['beyondBudgetTip']) return;
  257. var selectedProgramID = $('[name=parent]').zui('picker').$.state.value;
  258. var budget = $('#budget').val();
  259. if(selectedProgramID == 0)
  260. {
  261. $('#budgetTip').addClass('hidden');
  262. return false;
  263. }
  264. if(typeof(programID) == 'undefined') programID = 0;
  265. $.get($.createLink('project', 'ajaxGetProjectFormInfo', 'objectType=program&objectID=' + programID + "&selectedProgramID=" + selectedProgramID), function(data)
  266. {
  267. var data = JSON.parse(data);
  268. if(budget !=0 && budget !== null && budget > data.availableBudget)
  269. {
  270. let ignoreBtn = "<span id='ignore' onclick='ignoreTip(this)'>" + ignore + "</span>";
  271. var tip = budgetOverrun.replace('%s', currencySymbol[data.budgetUnit] + data.availableBudget) + ignoreBtn;
  272. $('#budgetTip').html(tip).removeClass('hidden');
  273. }
  274. });
  275. }
  276. /**
  277. * Make this prompt no longer appear.
  278. *
  279. * @param string $obj
  280. * @access public
  281. * @return void
  282. */
  283. window.ignoreTip = function(obj)
  284. {
  285. var parentID = obj.parentNode.id;
  286. $('#' + parentID).addClass('hidden');
  287. if(parentID == 'dateTip') window.ignoreTips['dateTip'] = true;
  288. if(parentID == 'beyondBudgetTip') window.ignoreTips['beyondBudgetTip'] = true;
  289. }
  290. window.onDateChange = () =>
  291. {
  292. if(window.ignoreTips['dateTip']) return;
  293. let programBegin = $('[name=begin]').val();
  294. let programEnd = $('[name=end]').val();
  295. let parentBegin = $('[data-name=parent]').data('parentBegin');
  296. let parentEnd = $('[data-name=parent]').data('parentEnd');
  297. const ignoreBtn = "<span id='ignore' onclick='ignoreTip(this)'>" + ignore + "</span>";
  298. if(programBegin && parentBegin && new Date(parentBegin) > new Date(programBegin))
  299. {
  300. $('#dateTip').html(beginLessThanParent + parentBegin + ignoreBtn).removeClass('hidden');
  301. }
  302. if(programEnd && parentEnd && new Date(parentEnd) < new Date(programEnd))
  303. {
  304. $('#dateTip').html(endGreatThanParent + parentEnd + ignoreBtn).removeClass('hidden');
  305. }
  306. };
  307. window.getDateMenu = function()
  308. {
  309. if(!endList) return [];
  310. const begin = $('input[name=begin]').val();
  311. if(!begin) return [];
  312. let endMenu = [];
  313. const beginDate = new Date(begin);
  314. for(let key in endList)
  315. {
  316. endMenu.push({'text': endList[key], 'data-set-date': zui.formatDate(new Date(beginDate.getTime() + 1000 * 60 * 60 * 24 * parseInt(key)), 'yyyy-MM-dd')});
  317. }
  318. return endMenu;
  319. }