selectunique.js 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. import $ from 'jquery';
  2. import forIn from 'mout/object/forIn';
  3. // import { config } from 'grav-config';
  4. const Data = {};
  5. export default class SelectUniqueField {
  6. constructor(options) {
  7. const body = $('body');
  8. this.items = $();
  9. this.options = Object.assign({}, this.defaults, options);
  10. $('[data-select-observe]').each((index, element) => this.addSelect(element)).last().trigger('change', { load: true });
  11. body.on('mutation._grav', this._onAddedNodes.bind(this));
  12. body.on('mutation_removed._grav', this._onRemovedNodes.bind(this));
  13. }
  14. _onAddedNodes(event, target, record, instance) {
  15. let fields = $(target).find('[data-select-observe]');
  16. if (!fields.length) { return; }
  17. fields.each((index, field) => {
  18. field = $(field);
  19. if (!~this.items.index(field)) {
  20. this.addSelect(field);
  21. }
  22. });
  23. }
  24. _onRemovedNodes(event, data/* , instance */) {
  25. const target = $(data.target);
  26. const holder = target.data('collectionHolder');
  27. if (!holder) { return false; }
  28. const node = $(data.mutation.removedNodes);
  29. const value = node.find('[data-select-observe]').val();
  30. if (value) {
  31. Data[holder].state[value] = value;
  32. }
  33. target.find('[data-select-observe]').each((index, field) => {
  34. field = $(field);
  35. if (field.val() !== value) {
  36. this.updateOptions(field);
  37. }
  38. });
  39. }
  40. addSelect(element) {
  41. this.items = this.items.add(element);
  42. element = $(element);
  43. const value = element.attr('value');
  44. const holder = element.closest('[data-collection-holder]').data('collectionHolder');
  45. const options = element.closest('[data-select-unique]').data('selectUnique');
  46. if (!Data[holder]) {
  47. let data = {};
  48. if (Array.isArray(options)) {
  49. options.slice(0).map((item) => { data[item] = item; });
  50. } else {
  51. data = Object.assign({}, options);
  52. }
  53. Data[holder] = { original: null, state: null };
  54. Data[holder].original = Object.assign({}, data);
  55. Data[holder].state = Object.assign({}, data);
  56. }
  57. this.updateOptions(element);
  58. element.data('originalValue', value);
  59. element.on('change', (event, extras) => {
  60. const target = $(event.currentTarget);
  61. if (target.data('dummyChange')) {
  62. target.data('dummyChange', false);
  63. return false;
  64. }
  65. this.refreshOptions(target, extras && extras.load ? null : element.data('originalValue'));
  66. element.data('originalValue', target.val());
  67. });
  68. }
  69. updateOptions(element) {
  70. element = $(element);
  71. const value = element.attr('value');
  72. const holder = element.closest('[data-collection-holder]').data('collectionHolder');
  73. forIn(Data[holder].state, (v, k) => {
  74. const selected = k === value ? 'selected="selected"' : '';
  75. if (element.get(0).selectize) {
  76. const selectize = element.data('selectize');
  77. selectize.removeOption(k);
  78. selectize.addOption({ value: k, text: v });
  79. } else {
  80. element.append(`<option value="${k}" ${selected}>${v}</option>`);
  81. }
  82. if (selected) {
  83. if (element.get(0).selectize) {
  84. const selectize = element.data('selectize');
  85. selectize.setValue(k);
  86. }
  87. delete Data[holder].state[value];
  88. }
  89. });
  90. }
  91. refreshOptions(element, originalValue) {
  92. const value = element.val();
  93. const holder = element.closest('[data-collection-holder]').data('collectionHolder');
  94. delete Data[holder].state[value];
  95. if (originalValue && Data[holder].original[originalValue]) {
  96. Data[holder].state[originalValue] = Data[holder].original[originalValue];
  97. }
  98. this.items.each((index, select) => {
  99. select = $(select);
  100. if (select[0] === element[0]) { return; }
  101. const selectedValue = select.val();
  102. select.data('dummyChange', true);
  103. if (select.get(0).selectize) {
  104. const selectize = select.data('selectize');
  105. if (selectize) {
  106. selectize.clearOptions();
  107. if (selectedValue) {
  108. selectize.addOption({
  109. value: selectedValue,
  110. text: Data[holder].original[selectedValue] || selectedValue
  111. });
  112. }
  113. forIn(Data[holder].state, (v, k) => {
  114. selectize.addOption({ value: k, text: v });
  115. });
  116. selectize.setValue(selectedValue, true);
  117. }
  118. } else {
  119. select.empty();
  120. forIn(Data[holder].state, (v, k) => {
  121. const selected = k === selectedValue ? 'selected="selected"' : '';
  122. select.append(`<option value="${k}" ${selected}>${v}</option>`);
  123. });
  124. }
  125. select.data('dummyChange', false);
  126. });
  127. }
  128. }
  129. export let Instance = new SelectUniqueField();