jimbo
jimbo

Reputation: 436

Django with Vue, detect form validation error

I have a Django ModelForm which is displayed in the template by using using crispy forms. After the user fills out the fields and presses a Submit button, an email is sent at the backend using Django's core send_email.

The problem is that the call to send_email is synchronous, so the user has to wait for the next page to load (success/failure page) but in this time the user might press the Submit button again and this generates multiple POSTs, making multiple emails.

I want to use Vue.js to make the button inactive once the user presses it but only if it passes Django's form validation. Is there a way to detect this?

Upvotes: 0

Views: 1025

Answers (1)

Redha Achour
Redha Achour

Reputation: 81

Add to your button :disabled="!readyToSend" where readyToSend can be returned by your data function or a computed propoerty.

Before submitting the form set this variable to false, afater receiving data from your API, reset it to true.

In the following example I've choosen to make readyToSend a computed proporty where it will return true if the form is valid and if the process is not waiting for the API response.

The complete Code Pen example is here

html file :

<html>
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <title>example</title>
  </head>
  <body>
    <div id="app">
      <h2>{{ message }}</h2>
      <form @submit.prevent>
        <input type="text" v-model="dataToSend" placeholder="Something to send">
        <button type="button" :disabled="!readyToSend" @click="send">Send</button>
      </form>
    </div>
  </body>
</html>

javascript:

var vm = new Vue({
  el: '#app',
  data: function(){
      return {
       message: "please enter your message and click on send.",
        dataToSend: "",
        sentAndWaiting: false,
      }
  },
  methods:{
    send: async function(){
      this.sentAndWaiting = true;
      // Send Data Here
      this.message = "sending....";
      try{
        let response = await fetch('https://jsonplaceholder.typicode.com/posts/1');
        let jsonResponse = await response.json();
      }
      catch(e){
        this.message = e.message;
      }
      // reponse received ... do Something with it
      this.reponseReceived();
    },
    reponseReceived: function(){
      this.sentAndWaiting = false; 
      this.message = "Ok. Got The response.";
    }
  },
  computed:{
    readyToSend: function(){
      return this.dataToSend.length > 0 && !this.sentAndWaiting;
    }
  },

});

in my browser I had to test this by going to the developper tools and limit my internet connexion to the GPRS and disabling cache:

Screenshot DevTools

Upvotes: 1

Related Questions