Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
124 views
in Technique[技术] by (71.8m points)

javascript - how can i do form wizard with validation using Vue.js

I'm working on a small project using Vue.Js, I followed a video tutorial to create the wizard, but now I try to validate the form using two css classes that I have already created 'is-valid' and 'is-invalid' but my validation doesn't works, this my code

<div class="modal-content tx-14">
              <div class="p-0 bg-ui-01">
                 <ul class="nav nav-tabs nav-justified" id="myTab3" role="tablist">
                    <li class="nav-item m-0">
                       <a class="nav-link border-0 rounded-0" id="home-tab3" data-toggle="tab" href="#home3" role="tab" aria-controls="home" aria-selected="true" :class="{'active':current_step == 1}" @click.prevent="goToStep(1)">Website</a>
                    </li>
                    <li class="nav-item m-0">
                       <a class="nav-link border-0 rounded-0" id="profile-tab3" data-toggle="tab" href="#profile3" role="tab" aria-controls="profile" aria-selected="false" :class="{'disabled':max_step < 2, 'active': current_step == 2}" @click.prevent="goToStep(2)">Location</a>
                    </li>
                    <li class="nav-item m-0">
                       <a class="nav-link border-0 rounded-0" id="contact-tab3" data-toggle="tab" href="#contact3" role="tab" aria-controls="contact" aria-selected="false" :class="{'disabled':max_step < 3, 'active': current_step == 3}" @click.prevent="goToStep(3)">Keywords</a>
                    </li>
                    <li class="nav-item m-0">
                       <a class="nav-link border-0 rounded-0" id="contact-tab3" data-toggle="tab" href="#contact4" role="tab" aria-controls="contact" aria-selected="false" :class="{'disabled':max_step < 4, 'active': current_step == 4}" @click.prevent="goToStep(4)">Crawler</a>
                    </li>
                    <li class="nav-item m-0">
                       <a class="nav-link border-0 rounded-0" id="contact-tab3" data-toggle="tab" href="#contact4" role="tab" aria-controls="contact" aria-selected="false" :class="{'disabled':max_step < 5, 'active': current_step == 5}" @click.prevent="goToStep(5)">Competition</a>
                    </li>
                 </ul>
              </div>
              <div class="modal-body">
                 <div class="tab-content" id="myTabContent">
                    <div class="fade show active" id="home" role="tabpanel" aria-labelledby="home-tab" v-show="current_step == 1">
                       <h4 class="text-center">Create Your Project</h4>
                       <p class="text-center">Enter your website informations, so you can track and improve your SEO traffic and keep an eye on the competition.</p>
                       <div class="row row-sm">
                          <div class="col-sm-12">
                             <div class="form-group">
                                <input type="url" id="project_url" v-model="rules.project_url.string" class="form-control" placeholder="Project URL">
                             </div>
                          </div>
                          <div class="col-sm-12">
                             <div class="form-group">
                                <input type="text" class="form-control" id="project_name" v-model="rules.project_name.string" placeholder="Project name">
                             </div>
                          </div>
                       </div>
                    </div>
                    <div id="location" role="tabpanel" aria-labelledby="profile-tab" v-show="current_step == 2">
                       <h4 class="text-center">Choose Your Location</h4>
                       <p class="text-center">
                          Enter all of the countries or cities you do business in or want traffic from. We recommend that you add at least 3 locations.
                       </p>
                       <div class="row row-sm">
                          <div class="col-sm-4">
                             <div class="form-group">
                                <select class="custom-select">
                                   <option selected>Select Engine</option>
                                   <option value="1">Google</option>
                                   <option value="2">Google Mobile</option>
                                </select>
                             </div>
                          </div>
                          <div class="col-sm-8">
                             <div class="form-group">
                                <input type="text" class="form-control" placeholder="Target Location">
                             </div>
                          </div>
                       </div>
                       <div class="row row-sm">
                          <div class="col-sm-4">
                             <div class="form-group">
                                <select class="custom-select">
                                   <option selected>Select Engine</option>
                                   <option value="1">Google</option>
                                   <option value="2">Google Mobile</option>
                                </select>
                             </div>
                          </div>
                          <div class="col-sm-8">
                             <div class="form-group">
                                <input type="text" class="form-control" placeholder="Target Location">
                             </div>
                          </div>
                       </div>
                    </div>
                    <div id="keywords" role="tabpanel" aria-labelledby="contact-tab" v-show="current_step == 3">
                       <h4 class="text-center">Add Keywords</h4>
                       <p class="text-center">
                          Choose the keywords you would like to track across the selected search engines. Track on the national level, or add locations to track on the local level. Add labels to group keywords by topic.
                       </p>
                       <textarea class="form-control" cols="30" rows="10" placeholder="Add separated keywords by comma ex: pasta,fish"></textarea>
                    </div>
                    <div id="crawling" role="tabpanel" aria-labelledby="contact-tab" v-show="current_step == 4">
                       <h4 class="text-center">Set Crawl Limit</h4>
                       <p class="text-center">
                          We crawl your site weekly to surface technical site issues that may be impacting your SEO performance. Select the number of pages you’d like to have crawled on this site.
                       </p>
                       <div class="row row-sm">
                          <div class="col-sm-4">
                             <div class="form-group">
                                <select class="custom-select">
                                   <option value="5000">5,000</option>
                                   <option value="10000">10,000</option>
                                   <option value="20000">20,000</option>
                                   <option value="30000">30,000</option>
                                   <option value="40000">40,000</option>
                                   <option value="50000">50,000</option>
                                   <option value="75000">75,000</option>
                                   <option value="100000">100,000</option>
                                   <option value="250000">250,000</option>
                                   <option value="450000">450,000</option>
                                </select>
                             </div>
                          </div>
                          <div class="col-sm-8">
                             <div class="form-group">
                                <select class="custom-select">
                                   <option selected>Whole Website</option>
                                   <option value="1">Exclude sub-domains</option>
                                   <option value="2">Follow sitemap</option>
                                </select>
                             </div>
                          </div>
                       </div>
                    </div>
                    <div id="crawling" role="tabpanel" aria-labelledby="contact-tab" v-show="current_step == 5">
                       <h4 class="text-center">Benchmark vs Competitors</h4>
                       <p class="text-center">
                          We will track competitive link and keyword metrics for these sites.
                       </p>
                       <div class="row row-sm">
                          <div class="col-sm-12">
                             <div class="form-group">
                                <input type="text" class="form-control" placeholder="Target Location">
                             </div>
                          </div>
                          <div class="col-sm-12">
                             <div class="form-group">
                                <input type="text" class="form-control" placeholder="Target Location">
                             </div>
                          </div>
                          <div class=&q

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

