Licitator 1.0
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

225 lines
6.7 KiB

5 years ago
  1. /**
  2. * Class that handles the Group
  3. * @param {Definitions} fieldDefinitions
  4. * @param {boolean} canBeRemoved
  5. * @param {Object} ruleData
  6. * @param {callable} changeCallback
  7. * @constructor
  8. */
  9. var Group = function (fieldDefinitions, ruleData, canBeRemoved) {
  10. this.fieldDefinitions = fieldDefinitions;
  11. this.canBeRemoved = (typeof canBeRemoved === 'undefined' ? true : canBeRemoved);
  12. this.ruleData = ruleData;
  13. this.id = guid();
  14. this.type = jQuery.isEmptyObject(ruleData) ? Group.TYPE_ALL : ruleData.logic_operator;
  15. this.title = jQuery.isEmptyObject(ruleData) ? '' : ruleData.title;
  16. this.wrapper = $("<div>").attr('id', this.id).addClass(this.type).addClass('conditional');
  17. this.items = {};
  18. this.processRuleData();
  19. };
  20. // Group "constants"
  21. Group.TYPE_ALL = 'all';
  22. Group.TYPE_ANY = 'any';
  23. Group.TYPE_NONE = 'none';
  24. Group.ITEM_GROUP = 'group';
  25. Group.ITEM_CONDITION = 'cond';
  26. /**
  27. *
  28. * @param {function} callback
  29. */
  30. Group.prototype.setRemoveCallback = function (callback) {
  31. this.removeCallback = callback;
  32. };
  33. /**
  34. *
  35. * @param {function} callback
  36. */
  37. Group.prototype.setChangeCallback = function (callback) {
  38. this.changeCallback = callback;
  39. for (var itemId in this.items) {
  40. this.items[itemId].setChangeCallback(callback);
  41. }
  42. };
  43. /**
  44. * Returns the html that contains group definition
  45. * @returns {null|*|jQuery}
  46. */
  47. Group.prototype.appendHtml = function (parentWrapper) {
  48. parentWrapper.append(this.wrapper);
  49. if (this.canBeRemoved) {
  50. this.wrapper.append(this.getRemoveGroupElement());
  51. }
  52. this.wrapper.append(this.getGroupTypeSelect());
  53. this.wrapper.append(this.getAddConditionButton());
  54. this.wrapper.append(this.getAddGroupButton());
  55. this.wrapper.append(this.getEditableTitle());
  56. for (var itemId in this.items) {
  57. this.items[itemId].appendHtml(this.wrapper);
  58. }
  59. };
  60. /**
  61. * Initialized existing group from serialized data
  62. */
  63. Group.prototype.processRuleData = function () {
  64. if (!$.isEmptyObject(this.ruleData)) {
  65. this.ruleData.items.forEach(function (item) {
  66. switch (item.item_type) {
  67. case Group.ITEM_GROUP:
  68. this.addItem(new Group(this.fieldDefinitions, item.data, true), false);
  69. break;
  70. case Group.ITEM_CONDITION:
  71. this.addItem(new Condition(this.fieldDefinitions, item.data), false);
  72. break;
  73. }
  74. }.bind(this));
  75. }
  76. };
  77. /**
  78. * Returns JQuery object that represents the select object for group type
  79. * @returns {*|jQuery|HTMLElement}
  80. */
  81. Group.prototype.getGroupTypeSelect = function () {
  82. var selectWrapper = $("<div>", {"class": "all-any-none-wrapper"});
  83. var select = $("<select>", {"class": "all-any-none " + this.type, 'data-sonata-select2': false});
  84. select.append($("<option>", {"value": Group.TYPE_ALL, "text": "All", "selected": this.type === Group.TYPE_ALL}));
  85. select.append($("<option>", {"value": Group.TYPE_ANY, "text": "Any", "selected": this.type === Group.TYPE_ANY}));
  86. select.append($("<option>", {"value": Group.TYPE_NONE, "text": "None", "selected": this.type === Group.TYPE_NONE}));
  87. select.on('change', function (e) {
  88. this.wrapper.removeClass(this.type);
  89. this.type = $(e.target).val();
  90. this.wrapper.addClass(this.type);
  91. }.bind(this));
  92. selectWrapper.append(select);
  93. return selectWrapper;
  94. };
  95. /**
  96. * Returns JQuery object that represents the add condition button
  97. * @returns {*|jQuery|HTMLElement}
  98. */
  99. Group.prototype.getAddConditionButton = function () {
  100. var btn = $("<a>", {href: 'javascript://', class: 'add-condition', text: 'Add Condition'});
  101. btn.append("<i class='glyphicon glyphicon-plus'></i>");
  102. btn.on('click', function (e) {
  103. this.addItem(new Condition(this.fieldDefinitions, {}), true);
  104. }.bind(this));
  105. return btn;
  106. };
  107. /**
  108. * Returns the JQuery object that represents the add group button
  109. * @returns {*|jQuery|HTMLElement}
  110. */
  111. Group.prototype.getAddGroupButton = function () {
  112. var btn = $("<a>", {href: 'javascript://', class: 'add-condition-group', text: 'Add Group'});
  113. btn.append("<i class='glyphicon glyphicon-th-list'></i>")
  114. btn.on('click', function (e) {
  115. this.addItem(new Group(this.fieldDefinitions, {}, true), true);
  116. }.bind(this));
  117. return btn;
  118. };
  119. /**
  120. * Returns a Jquery object that represents the remove group button
  121. * @returns {*|jQuery}
  122. */
  123. Group.prototype.getRemoveGroupElement = function () {
  124. var removeEl = $('<a>', {
  125. class: 'remove-group-button remove',
  126. href: 'javascript://'
  127. }).data('id', this.id);
  128. removeEl.append("<i class='glyphicon glyphicon-remove'></i>");
  129. removeEl.on('click', function (e) {
  130. this.remove();
  131. if (typeof this.removeCallback === 'function') {
  132. this.removeCallback(this.id);
  133. }
  134. }.bind(this));
  135. return removeEl;
  136. };
  137. /**
  138. * @returns {jQuery}
  139. */
  140. Group.prototype.getEditableTitle = function () {
  141. var input = $('<input/>', {type: 'text', class: 'group-title-edit', value: this.title, placeholder: 'Group title'});
  142. input.change(function (e) {
  143. this.title = e.target.value;
  144. }.bind(this));
  145. return input;
  146. };
  147. /**
  148. * @param {Group|Condition} item
  149. * @param {boolean} render
  150. */
  151. Group.prototype.addItem = function (item, render) {
  152. var itemId = item.getId();
  153. this.items[itemId] = item;
  154. item.setRemoveCallback(function () {
  155. delete this.items[itemId];
  156. if (typeof this.changeCallback === 'function') {
  157. this.changeCallback(this.id);
  158. }
  159. }.bind(this));
  160. if (render) {
  161. item.appendHtml(this.wrapper);
  162. }
  163. };
  164. /**
  165. * Removes this group and his associated groups and conditions
  166. */
  167. Group.prototype.remove = function () {
  168. for (var id in this.items) {
  169. this.items[id].remove();
  170. }
  171. this.wrapper.remove();
  172. };
  173. /**
  174. * Returns the group id
  175. * @returns {null|string|*}
  176. */
  177. Group.prototype.getId = function () {
  178. return this.id;
  179. };
  180. /**
  181. * Serialized the current group
  182. * @returns {{}}
  183. */
  184. Group.prototype.serialize = function () {
  185. if ($.isEmptyObject(this.items)) {
  186. return {};
  187. }
  188. var serialized = {
  189. logic_operator: this.type,
  190. title: this.title,
  191. items: []
  192. };
  193. for (var id in this.items) {
  194. var itemData = this.items[id].serialize();
  195. if (!$.isEmptyObject(itemData)) {
  196. var itemType;
  197. switch (true) {
  198. case this.items[id] instanceof Group:
  199. itemType = Group.ITEM_GROUP;
  200. break;
  201. case this.items[id] instanceof Condition:
  202. itemType = Group.ITEM_CONDITION;
  203. break;
  204. }
  205. serialized.items.push({item_type: itemType, data: itemData});
  206. }
  207. }
  208. return serialized;
  209. };