mirror of
https://github.com/tenrok/vue-form-wizard.git
synced 2026-06-23 13:50:33 +03:00
#18 Handle dynamic tab updates
This commit is contained in:
+6
-16
@@ -1,5 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
|
<button @click="tabs.shift()">Remove one tab</button>
|
||||||
|
<button @click="tabs.push('testt')">Add one tab</button>
|
||||||
<form-wizard @on-complete="onComplete"
|
<form-wizard @on-complete="onComplete"
|
||||||
:hide-buttons="false"
|
:hide-buttons="false"
|
||||||
shape="square"
|
shape="square"
|
||||||
@@ -7,22 +9,9 @@
|
|||||||
@on-loading="setLoading"
|
@on-loading="setLoading"
|
||||||
@on-error="setError"
|
@on-error="setError"
|
||||||
class="card" ref="wizard">
|
class="card" ref="wizard">
|
||||||
<tab-content title="Personal details"
|
<tab-content v-for="tab in tabs" :title="tab" :key="tab" icon="ti-settings">
|
||||||
route="/first"
|
{{tab}}
|
||||||
icon="ti-user">
|
|
||||||
</tab-content>
|
</tab-content>
|
||||||
<tab-content title="Additional Info"
|
|
||||||
:before-change="validateAsync"
|
|
||||||
route="/second"
|
|
||||||
icon="ti-settings">
|
|
||||||
</tab-content>
|
|
||||||
<tab-content title="Last step"
|
|
||||||
route="/third"
|
|
||||||
icon="ti-check">
|
|
||||||
</tab-content>
|
|
||||||
<transition name="fade" mode="out-in">
|
|
||||||
<router-view></router-view>
|
|
||||||
</transition>
|
|
||||||
<div class="loader" v-if="loadingWizard"></div>
|
<div class="loader" v-if="loadingWizard"></div>
|
||||||
<div v-if="error">
|
<div v-if="error">
|
||||||
{{error}}
|
{{error}}
|
||||||
@@ -39,7 +28,8 @@
|
|||||||
return {
|
return {
|
||||||
loadingWizard: false,
|
loadingWizard: false,
|
||||||
error: null,
|
error: null,
|
||||||
count: 0
|
count: 0,
|
||||||
|
tabs: ['test','test2','test3']
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|||||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
@@ -233,6 +233,37 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
nextTab () {
|
||||||
|
let cb = () => {
|
||||||
|
if (this.activeTabIndex < this.tabCount - 1) {
|
||||||
|
this.changeTab(this.activeTabIndex, this.activeTabIndex + 1)
|
||||||
|
} else {
|
||||||
|
this.isLastStep = true
|
||||||
|
this.$emit('finished')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.beforeTabChange(this.activeTabIndex, cb)
|
||||||
|
},
|
||||||
|
prevTab () {
|
||||||
|
let cb = () => {
|
||||||
|
if (this.activeTabIndex > 0) {
|
||||||
|
this.setValidationError(null)
|
||||||
|
this.changeTab(this.activeTabIndex, this.activeTabIndex - 1)
|
||||||
|
this.isLastStep = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.validateOnBack) {
|
||||||
|
this.beforeTabChange(this.activeTabIndex, cb)
|
||||||
|
} else {
|
||||||
|
cb()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
finish () {
|
||||||
|
let cb = () => {
|
||||||
|
this.$emit('on-complete')
|
||||||
|
}
|
||||||
|
this.beforeTabChange(this.activeTabIndex, cb)
|
||||||
|
},
|
||||||
setLoading (value) {
|
setLoading (value) {
|
||||||
this.loading = value
|
this.loading = value
|
||||||
this.$emit('on-loading', value)
|
this.$emit('on-loading', value)
|
||||||
@@ -312,37 +343,6 @@
|
|||||||
this.maxStep = this.activeTabIndex
|
this.maxStep = this.activeTabIndex
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
nextTab () {
|
|
||||||
let cb = () => {
|
|
||||||
if (this.activeTabIndex < this.tabCount - 1) {
|
|
||||||
this.changeTab(this.activeTabIndex, this.activeTabIndex + 1)
|
|
||||||
} else {
|
|
||||||
this.isLastStep = true
|
|
||||||
this.$emit('finished')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.beforeTabChange(this.activeTabIndex, cb)
|
|
||||||
},
|
|
||||||
prevTab () {
|
|
||||||
let cb = () => {
|
|
||||||
if (this.activeTabIndex > 0) {
|
|
||||||
this.setValidationError(null)
|
|
||||||
this.changeTab(this.activeTabIndex, this.activeTabIndex - 1)
|
|
||||||
this.isLastStep = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (this.validateOnBack) {
|
|
||||||
this.beforeTabChange(this.activeTabIndex, cb)
|
|
||||||
} else {
|
|
||||||
cb()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
finish () {
|
|
||||||
let cb = () => {
|
|
||||||
this.$emit('on-complete')
|
|
||||||
}
|
|
||||||
this.beforeTabChange(this.activeTabIndex, cb)
|
|
||||||
},
|
|
||||||
checkRouteChange (route) {
|
checkRouteChange (route) {
|
||||||
let matchingTabIndex = -1
|
let matchingTabIndex = -1
|
||||||
let matchingTab = this.tabs.find((tab, index) => {
|
let matchingTab = this.tabs.find((tab, index) => {
|
||||||
@@ -357,25 +357,63 @@
|
|||||||
const shouldValidate = matchingTabIndex > this.activeTabIndex
|
const shouldValidate = matchingTabIndex > this.activeTabIndex
|
||||||
this.navigateToTab(matchingTabIndex, shouldValidate)
|
this.navigateToTab(matchingTabIndex, shouldValidate)
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
getTabs () {
|
||||||
|
return this.$children.filter((comp) => comp.$options.name === 'tab-content')
|
||||||
|
},
|
||||||
|
activateTab (index) {
|
||||||
|
let tab = this.tabs[index]
|
||||||
|
tab.active = true
|
||||||
|
this.tryChangeRoute(tab)
|
||||||
|
},
|
||||||
|
activateTabAndCheckStep (index) {
|
||||||
|
this.activateTab(index)
|
||||||
|
this.checkStep()
|
||||||
|
this.maxStep = this.startIndex
|
||||||
|
this.activeTabIndex = this.startIndex
|
||||||
|
},
|
||||||
|
initializeTabs () {
|
||||||
|
this.tabs = this.getTabs()
|
||||||
|
if (this.tabs.length > 0 && this.startIndex === 0) {
|
||||||
|
this.activateTab(this.activeTabIndex)
|
||||||
|
}
|
||||||
|
if (this.startIndex < this.tabs.length) {
|
||||||
|
this.activateTabAndCheckStep(this.startIndex)
|
||||||
|
} else {
|
||||||
|
console.warn(`Prop startIndex set to ${this.startIndex} is greater than the number of tabs - ${this.tabs.length}. Make sure that the starting index is less than the number of tabs registered`)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
reinitializeTabs () {
|
||||||
|
let currentTabs = this.getTabs()
|
||||||
|
if (this.tabs.length === 0 || this.tabs.length === currentTabs.length) return
|
||||||
|
this.tabs = currentTabs
|
||||||
|
let oldTabIndex = -1
|
||||||
|
this.tabs.find((tab, index) => {
|
||||||
|
if (tab.active) {
|
||||||
|
oldTabIndex = index
|
||||||
|
}
|
||||||
|
return tab.active
|
||||||
|
})
|
||||||
|
if (oldTabIndex === -1) {
|
||||||
|
oldTabIndex = this.activeTabIndex > 0 ? this.activeTabIndex - 1 : 0
|
||||||
|
}
|
||||||
|
|
||||||
|
this.tabs.forEach((tab) => {
|
||||||
|
tab.active = false
|
||||||
|
})
|
||||||
|
this.activateTab(oldTabIndex)
|
||||||
|
this.maxStep = oldTabIndex
|
||||||
|
this.activeTabIndex = oldTabIndex
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted () {
|
mounted () {
|
||||||
this.tabs = this.$children.filter((comp) => comp.$options.name === 'tab-content')
|
this.initializeTabs()
|
||||||
if (this.tabs.length > 0 && this.startIndex === 0) {
|
},
|
||||||
let firstTab = this.tabs[this.activeTabIndex]
|
/***
|
||||||
firstTab.active = true
|
* Used to handle dynamic tab addition from an array since $children is not reactive
|
||||||
this.tryChangeRoute(firstTab)
|
*/
|
||||||
}
|
updated () {
|
||||||
if (this.startIndex < this.tabs.length) {
|
this.reinitializeTabs()
|
||||||
let tabToActivate = this.tabs[this.startIndex]
|
|
||||||
this.activeTabIndex = this.startIndex
|
|
||||||
tabToActivate.active = true
|
|
||||||
this.maxStep = this.startIndex
|
|
||||||
this.tryChangeRoute(this.tabs[this.startIndex])
|
|
||||||
this.checkStep()
|
|
||||||
} else {
|
|
||||||
console.warn(`Prop startIndex set to ${this.startIndex} is greater than the number of tabs - ${this.tabs.length}. Make sure that the starting index is less than the number of tabs registered`)
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
'$route.path': function (newRoute) {
|
'$route.path': function (newRoute) {
|
||||||
|
|||||||
Reference in New Issue
Block a user