I have a problem with a button that appears when an input have focus. "Cancel" button must be visible when a user interact with a search bar. I've made the job done with addEventListener on input click/focus. But there is a problem, when I click "clear" button my "cancel" button disappears on mobile, cause input loses focus. Is there a way to trigger button's appearing on another event suited for my goal? Or may be there is a method to keep focus on input while pressing the "clear" button. Thanks!
I've tried:
- mousedown events,
- addEventListenerAll on all elements of the from,
- changing click to focus and other..
My html
<form >
<button data-search-cancel-appears
tabindex="0">cancel</button>
<input data-search-cancel-appears type="search">
<button data-search-cancel-appears tabindex="0">clear</button>
<button data-search-cancel-appears
type="submit">search</button>
</form>
my css
/* clears the 'X' from Internet Explorer */
input[type=search]::-ms-clear { display: none; width : 0; height: 0; }
input[type=search]::-ms-reveal { display: none; width : 0; height: 0; }
/* clears the 'X' from Chrome */
input[type="search"]::-webkit-search-decoration,
input[type="search"]::-webkit-search-cancel-button,
input[type="search"]::-webkit-search-results-button,
input[type="search"]::-webkit-search-results-decoration { display: none; }
my JS
const searchCancel = document.querySelector('.search__cancel')
const searchClear = document.querySelector('.search__clear')
const searchInput = document.querySelector('.search__input')
searchCancel.style.display = "none"
searchClear.style.display = "none"
searchClear.addEventListener('click', function (e) {
e.preventDefault()
searchInput.value = ""
searchInput.focus()
searchCancel.style.display = ""
searchClear.style.display = "none"
})
searchCancel.addEventListener('click', function (e) {
e.preventDefault()
searchInput.value = ""
searchCancel.click()
searchCancel.style.display = "none"
searchClear.style.display = "none"
})
searchInput.addEventListener('input', function (e) {
searchCancel.style.display = ""
if (searchInput.value.length > 0) {
searchClear.style.display = ""
} else {
searchClear.style.display = "none"
}
})
searchInput.addEventListener('click', function (e) {
searchCancel.style.display = ""
if (searchInput.value.length > 0) {
searchClear.style.display = ""
} else {
searchClear.style.display = "none"
}
})
searchInput.addEventListener('focusout', function (e) {
console.log(e.relatedTarget)
setTimeout(() => {
if (e.relatedTarget == searchClear) {
console.log(1)
} else {
searchCancel.style.display = "none"
}
}, 500)
})
searchInput.addEventListener("keyup", function (event) {
if (event.keyCode === 46) {
event.preventDefault();
if (searchInput.value.length == 0) {
searchClear.style.display = "none"
}
}
});
CodePudding user response:
Do you necessarily need to hide the cancel button on focus lost?
How about hiding it only if the input doesn't have any value, something like this:
searchInput.addEventListener('focusout', function (e) {
if (!searchInput.value) { // trim if needed
searchCancel.style.display = "none"
}
});
This way even if you click the clear button (triggering focusout) it will not hide the cancel button because at that point the input is not going to be empty.