Reputation: 2031
I have this input box:
<b-row>
<b-col md="3"
v-for="(header, index) in columns"
:key="index"
>
<b-form-group>
<b-form-input
placeholder="Search"
type="text"
class="d-inline-block"
@input="advanceSearch($event, header.field)"
/>
</b-form-group>
</b-col>
</b-row>
When user type something I store the input to searchString
:
advanceSearch(e, field) {
this.searchString.push({
[field] : e
});
// http.post().then().catch(); // my http call
},
I want call http request when user finished type. But not it seems that every key strong it's callign the HTTP.
Is there any way in VUE JS ?
Upvotes: 0
Views: 766
Reputation: 340
This is how I achieved this with the smallest amount of code and easy to use :
<template>
<input v-model="searchInput" type="text" placeholder="Search...">
</template
<script>
export default {
data() {
return {
searchInput: null
};
},
watch: {
searchInput: function() {
clearTimeout(this.searchTimeout);
this.searchTimeout = setTimeout(() => {
this.searchFunction();
}, 500);
}
},
methods: {
searchFunction() {
/* whatever you perform for your search */
// use this.searchInput as search term
},
}
}
</script>
The use of v-model
and searchInput
avoid passing search parameters across every event and methods.
500 can be replaced by anything you want as search delay after typing ends, 300 to 600 is usually Ok for user experience.
Upvotes: 0
Reputation: 6319
Looks like you want the function to be triggered both on idle typing and when a user focuses out.
And un-focused input fires the event change
, so that should be simple to work with. You can also implement debouncing, amounting to something like the following:
export default {
advanceSearch(e, field) { /* ... */ },
// create a custom debounced search
debouncedSearch(...args) {
clearTimeout(this.debounceTimeout); // if we set a previous debounce timeout, don't fire it
this.debounceTimeout = setTimeout(
// we need to bind a custom `this` value because setTimeout binds `window` by default:
e => this.advanceSearch.apply(this, args),
500 // debounce time
);
},
// ...
}
For your Vue code, the input should look something like the following. Notice how a change
listener was added to the component, and that the input
handler called the debounce
function instead of directly.
<b-form-input
placeholder="Search"
type="text"
class="d-inline-block"
@input="debouncedSearch($event, header.field)"
@change="advanceSearch($event, header.field)"
/>
What this code essentially does, is when the user types then clicks out of the input box ("blur"), the HTTP request will fire, or when the user pauses typing for half a second (feel free to change this value), the request will also be sent.
Upvotes: 1