Shibbir
Shibbir

Reputation: 2031

Vue Js- How to call HTTP request when user finished type

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

Answers (2)

Jean-Loup
Jean-Loup

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

code
code

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

Related Questions