browse.js 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890
  1. $(document).ready(function()
  2. {
  3. /* Set action to up when in last actions. */
  4. $(".moreActions").click(function()
  5. {
  6. var height = $(this).offset().top - $('#actionListTable').offset().top + $(this).parent().parent().height() + $(this).next(".dropdown-menu").height();
  7. var maxHeight = $('#actionListTable').parent().css('max-height').replace("px", "");
  8. if(height > maxHeight)
  9. {
  10. $(this).next(".dropdown-menu").addClass('dropup');
  11. }
  12. });
  13. $(document).on('hide.zui.modal', '#triggerModal.layout-modal', function()
  14. {
  15. var action = $(this).data('action');
  16. $('#actionList tr[data-action=' + action + '] .select-action' ).click();
  17. });
  18. $('#actionList').on('sort.sortable', function(e, data)
  19. {
  20. $.post(createLink('workflowaction', 'sort'), data.orders, function(response)
  21. {
  22. if(response.result == 'success')
  23. {
  24. return location.reload();
  25. }
  26. else
  27. {
  28. bootbox.alert(response.message);
  29. }
  30. }, 'json');
  31. });
  32. $('#actionList .select-action').click(function()
  33. {
  34. $('#actionList tr.checked').removeClass('checked row-check-begin row-check-end');
  35. var $tr = $(this).parents('tr').addClass('checked row-check-begin row-check-end');
  36. var data = $tr.data();
  37. $('#previewArea .panel-heading').html('<strong>' + data.name + '</strong>');
  38. if(data.buildin && data.extensiontype != 'override')
  39. {
  40. $('.layout-buildin-tip').show();
  41. $('.layout-empty-tip').hide();
  42. $('.layout-no-tip').hide();
  43. $('.layout-preview').hide();
  44. }
  45. else if(data.open != 'none')
  46. {
  47. if(data.virtual)
  48. {
  49. var nextModule = data.action.substring(0, data.action.lastIndexOf('_'));
  50. var nextAction = data.action.substring(data.action.lastIndexOf('_') + 1);
  51. var previewLink = createLink('workflowaction', 'ajaxPreview', 'module=' + nextModule + '&action=' + nextAction);
  52. }
  53. else
  54. {
  55. var previewLink = createLink('workflowaction', 'ajaxPreview', 'module=' + window.moduleName + '&action=' + data.action);
  56. }
  57. $('#previewArea .layout-preview').load(previewLink, function(response)
  58. {
  59. if(!response)
  60. {
  61. var setLayoutLink = createLink('workflowlayout', 'admin', 'module=' + window.moduleName + '&action=' + data.action);
  62. var setLayoutButton = "<a href='" + setLayoutLink + "' class='btn btn-secondary setLayout' data-toggle='modal'>" + window.setLayout + '</a>';
  63. $('.layout-buildin-tip').hide();
  64. $('.layout-empty-tip').find('.setLayout').remove();
  65. $('.layout-empty-tip').append(setLayoutButton).show();
  66. $('.layout-no-tip').hide();
  67. $('.layout-preview').hide();
  68. return false;
  69. }
  70. $('.preview-content .chosen').chosen();
  71. $('.example-text-holder').each(function()
  72. {
  73. $(this).attr('data-size', Math.floor(Math.random() * 8) + 2);
  74. });
  75. $('.btn-group').fixInputGroup();
  76. });
  77. $('.layout-buildin-tip').hide();
  78. $('.layout-empty-tip').hide();
  79. $('.layout-no-tip').hide();
  80. $('.layout-preview').show();
  81. }
  82. else
  83. {
  84. $('.layout-buildin-tip').hide();
  85. $('.layout-empty-tip').hide();
  86. $('.layout-no-tip').show();
  87. $('.layout-preview').hide();
  88. }
  89. });
  90. $('#actionList .select-action:first').click();
  91. /* Action */
  92. $(document).on('change', '#actionTable #type', function()
  93. {
  94. $('#batchMode').parents('tr').toggle($(this).val() == 'batch');
  95. $('#position, #show').parents('tr').toggle($(this).val() == 'single');
  96. $('#open option[value=modal]').toggle($(this).val() == 'single');
  97. if($(this).val() == 'batch' && $('#open').val() == 'modal')
  98. {
  99. $('#open').val('normal');
  100. }
  101. });
  102. /* Condition */
  103. $(document).on('change', '#conditionTable #conditionType', function()
  104. {
  105. $('.sqlTR').toggle($(this).val() == 'sql');
  106. $('.dataTR').toggle($(this).val() == 'data');
  107. });
  108. $(document).on('click', '#conditionTable .addCondition', function()
  109. {
  110. $(this).parents('tr').after(window.itemRow.replace(/KEY/g, window.conditionKey));
  111. $(this).parents('tr').next().find('[name*=field]').chosen();
  112. window.conditionKey++;
  113. });
  114. $(document).on('click', '#conditionTable .delCondition', function()
  115. {
  116. $(this).parents('tr').remove();
  117. });
  118. $(document).on('change', '#conditionTable [name*=field]', function()
  119. {
  120. var $tr = $(this).parents('tr');
  121. var key = $tr.data('key');
  122. var name = window.btoa(encodeURI('param[' + key + ']'));
  123. var link = createLink('workflowfield', 'ajaxGetFieldControl', 'module=' + window.moduleName + '&field=' + $(this).val() + '&value=&elementName=' + name);
  124. $tr.find('#paramTD').load(link, function()
  125. {
  126. $tr.find('select.chosen').chosen();
  127. $tr.find('.form-date').datetimepicker(dateOptions);
  128. $tr.find('.form-datetime').datetimepicker(datetimeOptions);
  129. initSelect($tr.find('#paramTD .picker-select'));
  130. });
  131. });
  132. /* Linkage */
  133. $(document).on('change', '#linkageTable [name^=source]', function()
  134. {
  135. processField();
  136. var $tr = $(this).parents('tr');
  137. var $td = $tr.find('td.value');
  138. var field = $(this).find('option:selected').val();
  139. var $value = $(this).parents('tr').find('[name^=value]');
  140. var value = $value.val();
  141. var name = $value.attr('name');
  142. var id = $value.attr('id');
  143. value = window.btoa(encodeURI(value));
  144. name = window.btoa(encodeURI(name));
  145. $td.load(createLink('workflowfield', 'ajaxGetFieldControl', 'module=' + window.moduleName + '&field=' + field + '&value=' + value + '&elementName=' + name + '&elementID=' + id), function()
  146. {
  147. $td.find('select.chosen').chosen();
  148. $tr.find('.form-date').datetimepicker(dateOptions);
  149. $tr.find('.form-datetime').datetimepicker(datetimeOptions);
  150. initSelect($td.find('.picker-select'));
  151. });
  152. });
  153. $(document).on('click', '#linkageTable .addTarget', function()
  154. {
  155. var $rowspan = parseInt($('th.target').attr('rowspan'));
  156. $rowspan++;
  157. $('th.target').attr('rowspan', $rowspan);
  158. $(this).parents('tr').after(window.targetRow.replace(/KEY/g, window.targetIndex));
  159. $(this).parents('tr').next().find('.chosen').chosen();
  160. window.targetIndex++;
  161. processField();
  162. })
  163. $(document).on('click', '#linkageTable .delTarget', function()
  164. {
  165. if($('.delTarget').length == 1)
  166. {
  167. $(this).parents('tr').find('input,select').val('');
  168. $(this).parents('tr').find('.chosen').trigger('chosen:updated');
  169. return false;
  170. }
  171. var rowspan = parseInt($('th.target').attr('rowspan'));
  172. rowspan--;
  173. if($(this).parents('tr').find('th').length)
  174. {
  175. $(this).parents('tr').next().prepend(window.th.replace(/ROWSPAN/g, rowspan));
  176. }
  177. else
  178. {
  179. $('th.target').attr('rowspan', rowspan);
  180. }
  181. $(this).parents('tr').remove();
  182. processField();
  183. })
  184. $(document).on('change', '#linkageTable [name^=target]', function()
  185. {
  186. processField();
  187. });
  188. $(document).on('change', '#linkageTable [name^=source], #linkageTable [name^=operator], #linkageTable [name^=value]', function()
  189. {
  190. $('#sourceLabel').remove();
  191. });
  192. $(document).on('change', '#linkageTable [name^=target], #linkageTable [name^=status]', function()
  193. {
  194. $('#targetLabel').remove();
  195. });
  196. /* Verification */
  197. $(document).on('change', '#verificationTable [name*=\\[field\\]], #verificationTable [name*=paramType]', function()
  198. {
  199. var $tr = $(this).closest('tr');
  200. var $td = $tr.find('.paramTD');
  201. var $paramType = $tr.find('[name*=paramType]');
  202. var module = window.moduleName;
  203. var key = $tr.data('key');
  204. var name = 'param[' + key + ']';
  205. if($tr.hasClass('dataTR')) name = 'verifications[param][' + key + ']';
  206. loadParam($tr, $td, $paramType, module, name);
  207. });
  208. $(document).on('click', '#verificationTable .addVerification, #verificationTable .addVar', function()
  209. {
  210. var $tr = $(this).parents('tr');
  211. if($(this).hasClass('addVar'))
  212. {
  213. $tr.after(window.varRow.replace(/KEY/g, window.verificationVarKey));
  214. window.verificationVarKey++;
  215. }
  216. else if($(this).hasClass('addVerification'))
  217. {
  218. $tr.after(window.verificationRow.replace(/KEY/g, window.verificationDataKey));
  219. window.verificationDataKey++;
  220. }
  221. $tr.next().find('.chosen').chosen();
  222. });
  223. $(document).on('click', '#verificationTable .delVerification, #verificationTable .delVar', function()
  224. {
  225. if($(this).hasClass('delVar'))
  226. {
  227. $('#sql').val($('#sql').val().replace("'$" + $(this).parents('tr').find('#varName').val() + "'", ''));
  228. if($('.delVar').size() == 1)
  229. {
  230. $(this).parents('tr').find('input,select').val('').find('.chosen').trigger('chosen:updated');
  231. $(this).parents('tr').find('.chosen-single span').html('');
  232. return;
  233. }
  234. }
  235. $(this).parents('tr').remove();
  236. });
  237. $(document).on('change', '#verificationTable [name*=varName]', function()
  238. {
  239. if($(this).val() != '') $('#sql').val($('#sql').val() + "'$" + $(this).val() + "'");
  240. });
  241. /* Hook */
  242. $(document).on('change', '.hookForm #conditionType', function()
  243. {
  244. $('.sqlTR').toggle($(this).val() == 'sql');
  245. $('.dataTR').toggle($(this).val() == 'data');
  246. });
  247. $(document).on('change', '.hookForm #action, .hookForm #table', function()
  248. {
  249. $('.fieldTR').toggle($('#action').val() != 'delete');
  250. if($('#action').val() == 'insert')
  251. {
  252. $('.whereTR').hide().find('input,select').attr('disabled', 'disabled');
  253. }
  254. else
  255. {
  256. $('.whereTR').show().find('input,select').removeAttr('disabled');
  257. }
  258. if($(this).attr('id') == 'table')
  259. {
  260. var link = createLink('workflowhook', 'ajaxGetTableFields', 'table=' + $(this).val());
  261. $('.field').load(link, function()
  262. {
  263. $('.field').trigger('chosen:updated');
  264. });
  265. }
  266. loadTarget();
  267. });
  268. $(document).on('click', '.hookForm .toggleCondition', function()
  269. {
  270. var val = $('#condition').val() == 1 ? 0 : 1;
  271. $('#condition').val(val);
  272. $('#conditionDIV').toggle();
  273. });
  274. $(document).on('change', '.hookForm [name*=\\[field\\]], .hookForm [name*=paramType]', function()
  275. {
  276. var $tr = $(this).closest('tr');
  277. var $td = $tr.find('.paramTD');
  278. var $paramType = $tr.find('[name*=paramType]');
  279. var module = $('#table').val();
  280. var key = $tr.data('key');
  281. var name = 'param[' + key + ']';
  282. if($tr.hasClass('dataTR')) module = window.moduleName;
  283. if($tr.hasClass('dataTR')) name = 'conditions[param][' + key + ']';
  284. if($tr.hasClass('fieldTR')) name = 'fields[param][' + key + ']';
  285. if($tr.hasClass('whereTR')) name = 'wheres[param][' + key + ']';
  286. loadParam($tr, $td, $paramType, module, name);
  287. });
  288. $(document).on('click', '.hookForm .addVar, .hookForm .addCondition, .hookForm .addField, .hookForm .addWhere', function()
  289. {
  290. var $tr = $(this).parents('tr');
  291. if($(this).hasClass('addVar'))
  292. {
  293. $tr.after(window.varRow.replace(/KEY/g, window.hookVarKey));
  294. window.hookVarKey++;
  295. }
  296. else if($(this).hasClass('addCondition'))
  297. {
  298. $tr.after(window.conditionRow.replace(/KEY/g, window.hookDataKey));
  299. window.hookDataKey++;
  300. }
  301. else if($(this).hasClass('addField'))
  302. {
  303. $tr.after(window.fieldRow.replace(/KEY/g, window.hookFieldKey));
  304. window.hookFieldKey++;
  305. var link = createLink('workflowhook', 'ajaxGetTableFields', 'table=' + $('#table').val());
  306. $tr.next('tr').find('.field').load(link, function()
  307. {
  308. $(this).trigger('chosen:updated');
  309. });
  310. }
  311. else if($(this).hasClass('addWhere'))
  312. {
  313. $tr.after(window.whereRow.replace(/KEY/g, window.hookWhereKey));
  314. window.hookWhereKey++;
  315. var link = createLink('workflowhook', 'ajaxGetTableFields', 'table=' + $('#table').val());
  316. $tr.next('tr').find('.field').load(link, function()
  317. {
  318. $(this).trigger('chosen:updated');
  319. });
  320. }
  321. $tr.next().find('.chosen').chosen();
  322. $tr.next().find('#param_chosen').hide();
  323. });
  324. $(document).on('click', '.hookForm .delVar, .hookForm .delCondition, .hookForm .delField, .hookForm .delWhere', function()
  325. {
  326. if($(this).hasClass('delVar'))
  327. {
  328. $('#sql').val($('#sql').val().replace("'$" + $(this).parents('tr').find('#varName').val() + "'", ''));
  329. if($('.delVar').size() == 1)
  330. {
  331. $(this).parents('tr').find('input,select').val('').find('.chosen').trigger('chosen:updated');
  332. $(this).parents('tr').find('.chosen-single span').html('');
  333. return;
  334. }
  335. }
  336. $(this).parents('tr').remove();
  337. });
  338. $(document).on('change', '.hookForm [name*=varName]', function()
  339. {
  340. if($(this).val() != '') $('#sql').val($('#sql').val() + "'$" + $(this).val() + "'");
  341. });
  342. $panelHeadingHeight = $('.panel-heading').outerHeight(true);
  343. $panelMarginBottom = $('.panel').css('margin-bottom').replace('px', '');
  344. $editorNavHeight = $('#editorNav').outerHeight(true);
  345. $editorMenuHeight = $('#editorMenu').outerHeight();
  346. $spaceHeight = $('.space.space-sm').outerHeight(true);
  347. $maxHeight = $(window).height() - $panelHeadingHeight - $panelMarginBottom - $editorNavHeight - $editorMenuHeight - $spaceHeight;
  348. $('.panel-body').css('max-height', $maxHeight + 'px');
  349. $(document).on('click', '.addBlock', function()
  350. {
  351. $(this).parents('li').after($('.blockData').html().replace(/blockKey/g, window.blockKey));
  352. window.blockKey++;
  353. return false;
  354. });
  355. $(document).on('click', '.addTab', function()
  356. {
  357. if($(this).parents('li').find('ul').length > 0)
  358. {
  359. $(this).parents('li').find('ul').append($('.tabData').html().replace(/tabKey/g, window.tabKey));
  360. }
  361. else
  362. {
  363. $(this).parents('li').append("<ul class='tabList'>" + $('.tabData').html().replace(/tabKey/g, window.tabKey) + "</ul>");
  364. }
  365. window.tabKey++;
  366. return false;
  367. });
  368. $(document).on('click', '.removeBlock', function()
  369. {
  370. if($(this).parents('ul').children('li').length > 1)
  371. {
  372. $(this).parents('li').remove();
  373. }
  374. else
  375. {
  376. $(this).parents('li').find('input').val('');
  377. }
  378. });
  379. $(document).on('click', '.removeTab', function()
  380. {
  381. if($(this).parents('ul.tabList').children('li').length > 1)
  382. {
  383. $(this).parents('li.tab').remove();
  384. }
  385. else
  386. {
  387. $(this).parents('ul.tabList').remove();
  388. }
  389. });
  390. $(document).on('click', '#blockForm .form-actions .btn', function()
  391. {
  392. $('[name^=key]').each(function(index) {$(this).val(index); });
  393. $('[name^=parent]').each(function(index)
  394. {
  395. $(this).val($(this).parents('li').find('[name^=key]').val());
  396. });
  397. $('#blockForm').submit();
  398. });
  399. $.setAjaxForm('#blockForm', function(response)
  400. {
  401. if(response.result == 'success')
  402. {
  403. setTimeout(function()
  404. {
  405. var modal = $('#triggerModal');
  406. modal.load(modal.attr('ref'), function(){$(this).find('.modal-dialog').css('width', $(this).data('width')); $.zui.ajustModalPosition()})
  407. }, 1200);
  408. }
  409. });
  410. });
  411. /**
  412. * Make sure each field be selected only once.
  413. *
  414. * @access public
  415. * @return void
  416. */
  417. function processField()
  418. {
  419. $('#linkageTable [name^=source]').each(function()
  420. {
  421. var $this = $(this);
  422. var selected = $this.val();
  423. $this.empty().append($('#fieldTemplate').html());
  424. $('#linkageTable [name^=source]').not(this).each(function()
  425. {
  426. var next = $(this).val();
  427. if(next != 0) $this.find('option[value=' + next + ']').remove();
  428. });
  429. $('#linkageTable [name^=target]').each(function()
  430. {
  431. var next = $(this).val();
  432. if(next != 0) $this.find('option[value=' + next + ']').remove();
  433. });
  434. $this.val(selected).trigger('chosen:updated');
  435. });
  436. $('#linkageTable [name^=target]').each(function()
  437. {
  438. var $this = $(this);
  439. var selected = $this.val();
  440. $this.empty().append($('#fieldTemplate').html());
  441. $('#linkageTable [name^=target]').not(this).each(function()
  442. {
  443. var next = $(this).val();
  444. if(next != 0) $this.find('option[value=' + next + ']').remove();
  445. });
  446. $('#linkageTable [name^=source]').each(function()
  447. {
  448. var next = $(this).val();
  449. if(next != 0) $this.find('option[value=' + next + ']').remove();
  450. });
  451. $this.val(selected).trigger('chosen:updated');
  452. });
  453. }
  454. var dateOptions =
  455. {
  456. language: config.clientLang,
  457. weekStart: 1,
  458. todayBtn: 1,
  459. autoclose: 1,
  460. todayHighlight: 1,
  461. startView: 2,
  462. minView: 2,
  463. forceParse: 0,
  464. format: 'yyyy-mm-dd'
  465. };
  466. var datetimeOptions =
  467. {
  468. language: config.clientLang,
  469. weekStart: 1,
  470. todayBtn: 1,
  471. autoclose: 1,
  472. todayHighlight: 1,
  473. startView: 2,
  474. forceParse: 0,
  475. showMeridian: 1,
  476. format: 'yyyy-mm-dd hh:ii'
  477. };
  478. function loadParam($tr, $td, $paramType, module, name)
  479. {
  480. var paramType = $paramType.val();
  481. var value = $td.find('.paramValue').length == 1 ? $td.find('.paramValue').val() : '';
  482. switch(paramType)
  483. {
  484. case 'today':
  485. case 'now':
  486. case 'actor':
  487. case 'currentDept':
  488. case 'deptManager':
  489. $td.html("<input type='text' name='" + name + "' value='" + $paramType.find('option:selected').text() + "' class='form-control' disabled><input type='hidden' name='" + name + "' value='" + paramType + "'>");
  490. break;
  491. case 'form':
  492. case 'record':
  493. var paramFields = paramType + 'Fields';
  494. $td.html(window[paramFields].replace(/NAME/g, name));
  495. $td.find('[name*=param]').val(value);
  496. $td.find('.chosen').chosen();
  497. break;
  498. case 'formula':
  499. var id = name.replace(/\[/g, '').replace(/\]/g, '');
  500. $td.html("<input type='hidden' name='" + name + "' id='" + id + "' value='" + value + "'><a href='javascript:;' class='set-expression'>" + window.formulaLang.set + '</a>');
  501. break;
  502. default:
  503. if(paramType == 'custom')
  504. {
  505. var field = $tr.find('[name*=field]').val();
  506. if(!field)
  507. {
  508. $td.html("<input type='text' name='" + name + "' value='" + value + "' class='form-control'>");
  509. }
  510. else
  511. {
  512. var field = $tr.find('[name*=field]').val();
  513. if(!field) return false;
  514. name = window.btoa(encodeURI(name));
  515. value = window.btoa(encodeURI(value));
  516. var link = createLink('workflowfield', 'ajaxGetFieldControl', 'module=' + module + '&field=' + field + '&value=' + value + '&elementName=' + name + '&elementID=&groupID=' + flowGroup);
  517. $td.load(link, function()
  518. {
  519. $td.find('.chosen').chosen();
  520. $td.find('.form-date').datetimepicker(dateOptions);
  521. $td.find('.form-datetime').datetimepicker(datetimeOptions);
  522. initSelect($td.find('.picker-select'));
  523. });
  524. }
  525. }
  526. else
  527. {
  528. name = window.btoa(encodeURI(name));
  529. value = window.btoa(encodeURI(value));
  530. var link = createLink('workflowfield', 'ajaxGetParamOptions', 'paramType=' + paramType + '&value=' + value + '&elementName=' + name);
  531. $td.load(link, function()
  532. {
  533. $td.find('.chosen').chosen();
  534. $td.find('.form-date').datetimepicker(dateOptions);
  535. $td.find('.form-datetime').datetimepicker(datetimeOptions);
  536. initSelect($td.find('.picker-select'));
  537. });
  538. }
  539. }
  540. }
  541. $(function()
  542. {
  543. $(document).on('click', '.hookForm .btn-expression', function()
  544. {
  545. var text = $(this).html();
  546. var data = $(this).data();
  547. var type = $(this).data('type');
  548. $('.hookForm #expressionDIV .expression').append("<span class='item-expression item-" + type + "'>" + text + "</span>");
  549. window.expression.push(data);
  550. removeErrorLabel();
  551. });
  552. $(document).on('click', '.hookForm .clear-last', function()
  553. {
  554. $('.hookForm #expressionDIV .expression .item-expression:last').remove();
  555. window.expression.pop();
  556. removeErrorLabel();
  557. });
  558. $(document).on('click', '.hookForm .clear-all', function()
  559. {
  560. $('.hookForm #expressionDIV .expression .item-expression').remove();
  561. window.expression.length = 0;
  562. removeErrorLabel();
  563. });
  564. $(document).on('click', '.hookForm .save-expression', function()
  565. {
  566. let hasError = checkExpression();
  567. if(!hasError)
  568. {
  569. let key = $('.hookForm #expressionDIV').attr('data-key');
  570. $('.hookForm .fieldTR[data-key=' + key + '] .paramTD [name*=param]').val(JSON.stringify(window.expression));
  571. $('.hookForm #expressionDIV').hide();
  572. $('.hookForm #hookDIV').show();
  573. $('.hookForm #conditionDIV').toggle($('#condition').val() == 1);
  574. }
  575. });
  576. $(document).on('click', '.hookForm .cancel-expression', function()
  577. {
  578. removeErrorLabel();
  579. $('.hookForm #expressionDIV').hide();
  580. $('.hookForm #hookDIV').show();
  581. $('.hookForm #conditionDIV').toggle($('.hookForm #condition').val() == 1);
  582. });
  583. $(document).on('click', '.hookForm .set-expression', function()
  584. {
  585. var $tr = $(this).parents('tr');
  586. initExpression($tr);
  587. $('.hookForm #expressionLabel').remove();
  588. $('.hookForm #expressionDIV').show();
  589. $('.hookForm #conditionDIV, .hookForm #hookDIV').hide();
  590. });
  591. })
  592. function loadTarget()
  593. {
  594. var action = $('.hookForm #action').val();
  595. var table = $('.hookForm #table').val();
  596. $('.hookForm #expressionDIV .target-detail .detail-content .dynamic-target').remove();
  597. if(action == 'update' && table != window.moduleName)
  598. {
  599. $.get(createLink('workflowhook', 'ajaxGetNumberFields', 'table=' + table), function(fields)
  600. {
  601. $('.hookForm #expressionDIV .target-detail .detail-content').prepend(fields);
  602. });
  603. }
  604. }
  605. function initExpression($tr)
  606. {
  607. let key = $tr.data('key');
  608. let field = $tr.find('.field option:selected').text();
  609. let name = field == '' ? window.formulaLang.common : field;
  610. let expression = $tr.find('.paramTD [name*=param]').val();
  611. $('.hookForm #expressionDIV').attr('data-key', key);
  612. $('.hookForm #expressionDIV .expression .item-name').html(name);
  613. $('.hookForm #expressionDIV .expression .item-expression').remove();
  614. if(expression)
  615. {
  616. window.expression = JSON.parse(expression);
  617. for(var i in window.expression)
  618. {
  619. let current = window.expression[i];
  620. let text = current.text;
  621. if(current.type == 'target')
  622. {
  623. if(current.function)
  624. {
  625. text = window.formulaLang.functions[current.function].replace('%s', window.modules[current.module]).replace('%s', window.moduleFields[current.module][current.field]);
  626. }
  627. else
  628. {
  629. text = window.modules[current.module] + '_' + window.moduleFields[current.module][current.field];
  630. }
  631. }
  632. $('.hookForm #expressionDIV .expression').append("<span class='item-expression item-" + current.type + "'>" + text + "</span>");
  633. }
  634. }
  635. else
  636. {
  637. window.expression.length = 0;
  638. }
  639. }
  640. function checkExpression()
  641. {
  642. if(window.expression.length == 0)
  643. {
  644. appendErrorLabel(window.formulaLang.error.empty);
  645. return true;
  646. }
  647. else
  648. {
  649. let fakeExpression = [];
  650. for(var i in window.expression)
  651. {
  652. let current = window.expression[i];
  653. if(current.type == 'target') fakeExpression.push(current.field);
  654. if(current.type == 'operator') fakeExpression.push(current.operator);
  655. if(current.type == 'number') fakeExpression.push(current.value);
  656. }
  657. fakeExpression = fakeExpression.join('');
  658. try
  659. {
  660. math.parse(fakeExpression);
  661. }
  662. catch(error)
  663. {
  664. appendErrorLabel(window.formulaLang.error.error);
  665. return true;
  666. }
  667. let error = false;
  668. let length = window.expression.length;
  669. for(var i in window.expression)
  670. {
  671. i = parseInt(i);
  672. let current = window.expression[i];
  673. let prev = '';
  674. let next = '';
  675. if(i > 0) prev = window.expression[i - 1];
  676. if(i < length -1) next = window.expression[i + 1];
  677. switch(current.type)
  678. {
  679. case 'target' :
  680. if(prev != '' && (prev.type != 'operator' || prev.operator == ')'))
  681. {
  682. error = true;
  683. break;
  684. }
  685. if(next != '' && (next.type != 'operator' || next.operator == '('))
  686. {
  687. error = true;
  688. break;
  689. }
  690. break;
  691. case 'number' :
  692. if(current.value == '.')
  693. {
  694. if(prev == '' || prev.type != 'number' || prev.value == '.')
  695. {
  696. error = true;
  697. break;
  698. }
  699. if(next == '' || next.type != 'number' || next.value == '.')
  700. {
  701. error = true;
  702. break;
  703. }
  704. }
  705. else
  706. {
  707. if(prev != '' && (prev.type == 'target' || (prev.type == 'operator' && prev.operator == ')')))
  708. {
  709. error = true;
  710. break;
  711. }
  712. if(next != '' && (next.type == 'target' || (next.type == 'operator' && next.operator == '(')))
  713. {
  714. error = true;
  715. break;
  716. }
  717. }
  718. break;
  719. case 'operator' :
  720. switch(current.operator)
  721. {
  722. case '(' :
  723. if(prev != '' && (prev.type != 'operator' || prev.operator == ')'))
  724. {
  725. error = true;
  726. break;
  727. }
  728. if(next == '' || (next.type == 'number' && next.value == '.') || (next.type == 'operator' && next.operator != '('))
  729. {
  730. error = true;
  731. break;
  732. }
  733. break;
  734. case ')' :
  735. if(prev == '' || (prev.type == 'number' && prev.value == '.') || (prev.type == 'operator' && prev.operator != ')'))
  736. {
  737. error = true;
  738. break;
  739. }
  740. if(next != '' && (next.type != 'operator' || next.operator == '('))
  741. {
  742. error = true;
  743. break;
  744. }
  745. break;
  746. default :
  747. if(prev == '' || (prev.type == 'operaor' && prev.operator != ')') || (prev.type == 'number' && prev.value == '.'))
  748. {
  749. error = true;
  750. break;
  751. }
  752. if(next == '' || (next.type == 'operaor' && next.operator != '(') || (next.type == 'number' && next.value == '.'))
  753. {
  754. error = true;
  755. break;
  756. }
  757. }
  758. break;
  759. }
  760. if(error)
  761. {
  762. appendErrorLabel(window.formulaLang.error.error);
  763. return true;
  764. }
  765. }
  766. return false;
  767. }
  768. }
  769. function appendErrorLabel(message)
  770. {
  771. removeErrorLabel();
  772. $('.hookForm #expressionDIV .expression').css('border-color', '#953B39').after("<span id='expressionLabel' for='expression' class='text-error red'>" + message + '</span>');
  773. $('.hookForm').parents('.modal-body').scrollTop(0);
  774. }
  775. function removeErrorLabel()
  776. {
  777. $('.hookForm #expressionDIV .expression').css('border-color', '').next('#expressionLabel').remove();
  778. }