comboLookup.js 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. function comboOpenFormById(formId) {
  2. var form = qi(formId);
  3. form && comboOpenForm(form);
  4. }
  5. function comboCloseFormById(formId) {
  6. var form = qi(formId);
  7. form && comboCloseForm(form);
  8. }
  9. function comboOpenForm(container) {
  10. var dropdown = container.parentNode.querySelector('.dropdown');
  11. container.scrollTop = 0;
  12. container.parentNode.classList.add('dropdown-open');
  13. dropdown.classList.add('dropdown-open');
  14. activeForm = container.id;
  15. };
  16. function comboCloseForm(container) {
  17. container.parentNode.classList.remove('dropdown-open');
  18. //container.previousSibling.classList.remove('dropdown-open');
  19. activeForm = undefined;
  20. };
  21. function comboLookupTextApply(dom) {
  22. let elem = qi(dom);
  23. if (elem) {
  24. let textareaSplit = dom.split('_');
  25. textareaSplit.pop();
  26. const textarea = qi(textareaSplit.join('_'));
  27. textarea ? textarea.value = elem.value : null;
  28. }
  29. }
  30. function comboClear(dom) {
  31. let elem = qi('comboContainer_' + dom)
  32. var dropdown = qi(dom).closest('.dropdown');
  33. if (elem) { elem.style.display = 'none' }
  34. dropdown.classList.remove('dropdown-open');
  35. dropdown.classList.remove('is-reversed');
  36. activeCombo = undefined; currentItem = undefined;
  37. }
  38. function comboSelect(uid, dom, row, feed, mod, id) {
  39. let elem = qi(dom);
  40. comboClear(dom);
  41. if (qi(id)) elem.setAttribute("data-bind", qi(id).getAttribute('data-bind'));
  42. elem.value = row;
  43. elem.style.backgroundColor = 'white';
  44. var dropdown = qi(dom).closest('.dropdown');
  45. dropdown.classList.remove('dropdown-open');
  46. dropdown.classList.remove('is-reversed');
  47. dropdown.classList.add('dropdown-bind');
  48. let value = qi(id) ? dec(unbase64(qi(id).getAttribute('data-bind'))) : string(row);
  49. const modifyItem = qi(elem.getAttribute('nested'));
  50. if (modifyItem) {
  51. const list = modifyItem.parentNode;
  52. direct(tuple(atom('comboModify'),
  53. string(list.id),
  54. string(modifyItem.id),
  55. string(modifyItem.firstChild.innerHTML),
  56. dec(unbase64(modifyItem.getAttribute('data-bind'))),
  57. value,
  58. dec(unbase64(list.getAttribute('data-delegate'))),
  59. dec(unbase64(list.getAttribute('data-pos'))),
  60. dec(unbase64(list.getAttribute('data-feed')))));
  61. } else {
  62. direct(tuple(atom('comboSelect'), bin(uid), value, string(dom), string(feed), atom(mod)));
  63. }
  64. comboLookupTextApply(dom);
  65. }
  66. function comboLookupChange(dom) {
  67. let elem = qi(dom);
  68. if (elem) {
  69. elem.removeAttribute("data-bind");
  70. const dropdown = qi(dom).closest('.dropdown');
  71. if (dropdown) { dropdown.classList.remove('dropdown-bind'); }
  72. comboLookupTextApply(dom);
  73. }
  74. }
  75. function comboLookupClick(uid, dom, feed, mod) {
  76. var dropdown = qi(dom).closest('.dropdown');
  77. var char = event.which || event.keyCode;
  78. if (char == 1 && !activeCombo && (qi(dom).value == '' || qi(dom).getAttribute('nested'))) {
  79. activeCombo = dom;
  80. currentItem = undefined;
  81. dropdown.classList.add('dropdown-open');
  82. if (window.innerHeight - dropdown.getBoundingClientRect().bottom < 100)
  83. dropdown.classList.add('is-reversed');
  84. direct(tuple(atom('comboKey'),
  85. bin(uid),
  86. bin('all'),
  87. string(dom),
  88. string(feed),
  89. atom(mod)));
  90. return
  91. } else if (char == 1 && activeCombo == dom) { comboClear(dom); }
  92. }
  93. function comboLookupKeydown(uid, dom, feed, mod) {
  94. var dropdown = qi(dom).closest('.dropdown');
  95. var char = event.which || event.keyCode;
  96. if (char == 40 && !activeCombo && qi(dom).value == '') {
  97. activeCombo = dom;
  98. currentItem = undefined;
  99. dropdown.classList.add('dropdown-open');
  100. if (window.innerHeight - dropdown.getBoundingClientRect().bottom < 100)
  101. dropdown.classList.add('is-reversed');
  102. direct(tuple(atom('comboKey'),
  103. bin(uid),
  104. bin('all'),
  105. string(dom),
  106. string(feed),
  107. atom(mod)));
  108. return
  109. }
  110. if (activeCombo && [35, 36, 38, 40].includes(char)) {
  111. event.preventDefault();
  112. if (char == 40) { set_focus( currentItem && ( !cycleEnabled || currentItem.nextSibling)
  113. ? currentItem.nextSibling : qi('comboContainer_' + dom).firstChild, true) }
  114. if (char == 35) { set_focus( currentItem && ( !cycleEnabled || currentItem.nextSibling)
  115. ? currentItem.parentNode.lastChild : currentItem, true) }
  116. if (char == 38) { set_focus( currentItem && ( !cycleEnabled || currentItem.previousSibling)
  117. ? currentItem.previousSibling : qi('comboContainer_' + dom).lastChild, true) }
  118. if (char == 36) { set_focus( currentItem && ( !cycleEnabled || currentItem.previousSibling)
  119. ? currentItem.parentNode.firstChild : currentItem, true) }
  120. }
  121. if (char == 13) { event.preventDefault(); return }
  122. }
  123. function comboLookupKeyup(uid, dom, feed, mod) {
  124. var dropdown = qi(dom).closest('.dropdown')
  125. var char = event.which || event.keyCode;
  126. if (char == 27 || (char == 8 || char == 46) && qi(dom).value == '') { clearInput(dom); return }
  127. if (char == 13 && currentItem) { currentItem.click(); return }
  128. if ([33, 34, 37, 39].includes(char)) { return }
  129. if (activeCombo && [35, 36, 38, 40].includes(char)) { return }
  130. else {
  131. activeCombo = dom;
  132. currentItem = undefined;
  133. dropdown.classList.add('dropdown-open');
  134. if (window.innerHeight - dropdown.getBoundingClientRect().bottom < 100)
  135. dropdown.classList.add('is-reversed');
  136. direct(tuple(atom('comboKey'),
  137. bin(uid),
  138. bin(qi(dom).value),
  139. string(dom),
  140. string(feed),
  141. atom(mod)));
  142. }
  143. }
  144. function comboLookupMouseMove(dom) {
  145. set_focus(event.target.closest('.dropdown-item'), false)
  146. }
  147. function set_focus(elem, scroll) {
  148. if (elem) {
  149. if(currentItem) {currentItem.className = "dropdown-item"}
  150. elem.className = "dropdown-item focus"
  151. if (scroll==true) {elem.scrollIntoView({block: "nearest", inline: "nearest"})}
  152. currentItem = elem
  153. }
  154. }
  155. function clearInput(dom) {
  156. const input = qi(dom);
  157. if (input) {
  158. input.value = '';
  159. input.removeAttribute('value');
  160. }
  161. comboLookupChange(dom);
  162. comboClear(dom);
  163. }
  164. function comboLookupModifyAdd(listId, inputId) {
  165. const input = qi(inputId);
  166. const list = qi(listId);
  167. if (list && input && input.value != '') {
  168. const data = querySourceRaw(inputId);
  169. if (data && data.hasOwnProperty('text') && data.hasOwnProperty('bind')) {
  170. const bind = data.bind;
  171. const value = data.text;
  172. if (bind !== '' && bind !== 'null') {
  173. clearInput(inputId);
  174. direct(tuple(atom('comboAdd'),
  175. string(listId),
  176. string(value),
  177. dec(unbase64(bind)),
  178. dec(unbase64(list.getAttribute('data-delegate'))),
  179. dec(unbase64(list.getAttribute('data-pos'))),
  180. dec(unbase64(list.getAttribute('data-feed'))),
  181. dec(unbase64(list.getAttribute('data-default')))));
  182. }
  183. }
  184. }
  185. }
  186. function comboLookupModifyValues(listId) {
  187. const list = qi(listId);
  188. if (list) {
  189. return Array.from(list.children).map(function (el) {
  190. return {'text': el.firstChild.innerHTML, 'bind': el.getAttribute('data-bind')}
  191. })
  192. } else {
  193. return []
  194. }
  195. }
  196. document.addEventListener("click", () => {
  197. if (activeCombo && event.target.className != 'triangle' &&
  198. !event.target.closest('#comboContainer_' + activeCombo)) {
  199. qi(activeCombo).value = '';
  200. comboClear(activeCombo);
  201. } else if (activeForm && event.target.className != 'triangle' &&
  202. !event.target.closest("#" + activeForm)) {
  203. comboCloseFormById(activeForm);
  204. }
  205. })
  206. function comboLostFocus(e) { }
  207. function comboOnFocus(e) { }
  208. function comboLookupMouseOut(dom) { }
  209. var activeCombo = undefined
  210. var activeForm = undefined
  211. var currentItem = undefined
  212. var cycleEnabled = false