diff --git a/autocomplete/static/autocomplete/css/autocomplete.css b/autocomplete/static/autocomplete/css/autocomplete.css index 9ccb2af..5398494 100644 --- a/autocomplete/static/autocomplete/css/autocomplete.css +++ b/autocomplete/static/autocomplete/css/autocomplete.css @@ -9,7 +9,7 @@ .phac_aspc_form_autocomplete { display: block; width: 100%; - padding: .375rem 2.25rem 0.375rem 0.75rem; + padding: calc(.375rem - 2px) 2.25rem calc(0.375rem - 2px) 0.75rem; -moz-padding-start: calc(0.75rem - 3px); font-weight: 400; line-height: 1.5; @@ -23,6 +23,7 @@ border-radius: .375rem; transition: border-color .15s ease-in-out,box-shadow .15s ease-in-out; appearance: none; + min-height: 38px; } .phac_aspc_form_autocomplete.disabled { @@ -45,7 +46,7 @@ position: relative; overflow: hidden; margin: 0; - padding: 0 5px; + padding: 0; width: 100%; height: auto; cursor: text; @@ -71,7 +72,7 @@ background-clip: padding-box; box-shadow: 0 0 2px #fff inset, 0 1px 0 rgb(0 0 0 / 5%); color: #333; - line-height: 13px; + line-height: 14px; cursor: default; } @@ -112,9 +113,12 @@ .phac_aspc_form_autocomplete ul.ac_container li.input { margin: 0; padding: 0; + min-width: 10px; white-space: nowrap; flex: 1; display: flex; + flex-wrap: nowrap; + line-height: 14px; } .phac_aspc_form_autocomplete ul.ac_container li input.textinput { @@ -130,6 +134,7 @@ line-height: normal; border-radius: 0; flex: 1; + max-width: 100%; } .phac_aspc_form_autocomplete .ac_required_input { @@ -251,3 +256,7 @@ display: list-item; color: #ccc; } + +.phac_aspc_form_autocomplete li.input.ac-active { + min-width: 50px !important; +} diff --git a/autocomplete/static/autocomplete/js/autocomplete.js b/autocomplete/static/autocomplete/js/autocomplete.js index adc7257..c4a18c6 100644 --- a/autocomplete/static/autocomplete/js/autocomplete.js +++ b/autocomplete/static/autocomplete/js/autocomplete.js @@ -5,6 +5,7 @@ function phac_aspc_autocomplete_blur_handler(event, name, sync=false, item=false requestAnimationFrame(function () { const parent = document.getElementById(`${name}__container`); if (!parent.contains(document.activeElement)) { + // We are now outside the component const el = document.getElementById(name + '__textinput'); const data_el = document.getElementById(name + '__data'); if (!sync) { @@ -15,12 +16,24 @@ function phac_aspc_autocomplete_blur_handler(event, name, sync=false, item=false // Reset focus back to textbox if a search result item triggered the blur if (item) el.focus(); document.getElementById(name + '__items').classList.remove('show'); + // Change the min-width of the text input back to the (small) default + parent.querySelector('.textinput') + .parentElement.classList.remove('ac-active'); } }); } const phac_aspc_autocomplete_keydown_debounce = {}; function phac_aspc_autocomplete_keydown_handler(event) { + if (event.target.classList.contains('textinput') && event.keyCode > 47) { + // Expands the min-width of text input to a reasonable size when typing + event.target.parentElement.classList.add('ac-active'); + } else if (event.target.classList.contains('textinput') && event.keyCode === 8 + && event.target.value.length === 1) { + // Shrinks the min-width of text input back to the (small) default if + // the text input is empty due to backspacing + event.target.parentElement.classList.remove('ac-active'); + } // Handler responsible for keyboard navigation (up, down, esc and backspace) const debounce = phac_aspc_autocomplete_keydown_debounce; const whereTo = (element, down=true, skip_element=true, count=1) => { @@ -159,4 +172,4 @@ function phac_aspc_autocomplete_keydown_handler(event) { return false; } return true; -} \ No newline at end of file +} diff --git a/autocomplete/templates/autocomplete/textinput.html b/autocomplete/templates/autocomplete/textinput.html index 0c9fd72..e02ad1f 100644 --- a/autocomplete/templates/autocomplete/textinput.html +++ b/autocomplete/templates/autocomplete/textinput.html @@ -7,7 +7,7 @@ onkeydown="return phac_aspc_autocomplete_keydown_handler(event)" onblur="return phac_aspc_autocomplete_blur_handler(event, '{{ route_name|escapejs }}', {{ multiselect|yesno:'false,true' }})" hx-get="{% url route_name method='items' %}" - hx-trigger="click,input delay:250ms" + hx-trigger="focus,click,input delay:250ms" hx-include="#{{ route_name }}" hx-target="#{{ route_name }}__items" hx-vals="js:{search: document.getElementById('{{ route_name|escapejs }}__textinput').value}"