The basic idea is that you don't validate the form itself, but the data that is displayed in the form.

You might think that "but they are the same" or "it's a subtle difference", but no.

With jQuery you are going through the form UI - a part of the application, that is THE END RESULT of whole lot of other things. Don't do that. Store your form data in Vue's data option, and only display the result of validations.

Vue.component('InputField', {
  props: ['error', 'value'],
  computed: {
    inputValue: {
      get() {
        return this.value
      },
      set(val) {
        this.$emit("update:value", val)
      }
    },
  },
  template: `
    <div
      class="input-field-wrapper"
      :class="{ error: error }"
    >
      <label>
        INPUT: 
        <input
          type="text"
          placeholder="Type in something"
          v-model="inputValue"
        />
        <span v-if="error">this field is required!</span>
      </label>
    </div>
  `
})

new Vue({
  el: "#app",
  data() {
    return {
      form: [],
      canSubmit: false,
    }
  },
  methods: {
    handleAddInput(id) {
      this.form.push({
        id,
        error: null,
        value: null,
      })
    },
    handleFormValidate() {
      this.form = this.form.map(({ id, error, value }) => {
        return {
          id,
          error: !value,
          value,
        }
      })
      return this.form.every(({
        error
      }) => !error)
    },
    handleResetValidation() {
      this.form = this.form.map(field => {
        return {
          ...field,
          error: false
        }
      })
    },
    handleSubmitForm() {
      this.canSubmit = this.handleFormValidate()
    },
  },
  template: `
    <div>
      <button
        @click="handleAddInput(form.length + 1)"
      >ADD INPUT FIELD +</button>
      <button
        @click="handleFormValidate"
      >VALIDATE FORM</button>
      <button
        @click="handleResetValidation"
      >RESET VALIDATION</button>
      <hr />
      <form>
        <input-field
          v-for="(inputField, i) in form"
          :key="inputField.id"
          :error="inputField.error"
          :value.sync="inputField.value"
        ></input-field>
        <hr />
        <button type="submit" @click.prevent="handleSubmitForm">SUBMIT FORM</button>
      </form>
      FORM CAN BE SUBMITTED: {{ canSubmit }}
    </div>
  `
})
.input-field-wrapper {
  padding: 8px 16px;
  color: black;
}
.input-field-wrapper.error {
  color: white;
  background: red;
  transition: all 0.1s;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app"></div>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...