loading...
Cover image for Vue Quick Shot - Disabling a Submit Button While Waiting for an Ajax Call

Vue Quick Shot - Disabling a Submit Button While Waiting for an Ajax Call

raymondcamden profile image Raymond Camden Originally published at raymondcamden.com on ・2 min read

Welcome to the first of a week long series of quick Vue.js tips. Each day (well, each week day) I'll be posting a real short, but hopefully practical, tip for Vue.js developers. For the first day we'll start with a simple tip but one that almost any application can use.

It is fairly typical for an application to make use of some sort of asynchronous process. Typically this is an Ajax call. (Although not always, and to be clear, today's tip will work with anything asynchronous!) You have a form of some sort. The user hits a button. You make a network call and when that call is done, you render the result. Let's consider a simple example of this.

First, a quick form.

<div id="app" v-cloak>
  <form @submit.prevent="doSearch">
    <input type="search" v-model="term" placeholder="Search">
    <input type="submit" value="Perform Search">
  </form>

  <div v-if="result">
  <p>
    <b>The result: {{ result }}</b>
  </p>
  </div>
</div>

My form has one field and a button. On submit I'll run a method named doSearch. When I get a result, it will be displayed in a paragraph below.

Now let's look at the JavaScript:

Vue.config.productionTip = false;
Vue.config.devtools = false;

const app = new Vue({
  el:'#app',
  data: {
    term:'',
    result:''
  },
  methods:{
    async doSearch() {
     if(this.term === '') return; 
     console.log(`search for ${this.term}`);
     // clear previous result
     this.result = '';
     this.result = await searchMyAPI(this.term);
    }
  }
})

async function searchMyAPI(s) {
  return new Promise((resolve, reject) => {
    window.setTimeout(() => {
      resolve(`something for ${s}`);
    }, 3000);
  });
}

My doSearch method checks to see if anything was entered and if so, fires off a call to searchMyAPI. The details of searchMyAPI aren't relevant, but you can see I'm faking a slow process by making it wait for three seconds before returning the result.

You can test this here:

When you test this, note that there's no indication that the search is actually doing anything. There's actually a few things we can do here, but today we're just going to do one - disabling the button while the search is being done.

I'll begin by slightly tweaking the button:

<input type="submit" value="Perform Search" :disabled="searchDisabled">

I've added a bound property, disabled, that points to a new value, searchDisabled. I then modified my JavaScript like so:

Vue.config.productionTip = false;
Vue.config.devtools = false;

const app = new Vue({
  el:'#app',
  data: {
    term:'',
    result:'',
    searchDisabled:false
  },
  methods:{
    async doSearch() {
     if(this.term === '') return; 
     console.log(`search for ${this.term}`);
     //disable the button
     this.searchDisabled = true;
     // clear previous result
     this.result = '';
     this.result = await searchMyAPI(this.term);
     //re-enable the button
     this.searchDisabled = false;
    }
  }
})

First I added searchDisabled, defaulted to false. Before the search is begun I switch to false and when done, back to true. That's it! You can test this version here:

That's it for today's quick tip. As I said, there's one more thing you could do to this form to make it even better and I'll be covering that in tomorrow's tip!

Discussion

pic
Editor guide