quasar
quasar copied to clipboard
QSelect with Basic Filtering example does not reset input when clicking in no-option slot and then losing focus
What happened?
Using the "Basic Filtering" example from the docs (https://quasar.dev/vue-components/select#filtering-and-autocomplete), when I filter for a value that isn't in the list it shows the no-option slot (i.e. "No results") . If I click the "No results" and then click outside the element, the input keeps the invalid value.
What did you expect to happen?
The input should restore to the previously selected item, or blank.
Reproduction URL
https://quasar.dev/vue-components/select#filtering-and-autocomplete
How to reproduce?
- Click in the QSelect input
- Type "abc"
- Click "No results"
- Click outside of the QSelect component
Flavour
Vite Plugin (@quasar/vite-plugin)
Areas
Components (quasar)
Platforms/Browsers
Chrome
Quasar info output
No response
Relevant log output
No response
Additional context
No response
Hi @vincemammoliti! 👋
It looks like you provided an invalid or unsupported reproduction URL. Do not use any service other than Codepen, jsFiddle, StackBlitz, Codesandbox, and GitHub. Make sure the URL you provided is correct and reachable. You can test it by visiting it in a private tab, another device, etc. Please edit your original post above and provide a valid reproduction URL as explained.
Without a proper reproduction, your issue will have to get closed.
Thank you for your collaboration. 👏
It was not supposed to do that. There is nowhere any mention that it works like that.
It was not supposed to do that. There is nowhere any mention that it works like that.
My expectation of what should happen is what the component already does when, for example, you tab out of the select input, or you click outside of the select input.
To clarify, the issue is only when you first click on the "No results" (no-option slot) and then click outside of the select input.
Here is a recording of how the QSelect component works correctly when you have an invalid filter string and then click outside the component. Notice how the "abc" string in the input is cleared/reset.
Here is a recording of how the Qselect component has an issue when you have an invalid filter string and first click on "No results" and then click outside the component. Notice how the "abc" string in the input is not cleared.
Please review again and it would be appreciated if you could re-open the issue. Thanks
The content of the slot is not designed as an option. It does nothing on click by default
I understand that, but I think you're missing my point. I'm not expecting that clicking "No results" would clear my input. I'm expecting that when I lose focus on the input, if the filter string is invalid, then the input should be cleared.
As I demonstrated above, QSelect already clears the input when you tab out of the component or when you click outside of the component. So the expectation is it should also work that same way whichever way you make the component lose focus. But, the bug is if you first click in "No results" and then click outside the component, the input value does not get cleared/reset.
Please try to reproduce and I'm sure you will understand.
From a user's perspective, if the input is not cleared/reset when they input an invalid option/filter string, then it appears as if the value they entered is valid and will be saved with the form submission, when in fact the underlying model-value is actually not "abc" in this case.
Side note; I've made a work around for now by resetting the input value onPopupHide event if there are no filtered options.
Ah, now I understand. Sorry for missing the problem.
This is a duplicate of https://github.com/quasarframework/quasar/issues/16135 right?
Good catch :D
Has anyone solved the problem yet?
Has anyone solved the problem yet?
It's a work around, but what I landed on is to:
clearInputWhenInvalidwhen theblurevent is emitted from the QSelect component.clearModelWhenEmptywhen theinput-valueevent is emitted from the QSelect component.
Extending upon the "Basic Filtering" example from the docs (https://quasar.dev/vue-components/select#example--basic-filtering), this is what my solution would look like:
<template>
<div class="q-pa-md">
<div class="q-gutter-md row">
<q-select
ref="select"
filled
v-model="model"
use-input
hide-selected
fill-input
input-debounce="0"
:options="options"
@filter="filterFn"
hint="Basic filtering"
style="width: 250px; padding-bottom: 32px"
@blur="clearInputWhenInvalid"
@input-value="clearModelWhenEmpty"
>
<template v-slot:no-option>
<q-item>
<q-item-section class="text-grey">
No results
</q-item-section>
</q-item>
</template>
</q-select>
</div>
</div>
</template>
<script setup>
import { ref, computed } from 'vue'
const stringOptions = [
'Google', 'Facebook', 'Twitter', 'Apple', 'Oracle'
]
const options = ref(stringOptions)
const model = ref(null)
function filterFn(val, update, abort) {
update(() => {
const needle = val.toLowerCase()
options.value = stringOptions.filter(v => v.toLowerCase().indexOf(needle) > -1)
})
}
// Extending beyond the "Basic Filtering" example from the docs starts below...
const select = ref(null)
const inputElement = computed(() => {
return select.value.$el.getElementsByTagName('input')[0]
})
function clearInputWhenInvalid() {
if (!options.value.includes(inputElement.value.value)) {
select.value.updateInputValue('', true)
}
}
function clearModelWhenEmpty(value) {
if (value === null || value === undefined || value.trim() === '') {
model.value = null
}
}
</script>