Make the search feature act as soon as the user starts typing - Closes #441

This commit is contained in:
Bubka 2025-02-25 15:45:15 +01:00
parent 11db01e889
commit 530b1a5cf6

View File

@ -1,6 +1,6 @@
<script setup> <script setup>
const keyword = defineModel('keyword')
const props = defineProps({ const props = defineProps({
keyword: String,
hasNoBackground: { hasNoBackground: {
type: Boolean, type: Boolean,
default: false default: false
@ -10,28 +10,56 @@
const searchInput = ref(null) const searchInput = ref(null)
onMounted(() => { onMounted(() => {
document.addEventListener('keydown', keyListener) document.addEventListener('keydown', ctrlFHandler)
document.addEventListener('keypress', anyPrintableKeyHandler)
}) })
onUnmounted(() => { onUnmounted(() => {
document.removeEventListener('keydown', keyListener) document.removeEventListener('keydown', ctrlFHandler)
document.removeEventListener('keypress', anyPrintableKeyHandler)
}) })
/** /**
* Attach an event listen for ctrl+F * Attach an event listen for ctrl+F
*/ */
function keyListener(e) { function ctrlFHandler(e) {
if (e.key === "f" && (e.ctrlKey || e.metaKey)) { if (e.key === "f" && (e.ctrlKey || e.metaKey)) {
e.preventDefault(); e.preventDefault()
searchInput.value?.focus() searchInput.value?.focus()
} }
} }
/**
* Clear the search field
*/
function clearSearch() {
keyword.value = ''
}
/**
* Attach an event listen for any key press to automatically focus on search
* without having to ctrl+F
*/
function anyPrintableKeyHandler(e) {
if (e.key === 'Enter') {
return
}
keyword.value = e.key
searchInput.value?.setSelectionRange(1, 1)
searchInput.value?.focus()
e.preventDefault()
}
</script> </script>
<template> <template>
<div role="search" class="field"> <div role="search" class="field">
<div class="control has-icons-right"> <div class="control has-icons-right">
<input <input
v-model="keyword"
@keyup.esc.prevent="(event) => { clearSearch(); event.target.blur() }"
@keyup.enter.prevent="(event) => event.target.blur()"
@keypress.stop
ref="searchInput" ref="searchInput"
id="txtSearch" id="txtSearch"
type="search" type="search"
@ -40,11 +68,9 @@
:title="$t('commons.search')" :title="$t('commons.search')"
:placeholder="placeholder" :placeholder="placeholder"
class="input is-rounded is-search" class="input is-rounded is-search"
:class="{ 'has-no-background': hasNoBackground }" :class="{ 'has-no-background': hasNoBackground }">
:value="keyword"
v-on:keyup="$emit('update:keyword', $event.target.value)">
<span class="icon is-small is-right"> <span class="icon is-small is-right">
<button type="button" v-if="keyword != ''" id="btnClearSearch" tabindex="1" :title="$t('commons.clear_search')" class="clear-selection delete" @click="$emit('update:keyword','')"></button> <button type="button" v-if="keyword != ''" id="btnClearSearch" tabindex="1" :title="$t('commons.clear_search')" class="clear-selection delete" @click="clearSearch"></button>
<FontAwesomeIcon v-else :icon="['fas', 'search']" /> <FontAwesomeIcon v-else :icon="['fas', 'search']" />
</span> </span>
</div> </div>