From 1f477b7d4a9f1e701c36a7a21d374b29821f4e54 Mon Sep 17 00:00:00 2001 From: Andrea Lepori Date: Thu, 26 May 2022 19:04:51 +0200 Subject: fix dropdown on safari (ios) --- static/utils.js | 107 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 static/utils.js (limited to 'static') diff --git a/static/utils.js b/static/utils.js new file mode 100644 index 0000000..60ffd64 --- /dev/null +++ b/static/utils.js @@ -0,0 +1,107 @@ +document.addEventListener('DOMContentLoaded', () => { + initMaterializeHelper(window.materializeHelper || {}) +}) + +function initMaterializeHelper(customOptions) { + const options = { + debug: true, + selectOptions: true, + selectTriggers: true, + autocompletedInputLabels: true, + ...customOptions + } + + if (options.selectOptions) + fixSelectOptions(options.debug) + fixNavbarDropdown(options.debug) + if (options.selectTriggers) + fixSelectTriggers(options.debug) + if (options.autocompletedInputLabels) + fixAutocompletedInputLabels(options.debug) +} + +/** + * Issue: Select element is misbehaving on iOS. + * When clicking one option, other one is being selected... + */ +function fixSelectOptions(debug) { + setTimeout(() => { // To be called after M.FormSelect.init() + let dragging = false + const opts = { passive: false } + const options = document.querySelectorAll('.select-wrapper ul.select-dropdown li') + + if (options.length && debug) { + console.info('[Materialize Helper] Fixed select options', { options }) + } + + for (const option of options) { + option.addEventListener('touchmove', () => { dragging = true }, opts) + option.addEventListener('touchstart', () => { dragging = false }, opts) + option.addEventListener('touchend', (e) => { + if (dragging) return + else e.stopPropagation() + }, opts) + } + }, 0) +} + +function fixNavbarDropdown(debug) { + setTimeout(() => { // To be called after M.FormSelect.init() + let dragging = false + const opts = { passive: false } + const options = document.querySelectorAll('ul.dropdown-content li') + + if (options.length && debug) { + console.info('[Materialize Helper] Fixed navbar dropdown', { options }) + } + + for (const option of options) { + option.addEventListener('touchmove', () => { dragging = true }, opts) + option.addEventListener('touchstart', () => { dragging = false }, opts) + option.addEventListener('touchend', (e) => { + if (dragging) return + else e.stopPropagation() + }, opts) + } + }, 0) +} + +/** + * Issue: Select triggers are causing Lighthouse warnings. + */ +function fixSelectTriggers(debug) { + setTimeout(() => { // To be called after M.FormSelect.init() + const triggers = document.querySelectorAll('input.select-dropdown.dropdown-trigger') + + for (const trigger of triggers) { + const wrapper = trigger.closest('.select-wrapper') + const select = wrapper.querySelector('select') + const option = select.options[select.selectedIndex] + trigger.placeholder = option.text + } + + if (triggers.length && debug) { + console.info('[Materialize Helper] Fixed select triggers', { triggers }) + } + }, 0) +} + +/** + * Issue: Input label is covering an input when it's autocompleted. + */ +function fixAutocompletedInputLabels(debug) { + document.addEventListener('onautocomplete', function(e) { + const input = e.target + const label = input.parentNode.querySelector(`label[for="${input.id}"]`) + const autocompleted = input.hasAttribute('autocompleted') + + if (autocompleted && label) { + label.classList.add('active') + input.classList.add('valid') + + if (debug) { + console.info('[Materialize Helper] Fixed autocompleted input label', { input, label }) + } + } + }) +} -- cgit v1.2.1