T_Ner
T_Ner

Reputation: 127

Vue: how to draw user's attention to empty fields on form submission: is an if-else required?

I try to do the if-else function. I see that it works when there is an empty field it will focus on input first or if there is a value in the input then can submit. But I tried to write some text into the input and then subtracting it and If-else function doesn't work as before so how to do next?

<!doctype html>
<html>

<head>


    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" />
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.min.css" />
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@mdi/[email protected]/css/materialdesignicons.min.css" />
    <link href="https://unpkg.com/[email protected]/dist/bootstrap-vue.css" rel="stylesheet" />
    <link href="https://unpkg.com/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" />
</head>

<body>
    <div id="app">
        <v-app>
            <v-content>
                <v-container>
                    <b-form @submit="onSubmit">
                        <b-row>
                            <b-col>
                                <v-combobox v-model="answer.type_a" :items="type_a" label="a" multiple ref="type_a">
                                </v-combobox>
                            </b-col>
                            <b-col>
                                <v-combobox v-model="answer.type_b" :items="type_b" label="b" multiple ref="type_b">
                                </v-combobox>
                            </b-col>
                        </b-row>

                        <v-btn type="submit" color="primary">Submit</v-btn>

                    </b-form>

                </v-container>
            </v-content>
        </v-app>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.19.2/axios.min.js"></script>
    <script src="https://unpkg.com/[email protected]/dist/bootstrap-vue.min.js"></script>
</body>
<script>
    new Vue({
      el: '#app',
      vuetify: new Vuetify(),
      data: () => ({
        type_a: ["a", "b"],
        type_b: ["c","d"],
      
        
        answer: {
          type_a: "",
          type_b: "",
        },

      }),
       methods: {
        focusInput: function(inputRef) {
          this.$refs[inputRef].focus();
        },
         
       onSubmit(evt) {
      evt.preventDefault();

      if (this.answer.type_a !== "" && this.answer.type_b !== "") {
        axios.post("/", this.answer)
          .then(() => {
            console.log("SUCCESS!!");
          })
          .catch(() => {
            alert("FAILURE!!");
          })
      } else {
        if (!this.answer.type_a) {
          this.focusInput("type_a");
          return ;
        }
        if (!this.answer.type_b) {
          this.focusInput("type_b");
          return ;
        }
        // return true;
      }
    },

         
         

      }

    })

</script>

</html>

In this simple HTML code, I can see function required that I want is when click submit if empty field do focus and If there is a value in the input, can pass

<form>
    <input type="text" name="usrname" required>
    <input type="text" name="usrname" required>
    <input type="submit">
</form>

Upvotes: 1

Views: 159

Answers (2)

ProfDFrancis
ProfDFrancis

Reputation: 9411

Example of using v-if in the template

As my short answer wasn't clear enough, I have taken your code and changed the code around the SUBMIT button. I have used Vue's ability to make HTML content appear and disappear, depending on a condition of the Javascript variables.

When you write v-if inside the < > of a div, then that div is only rendered if the condition of the v-if is true. Using this approach you can make each question only appear (and automatically take focus, using the autofocus attribute) when all previous questions have been answered.

This is much better than showing a large page of questions, which the user only realises is incomplete when they press Submit. Better that their attention is always directed to the task they need to do now, and no later nasty surprises.

<!DOCTYPE html>
<html>
  <head>
    <link
      rel="stylesheet"
      href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900"
    />
    <link
      rel="stylesheet"
      href="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.min.css"
    />
    <link
      rel="stylesheet"
      href="https://cdn.jsdelivr.net/npm/@mdi/[email protected]/css/materialdesignicons.min.css"
    />
    <link
      href="https://unpkg.com/[email protected]/dist/bootstrap-vue.css"
      rel="stylesheet"
    />
    <link
      href="https://unpkg.com/[email protected]/dist/css/bootstrap.min.css"
      rel="stylesheet"
    />
  </head>

  <body>
    <div id="app">
      <v-app>
        <v-main>
          <v-container>
            <b-form @submit="onSubmit">
              <b-row>
                <b-col>
                  <v-combobox
                    v-model="answer.type_a"
                    :items="type_a"
                    label="a"
                    multiple
                    autofocus
                    ref="type_a"
                  >
                  </v-combobox>
                </b-col>
                <b-col v-if="answer.type_a !==''">
                  <v-combobox
                    v-model="answer.type_b"
                    :items="type_b"
                    label="b"
                    multiple
                    autofocus
                    ref="type_b"
                  >
                  </v-combobox>
                </b-col>
                <b-col> 
                  <div v-if="answer.type_b!==''">
                    <v-btn type="submit" color="primary">Submit</v-btn>
                  </div>
                </b-col>
              </b-row>
            </b-form>
          </v-container>
        </v-main>
      </v-app>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.19.2/axios.min.js"></script>
    <script src="https://unpkg.com/[email protected]/dist/bootstrap-vue.min.js"></script>
  </body>
  <script>
    new Vue({
      el: "#app",
      vuetify: new Vuetify(),
      data: () => ({
        type_a: ["a", "b"],
        type_b: ["c", "d"],

        answer: {
          type_a: "",
          type_b: "",
        },
      }),
      methods: {
        focusInput: function(inputRef) {
          this.$refs[inputRef].focus();
        },

        onSubmit(evt) {
          evt.preventDefault();
          if ((!this.answer.type_a, !this.answer.type_b)) {
            if (!this.answer.type_a) {
              this.focusInput("type_a");
              return true;
            }
            if (!this.answer.type_b) {
              this.focusInput("type_b");
              return true;
            }
          } else {
            axios
              .post("", this.answer)
              .then(() => {
                alert("SUCCESS!!");
              })
              .catch(() => {
                alert("FAILURE!!");
              });
          }
        },
      },
    });
  </script>
</html>

Upvotes: 1

ProfDFrancis
ProfDFrancis

Reputation: 9411

You are right, Vue and its reactivity allow much better ways of doing this

Here is a simple approach you can try: show the "Submit" button only once they have entered all the data.

<v-combobox v-model="answer.type_a" :items="type_a" label="a" multiple ref="type_a">
</v-combobox>

<v-combobox v-model="answer.type_b" :items="type_b" label="b" multiple ref="type_b">
</v-combobox>

<div v-if="answer.type_a && answer.type_b">
    <v-btn type="submit" color="primary">Submit</v-btn>
</div>
<div v-else>
    Both entries are required
</div>

The HTML itself contains the "if-then" logic, which is easier to see when programming. Only when answers are given (for simplicity I am assuming that valid answers are 'truthy' in Javascript), will the button be visible. Until that happens, they will get a message saying "Both entries are required".

Is this enough of a help to get you started?

Upvotes: 0

Related Questions