picker.js 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. import DropdownIcon from '../assets/icons/dropdown.svg';
  2. class Picker {
  3. constructor(select) {
  4. this.select = select;
  5. this.container = document.createElement('span');
  6. this.buildPicker();
  7. this.select.style.display = 'none';
  8. this.select.parentNode.insertBefore(this.container, this.select);
  9. this.label.addEventListener('click', (event) => {
  10. this.container.classList.toggle('ql-expanded');
  11. });
  12. this.select.addEventListener('change', this.update.bind(this));
  13. }
  14. buildItem(option) {
  15. let item = document.createElement('span');
  16. item.classList.add('ql-picker-item');
  17. if (option.hasAttribute('value')) {
  18. item.setAttribute('data-value', option.getAttribute('value'));
  19. }
  20. if (option.textContent) {
  21. item.setAttribute('data-label', option.textContent);
  22. }
  23. item.addEventListener('click', (event) => {
  24. this.selectItem(item, true);
  25. });
  26. return item;
  27. }
  28. buildLabel() {
  29. let label = document.createElement('span');
  30. label.classList.add('ql-picker-label');
  31. label.innerHTML = DropdownIcon;
  32. this.container.appendChild(label);
  33. return label;
  34. }
  35. buildOptions() {
  36. let options = document.createElement('span');
  37. options.classList.add('ql-picker-options');
  38. [].slice.call(this.select.options).forEach((option) => {
  39. let item = this.buildItem(option);
  40. options.appendChild(item);
  41. if (option.hasAttribute('selected')) {
  42. this.selectItem(item);
  43. }
  44. });
  45. this.container.appendChild(options);
  46. }
  47. buildPicker() {
  48. [].slice.call(this.select.attributes).forEach((item) => {
  49. this.container.setAttribute(item.name, item.value);
  50. });
  51. this.container.classList.add('ql-picker');
  52. this.label = this.buildLabel();
  53. this.buildOptions();
  54. }
  55. close() {
  56. this.container.classList.remove('ql-expanded');
  57. }
  58. selectItem(item, trigger = false) {
  59. let selected = this.container.querySelector('.ql-selected');
  60. if (item === selected) return;
  61. if (selected != null) {
  62. selected.classList.remove('ql-selected');
  63. }
  64. if (item != null) {
  65. item.classList.add('ql-selected');
  66. this.select.selectedIndex = [].indexOf.call(item.parentNode.children, item);
  67. if (item.hasAttribute('data-value')) {
  68. this.label.setAttribute('data-value', item.getAttribute('data-value'));
  69. } else {
  70. this.label.removeAttribute('data-value');
  71. }
  72. if (item.hasAttribute('data-label')) {
  73. this.label.setAttribute('data-label', item.getAttribute('data-label'));
  74. } else {
  75. this.label.removeAttribute('data-label');
  76. }
  77. if (trigger) {
  78. if (typeof Event === 'function') {
  79. this.select.dispatchEvent(new Event('change'));
  80. } else if (typeof Event === 'object') { // IE11
  81. let event = document.createEvent('Event');
  82. event.initEvent('change', true, true);
  83. this.select.dispatchEvent(event);
  84. }
  85. this.close();
  86. }
  87. } else {
  88. this.label.removeAttribute('data-value');
  89. this.label.removeAttribute('data-label');
  90. }
  91. }
  92. update() {
  93. let option;
  94. if (this.select.selectedIndex > -1) {
  95. let item = this.container.querySelector('.ql-picker-options').children[this.select.selectedIndex];
  96. option = this.select.options[this.select.selectedIndex];
  97. this.selectItem(item);
  98. } else {
  99. this.selectItem(null);
  100. }
  101. let isActive = option != null && option !== this.select.querySelector('option[selected]');
  102. this.label.classList.toggle('ql-active', isActive);
  103. }
  104. }
  105. export default Picker;