Vue form Wizard prevent back step

Viewed 974

we are working with injection of dynamic components by server response, but once the user has approved a step, we will prevent him from going back to the steps he has already approved.

HTML


<div id="app">
<div>
  <form-wizard @on-complete="onComplete">
    <tab-content v-for="tab in tabs"
                v-if="!tab.hide"
                :key="tab.title"
                :title="tab.title"
                :icon="tab.icon">
      <component :is="tab.component"></component>
    </tab-content>
  </form-wizard>
 </div>
</div>

JS

Vue.use(VueFormWizard)
Vue.component('step1', {
 template:` <div> My first tab content <br>
             </div>`
 }
)
Vue.component('step2', {
 template:`<div>  My second tab content </div>`
})
Vue.component('step3', {
 template:`<div>  My third tab content </div>`
})
Vue.component('step4', {
template:`<div> Yuhuuu! This seems pretty damn simple </div>`
})
new Vue({
 el: '#app',
 data() {
    return {
    tabs: [{title: 'Personal details', icon: 'ti-user', component: 'step1'}, 
    {title: 'Is Logged In?', icon: 'ti-settings', component: 'step2', hide: false}, 
    {title: 'Additional Info', icon: 'ti-location-pin', component: 'step3'},
    {title: 'Last step', icon: 'ti-check', component: 'step4'},
    ],
  }
 },
 methods: {
  onComplete: function(){
      alert('Yay. Done!');
   }
  }
})

but we have not found answers in the documentation if suddenly someone has had this problem and can tell us how to solve it, I would appreciate it, thanks.

2 Answers

Once the user has approved a step, we will prevent him from going back to the steps he has already approved.

Validate going forward, then simply remove the back button.

I did some tests and the beforeTabSwitch doesn't fire if going backwards props.prevTab(), shame as you could then do it in the validate call.

Here is an example, which validates going forward and removes the Previous button and prevents navigating via the header (wizard-step).

Vue.use(VueFormWizard)
Vue.component('step1', {
  template: ` <div> My first tab content</div>`,
  data: () => ({
    name: ''
  }),
  methods: {
    validate() {
      // change `true` to things checked on model, beyond scope of question
      this.$emit('on-validate', this.$data, true)
      return true
    }
  }
})
Vue.component('step2', {
  template: `<div>  My second tab content </div>`,
  data: () => ({
    logged_in_yada: ''
  }),
  methods: {
    validate() {
      this.$emit('on-validate', this.$data, true)
      return true
    }
  }
})
Vue.component('step3', {
  template: `<div>  My third tab content </div>`,
  data: () => ({
    additional_info: ''
  }),
  methods: {
    validate() {
      this.$emit('on-validate', this.$data, true)
      return true
    }
  }
})
Vue.component('step4', {
  template: `<div> Yuhuuu! This seems pretty damn simple </div>`,
  data: () => ({
    last_step: ''
  }),
  methods: {
    validate() {
      this.$emit('on-validate', this.$data, true)
      return true
    }
  }
})
new Vue({
  el: '#app',
  data() {
    return {
      tabModel: {},
      tabs: [{
          title: 'Personal details',
          icon: 'ti-user',
          component: 'step1'
        },
        {
          title: 'Is Logged In?',
          icon: 'ti-settings',
          component: 'step2',
          hide: false
        },
        {
          title: 'Additional Info',
          icon: 'ti-location-pin',
          component: 'step3'
        },
        {
          title: 'Last step',
          icon: 'ti-check',
          component: 'step4'
        },
      ],
    }
  },
  methods: {
    onComplete: function() {
      alert('Yay. Done!');
    },
    validateStep(name) {
      return this.$refs[name][0].validate()
    },
    mergeTabModel(model, isValid) {
      if (isValid) {
        // merging each step model into the final model
        this.tabModel = Object.assign({}, this.tabModel, model)
      }
    }
  }
})
<script src="https://vuejs.org/js/vue.min.js"></script>
<link rel="stylesheet" href="https://unpkg.com/vue-form-wizard/dist/vue-form-wizard.min.css">
<script src="https://unpkg.com/vue-form-wizard/dist/vue-form-wizard.js"></script>
<link rel="stylesheet" href="https://rawgit.com/lykmapipo/themify-icons/master/css/themify-icons.css">


<div id="app">
  <div>
    <form-wizard @on-complete="onComplete">
      <wizard-step slot-scope="props" slot="step" :tab="props.tab" :transition="props.transition" :index="props.index">
      </wizard-step>
      <tab-content v-for="tab in tabs" v-if="!tab.hide" :key="tab.title" :title="tab.title" :icon="tab.icon" :before-change="()=>validateStep(tab.component)">
        <component :is="tab.component" :ref="tab.component" @on-validate="mergeTabModel"></component>
      </tab-content>
      <template slot="footer" scope="props">
        <div class="wizard-footer-left">
          <!-- remove previous button -->
          <!-- <wizard-button v-if="props.activeTabIndex > 0 && !props.isLastStep" @click.native="props.prevTab()" :style="props.fillButtonStyle">Previous</wizard-button> -->
        </div>
        <div class="wizard-footer-right">
          <wizard-button @click.native="props.nextTab()" class="wizard-footer-right finish-button" :style="props.fillButtonStyle">{{props.isLastStep ? 'Done' : 'Next'}}</wizard-button>
        </div>
      </template>
    </form-wizard>

    <pre>{{ tabModel }}</pre>
  </div>
</div>

use this CSS instead:

.vue-form-wizard .wizard-nav-pills a, .vue-form-wizard .wizard-nav-pills li{
  cursor: not-allowed;
  pointer-events: none;
}
Related