ExtensionElements.js 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. 'use strict';
  2. var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject;
  3. var domQuery = require('min-dom').query,
  4. domClosest = require('min-dom').closest,
  5. domify = require('min-dom').domify,
  6. forEach = require('lodash/forEach');
  7. var elementHelper = require('../../../../helper/ElementHelper'),
  8. cmdHelper = require('../../../../helper/CmdHelper'),
  9. utils = require('../../../../Utils'),
  10. escapeHTML = utils.escapeHTML;
  11. function getSelectBox(node, id) {
  12. var currentTab = domClosest(node, 'div.bpp-properties-tab');
  13. var query = 'select[name=selectedExtensionElement]' + (id ? '[id=cam-extensionElements-' + id + ']' : '');
  14. return domQuery(query, currentTab);
  15. }
  16. function getSelected(node, id) {
  17. var selectBox = getSelectBox(node, id);
  18. return {
  19. value: (selectBox || {}).value,
  20. idx: (selectBox || {}).selectedIndex
  21. };
  22. }
  23. function generateElementId(prefix) {
  24. prefix = prefix + '_';
  25. return utils.nextId(prefix);
  26. }
  27. var CREATE_EXTENSION_ELEMENT_ACTION = 'create-extension-element',
  28. REMOVE_EXTENSION_ELEMENT_ACTION = 'remove-extension-element';
  29. module.exports = function(element, bpmnFactory, options, translate) {
  30. var id = options.id,
  31. prefix = options.prefix || 'elem',
  32. label = options.label || id,
  33. idGeneration = (options.idGeneration === false) ? options.idGeneration : true,
  34. businessObject = options.businessObject || getBusinessObject(element);
  35. var modelProperty = options.modelProperty || 'id';
  36. var getElements = options.getExtensionElements;
  37. var createElement = options.createExtensionElement,
  38. canCreate = typeof createElement === 'function';
  39. var removeElement = options.removeExtensionElement,
  40. canRemove = typeof removeElement === 'function';
  41. var onSelectionChange = options.onSelectionChange;
  42. var hideElements = options.hideExtensionElements,
  43. canBeHidden = typeof hideElements === 'function';
  44. var setOptionLabelValue = options.setOptionLabelValue;
  45. var defaultSize = options.size || 5,
  46. resizable = options.resizable;
  47. var reference = options.reference || undefined;
  48. var selectionChanged = function(element, node, event, scope) {
  49. if (typeof onSelectionChange === 'function') {
  50. return onSelectionChange(element, node, event, scope);
  51. }
  52. };
  53. var createOption = function(value) {
  54. return '<option value="' + escapeHTML(value) + '" data-value data-name="extensionElementValue">' + escapeHTML(value) + '</option>';
  55. };
  56. var initSelectionSize = function(selectBox, optionsLength) {
  57. if (resizable) {
  58. selectBox.size = optionsLength > defaultSize ? optionsLength : defaultSize;
  59. }
  60. };
  61. return {
  62. id: id,
  63. html: '<div class="bpp-row bpp-element-list" ' +
  64. (canBeHidden ? 'data-show="hideElements"' : '') + '>' +
  65. '<label for="cam-extensionElements-' + escapeHTML(id) + '">' + escapeHTML(label) + '</label>' +
  66. '<div class="bpp-field-wrapper">' +
  67. '<select id="cam-extensionElements-' + escapeHTML(id) + '"' +
  68. 'name="selectedExtensionElement" ' +
  69. 'size="' + escapeHTML(defaultSize) + '" ' +
  70. 'data-list-entry-container ' +
  71. 'data-on-change="selectElement">' +
  72. '</select>' +
  73. (canCreate ? '<button class="add" ' +
  74. 'id="cam-extensionElements-create-' + escapeHTML(id) + '" ' +
  75. 'data-action="createElement">' +
  76. '<span>+</span>' +
  77. '</button>' : '') +
  78. (canRemove ? '<button class="clear" ' +
  79. 'id="cam-extensionElements-remove-' + escapeHTML(id) + '" ' +
  80. 'data-action="removeElement" ' +
  81. 'data-disable="disableRemove">' +
  82. '<span>-</span>' +
  83. '</button>' : '') +
  84. '</div>' +
  85. '</div>',
  86. get: function(element, node) {
  87. var elements = getElements(element, node);
  88. var result = [];
  89. forEach(elements, function(elem) {
  90. result.push({
  91. extensionElementValue: elem.get(modelProperty)
  92. });
  93. });
  94. var selectBox = getSelectBox(node.parentNode, id);
  95. initSelectionSize(selectBox, result.length);
  96. return result;
  97. },
  98. set: function(element, values, node) {
  99. var action = this.__action;
  100. delete this.__action;
  101. businessObject = businessObject || getBusinessObject(element);
  102. var bo =
  103. (reference && businessObject.get(reference))
  104. ? businessObject.get(reference)
  105. : businessObject;
  106. var extensionElements = bo.get('extensionElements');
  107. if (action.id === CREATE_EXTENSION_ELEMENT_ACTION) {
  108. var commands = [];
  109. if (!extensionElements) {
  110. extensionElements = elementHelper.createElement('bpmn:ExtensionElements', { values: [] }, bo, bpmnFactory);
  111. commands.push(cmdHelper.updateBusinessObject(element, bo, { extensionElements: extensionElements }));
  112. }
  113. commands.push(createElement(element, extensionElements, action.value, node));
  114. return commands;
  115. }
  116. else if (action.id === REMOVE_EXTENSION_ELEMENT_ACTION) {
  117. return removeElement(element, extensionElements, action.value, action.idx, node);
  118. }
  119. },
  120. createListEntryTemplate: function(value, index, selectBox) {
  121. initSelectionSize(selectBox, selectBox.options.length + 1);
  122. return createOption(value.extensionElementValue);
  123. },
  124. deselect: function(element, node) {
  125. var selectBox = getSelectBox(node, id);
  126. selectBox.selectedIndex = -1;
  127. },
  128. getSelected: function(element, node) {
  129. return getSelected(node, id);
  130. },
  131. setControlValue: function(element, node, option, property, value, idx) {
  132. node.value = value;
  133. if (!setOptionLabelValue) {
  134. node.text = value;
  135. } else {
  136. setOptionLabelValue(element, node, option, property, value, idx);
  137. }
  138. },
  139. createElement: function(element, node) {
  140. // create option template
  141. var generatedId;
  142. if (idGeneration) {
  143. generatedId = generateElementId(prefix);
  144. }
  145. var selectBox = getSelectBox(node, id);
  146. var template = domify(createOption(generatedId));
  147. // add new empty option as last child element
  148. selectBox.appendChild(template);
  149. // select last child element
  150. selectBox.lastChild.selected = 'selected';
  151. selectionChanged(element, node);
  152. // update select box size
  153. initSelectionSize(selectBox, selectBox.options.length);
  154. this.__action = {
  155. id: CREATE_EXTENSION_ELEMENT_ACTION,
  156. value: generatedId
  157. };
  158. return true;
  159. },
  160. removeElement: function(element, node) {
  161. var selection = getSelected(node, id);
  162. var selectBox = getSelectBox(node, id);
  163. selectBox.removeChild(selectBox.options[selection.idx]);
  164. // update select box size
  165. initSelectionSize(selectBox, selectBox.options.length);
  166. this.__action = {
  167. id: REMOVE_EXTENSION_ELEMENT_ACTION,
  168. value: selection.value,
  169. idx: selection.idx
  170. };
  171. return true;
  172. },
  173. hideElements: function(element, entryNode, node, scopeNode) {
  174. return !hideElements(element, entryNode, node, scopeNode);
  175. },
  176. disableRemove: function(element, entryNode, node, scopeNode) {
  177. return (getSelected(entryNode, id) || {}).idx < 0;
  178. },
  179. selectElement: selectionChanged
  180. };
  181. };