2023-02-28 08:29:30 +00:00
< template >
< DocSectionText v-bind ="$attrs" >
< p > In order to add interactivity to the component , disable < i > readonly < / i > to control the Steps . < / p >
< / DocSectionText >
< div class = "card" >
2023-08-31 14:02:09 +00:00
< Steps
: model = "items"
aria - label = "Form Steps"
: pt = " {
menuitem : ( { context } ) => ( {
class : isActive ( context . item ) && 'p-highlight p-steps-current'
} )
} "
>
2023-08-30 14:38:19 +00:00
< template # item = "{ label, item, index, props }" >
< router -link v -if = " item.route " v -slot = " routerProps " :to ="item.route" custom >
< a :href ="routerProps.href" v-bind ="props.action" @click="($event) => routerProps.navigate($event)" @keydown.enter="($event) => routerProps.navigate($event)" >
< span v-bind ="props.step" > {{ index + 1 }} < / span >
< span v-bind ="props.label" > {{ label }} < / span >
< / a >
< / r o u t e r - l i n k >
< / template >
< / Steps >
2023-02-28 08:29:30 +00:00
< / div >
< NuxtPage v-slot ="{ Component }" :formData="formObject" @prev-page="prevPage($event)" @next-page="nextPage($event)" @complete="complete" >
< keep -alive >
< component :is ="Component" / >
< / k e e p - a l i v e >
< / NuxtPage >
< br class = "mt-4" / >
< DocSectionCode :code ="code" / >
< / template >
< script >
export default {
data ( ) {
return {
items : [
{
label : 'Personal' ,
2023-09-18 11:23:57 +00:00
route : '/steps/'
2023-02-28 08:29:30 +00:00
} ,
{
label : 'Seat' ,
2023-08-30 14:38:19 +00:00
route : '/steps/seat'
2023-02-28 08:29:30 +00:00
} ,
{
label : 'Payment' ,
2023-08-30 14:38:19 +00:00
route : '/steps/payment'
2023-02-28 08:29:30 +00:00
} ,
{
label : 'Confirmation' ,
2023-08-30 14:38:19 +00:00
route : '/steps/confirmation'
2023-02-28 08:29:30 +00:00
}
] ,
formObject : { } ,
code : {
2023-09-22 12:54:14 +00:00
basic : `
< div class = "card" >
2023-08-31 14:02:09 +00:00
< Steps
: model = "items"
aria - label = "Form Steps"
: pt = " {
menuitem : ( { context } ) => ( {
class : isActive ( context . item ) && 'p-highlight p-steps-current'
} )
} "
>
2023-08-30 14:38:19 +00:00
< template # item = "{ label, item, index, props }" >
< router -link v -if = " item.route " v -slot = " routerProps " :to ="item.route" custom >
< a :href ="routerProps.href" v-bind ="props.action" @click="($event) => routerProps.navigate($event)" @keydown.enter="($event) => routerProps.navigate($event)" >
< span v-bind ="props.step" > {{ index + 1 }} < / span >
< span v-bind ="props.label" > {{ label }} < / span >
< / a >
< / r o u t e r - l i n k >
< / template >
< / Steps >
2023-02-28 08:29:30 +00:00
< / div >
< router -view v-slot ="{ Component }" :formData="formObject" @prev-page="prevPage($event)" @next-page="nextPage($event)" @complete="complete" >
< keep -alive >
< component :is ="Component" / >
< / k e e p - a l i v e >
2023-10-15 09:38:39 +00:00
< / r o u t e r - v i e w >
` ,
2023-09-22 12:54:14 +00:00
options : `
< template >
2023-02-28 08:29:30 +00:00
< div >
< div class = "card" >
2023-08-31 14:02:09 +00:00
< Steps
: model = "items"
aria - label = "Form Steps"
: pt = " {
menuitem : ( { context } ) => ( {
class : isActive ( context . item ) && 'p-highlight p-steps-current'
} )
} "
>
2023-08-30 14:38:19 +00:00
< template # item = "{ label, item, index, props }" >
< router -link v -if = " item.route " v -slot = " routerProps " :to ="item.route" custom >
< a :href ="routerProps.href" v-bind ="props.action" @click="($event) => routerProps.navigate($event)" @keydown.enter="($event) => routerProps.navigate($event)" >
< span v-bind ="props.step" > {{ index + 1 }} < / span >
< span v-bind ="props.label" > {{ label }} < / span >
< / a >
< / r o u t e r - l i n k >
< / template >
< / Steps >
2023-02-28 08:29:30 +00:00
< / div >
2023-08-30 14:38:19 +00:00
< Toast / >
2023-02-28 08:29:30 +00:00
< router -view v-slot ="{Component}" :formData="formObject" @prevPage="prevPage($event)" @nextPage="nextPage($event)" @complete="complete" >
< keep -alive >
< component :is ="Component" / >
< / k e e p - a l i v e >
< / r o u t e r - v i e w >
< / div >
< / template >
< script >
export default {
data ( ) {
return {
items : [
{
label : 'Personal' ,
2023-08-30 14:38:19 +00:00
route : '/'
2023-02-28 08:29:30 +00:00
} ,
{
label : 'Seat' ,
2023-08-30 14:38:19 +00:00
route : '/seat'
2023-02-28 08:29:30 +00:00
} ,
{
label : 'Payment' ,
2023-08-30 14:38:19 +00:00
route : '/payment'
2023-02-28 08:29:30 +00:00
} ,
{
label : 'Confirmation' ,
2023-08-30 14:38:19 +00:00
route : '/confirmation'
2023-02-28 08:29:30 +00:00
}
] ,
formObject : { }
}
} ,
methods : {
nextPage ( event ) {
for ( let field in event . formData ) {
this . formObject [ field ] = event . formData [ field ] ;
}
2023-10-16 12:11:16 +00:00
this . $router . push ( this . items [ event . pageIndex + 1 ] . route ) ;
2023-02-28 08:29:30 +00:00
} ,
prevPage ( event ) {
2023-10-16 12:11:16 +00:00
this . $router . push ( this . items [ event . pageIndex - 1 ] . route ) ;
2023-02-28 08:29:30 +00:00
} ,
complete ( ) {
this . $toast . add ( { severity : 'success' , summary : 'Order submitted' , detail : 'Dear, ' + this . formObject . firstname + ' ' + this . formObject . lastname + ' your order completed.' } ) ;
2023-08-31 14:02:09 +00:00
} ,
isActive ( item ) {
return item . route ? this . $router . resolve ( item . route ) . path === this . $route . path : false ;
2023-02-28 08:29:30 +00:00
}
}
}
< \ / script >
< style scoped >
: : v - deep ( b ) {
display : block ;
}
: : v - deep ( . p - card - body ) {
padding : 2 rem ;
}
2023-10-15 09:38:39 +00:00
< / style >
` ,
2023-09-22 12:54:14 +00:00
composition : `
< template >
2023-02-28 08:29:30 +00:00
< div >
< div class = "card" >
2023-08-31 14:02:09 +00:00
< Steps
: model = "items"
aria - label = "Form Steps"
: pt = " {
menuitem : ( { context } ) => ( {
class : isActive ( context . item ) && 'p-highlight p-steps-current'
} )
} "
>
2023-08-30 14:38:19 +00:00
< template # item = "{ label, item, index, props }" >
< router -link v -if = " item.route " v -slot = " routerProps " :to ="item.route" custom >
< a :href ="routerProps.href" v-bind ="props.action" @click="($event) => routerProps.navigate($event)" @keydown.enter="($event) => routerProps.navigate($event)" >
< span v-bind ="props.step" > {{ index + 1 }} < / span >
< span v-bind ="props.label" > {{ label }} < / span >
< / a >
< / r o u t e r - l i n k >
< / template >
< / Steps >
2023-02-28 08:29:30 +00:00
< / div >
2023-08-30 14:38:19 +00:00
< Toast / >
2023-02-28 08:29:30 +00:00
< router -view v-slot ="{Component}" :formData="formObject" @prevPage="prevPage($event)" @nextPage="nextPage($event)" @complete="complete" >
< keep -alive >
< component :is ="Component" / >
< / k e e p - a l i v e >
< / r o u t e r - v i e w >
< / div >
< / template >
< script setup >
import { ref } from "vue" ;
import { useRouter } from "vue-router" ;
import { useToast } from "primevue/usetoast" ;
const router = useRouter ( ) ;
const toast = useToast ( ) ;
const items = ref ( [
{
label : 'Personal' ,
2023-08-30 14:38:19 +00:00
route : "/"
2023-02-28 08:29:30 +00:00
} ,
{
label : 'Seat' ,
2023-08-30 14:38:19 +00:00
route : "/seat" ,
2023-02-28 08:29:30 +00:00
} ,
{
label : 'Payment' ,
2023-08-30 14:38:19 +00:00
route : "/payment" ,
2023-02-28 08:29:30 +00:00
} ,
{
label : 'Confirmation' ,
2023-08-30 14:38:19 +00:00
route : "/confirmation" ,
2023-02-28 08:29:30 +00:00
}
] ) ;
const formObject = ref ( { } ) ;
const nextPage = ( event ) => {
for ( let field in event . formData ) {
formObject . value [ field ] = event . formData [ field ] ;
}
2023-10-16 12:11:16 +00:00
router . push ( items . value [ event . pageIndex + 1 ] . route ) ;
2023-02-28 08:29:30 +00:00
} ;
const prevPage = ( event ) => {
2023-10-16 12:11:16 +00:00
router . push ( items . value [ event . pageIndex - 1 ] . route ) ;
2023-02-28 08:29:30 +00:00
} ;
const complete = ( ) => {
toast . add ( { severity : 'success' , summary : 'Order submitted' , detail : 'Dear, ' + formObject . value . firstname + ' ' + formObject . value . lastname + ' your order completed.' } ) ;
} ;
2023-08-31 14:02:09 +00:00
const isActive = ( item ) => {
return item . route ? router . resolve ( item . route ) . path === route . path : false ;
} ;
2023-02-28 08:29:30 +00:00
< \ / script >
< style scoped >
: : v - deep ( b ) {
display : block ;
}
: : v - deep ( . p - card - body ) {
padding : 2 rem ;
}
< / style > ` ,
pages : [
{
tabName : 'PersonalDemo' ,
content : `
< template >
< div class = "stepsdemo-content" >
< Card >
< template v -slot : title >
Personal Information
< / template >
< template v -slot : subtitle >
Enter your personal information
< / template >
< template v -slot : content >
< div class = "p-fluid" >
< div class = "field" >
< label for = "firstname" > Firstname < / label >
< InputText id = "firstname" v -model = " firstname " : class = "{'p-invalid': validationErrors.firstname && submitted}" / >
< small v-show ="validationErrors.firstname && submitted" class="p-error" > Firstname is required. < / small >
< / div >
< div class = "field" >
< label for = "lastname" > Lastname < / label >
< InputText id = "lastname" v -model = " lastname " : class = "{'p-invalid': validationErrors.lastname && submitted}" / >
< small v-show ="validationErrors.lastname && submitted" class="p-error" > Lastname is required. < / small >
< / div >
< div class = "field" >
< label for = "age" > Age < / label >
< InputNumber id = "age" v -model = " age " / >
< / div >
< / div >
< / template >
< template v -slot : footer >
< div class = "grid grid-nogutter justify-content-between" >
< i > < / i >
< Button label = "Next" @click ="nextPage()" icon = "pi pi-angle-right" iconPos = "right" / >
< / div >
< / template >
< / Card >
< / div >
< / template >
< script >
export default {
data ( ) {
return {
firstname : '' ,
lastname : '' ,
age : null ,
submitted : false ,
validationErrors : { }
}
} ,
methods : {
nextPage ( ) {
this . submitted = true ;
if ( this . validateForm ( ) ) {
this . $emit ( 'next-page' , { formData : { firstname : this . firstname , lastname : this . lastname , age : this . age } , pageIndex : 0 } ) ;
}
} ,
validateForm ( ) {
if ( ! this . firstname . trim ( ) )
this . validationErrors [ 'firstname' ] = true ;
else
delete this . validationErrors [ 'firstname' ] ;
if ( ! this . lastname . trim ( ) )
this . validationErrors [ 'lastname' ] = true ;
else
delete this . validationErrors [ 'lastname' ] ;
return ! Object . keys ( this . validationErrors ) . length ;
}
}
}
< \ / script >
`
} ,
{
tabName : 'SeatDemo' ,
content : `
< template >
< div class = "stepsdemo-content" >
< Card >
< template v -slot : title >
Seat Information
< / template >
< template v -slot : subtitle >
Choose your seat
< / template >
< template v -slot : content >
< div class = "p-fluid formgrid grid" >
< div class = "field col-12 md:col-6" >
< label for = "class" > Class < / label >
< Dropdown inputId = "class" v -model = " selectedClass " :options ="classes" @change ="setVagons($event)" optionLabel = "name" placeholder = "Select a Class" / >
< / div >
< div class = "field col-12 md:col-6" >
< label for = "lastname" > Wagon < / label >
< Dropdown inputId = "wagon" v -model = " selectedVagon " :options ="vagons" @change ="setSeats($event)" optionLabel = "vagon" placeholder = "Select a Vagon" / >
< / div >
< div class = "field col-12" >
< label for = "seat" > Seat < / label >
< Dropdown inputId = "seat" v -model = " selectedSeat " :options ="seats" optionLabel = "seat" placeholder = "Select a Seat" / >
< / div >
< / div >
< / template >
< template v -slot : footer >
< div class = "grid grid-nogutter justify-content-between" >
< Button label = "Back" @click ="prevPage()" icon = "pi pi-angle-left" / >
< Button label = "Next" @click ="nextPage()" icon = "pi pi-angle-right" iconPos = "right" / >
< / div >
< / template >
< / Card >
< / div >
< / template >
< script >
export default {
data ( ) {
return {
selectedClass : '' ,
classes : [
{ name : 'First Class' , code : 'A' , factor : 1 } ,
{ name : 'Second Class' , code : 'B' , factor : 2 } ,
{ name : 'Third Class' , code : 'C' , factor : 3 }
] ,
vagons : [ ] ,
selectedVagon : '' ,
seats : [ ] ,
selectedSeat : ''
}
} ,
methods : {
setVagons ( event ) {
if ( this . selectedClass && event . value ) {
this . vagons = [ ] ;
this . seats = [ ] ;
for ( let i = 1 ; i < 3 * event . value . factor ; i ++ ) {
this . vagons . push ( { vagon : i + event . value . code , type : event . value . name , factor : event . value . factor } ) ;
}
}
} ,
setSeats ( event ) {
if ( this . selectedVagon && event . value ) {
this . seats = [ ] ;
for ( let i = 1 ; i < 10 * event . value . factor ; i ++ ) {
this . seats . push ( { seat : i , type : event . value . type } ) ;
}
}
} ,
nextPage ( ) {
this . $emit ( 'next-page' , { formData : { class : this . selectedClass . name , vagon : this . selectedVagon . vagon , seat : this . selectedSeat . seat } , pageIndex : 1 } ) ;
} ,
prevPage ( ) {
this . $emit ( 'prev-page' , { pageIndex : 1 } ) ;
}
}
}
< \ / script >
`
} ,
{
tabName : 'PaymentDemo' ,
content : `
< template >
< div class = "stepsdemo-content" >
< Card >
< template v -slot : title >
Payment Information
< / template >
< template v -slot : subtitle >
Enter your card details
< / template >
< template v -slot : content >
< div class = "p-fluid formgrid grid" >
< div class = "field col-12" >
< label for = "class" > Card Holder Name < / label >
< InputText type = "text" v -model = " cardholderName " / >
< / div >
< div class = "field col-8" >
< label id = "number" for = "lastname" > Number < / label >
< InputMask id = "number" mask = "9999-9999-9999-9999" v -model = " cardholderNumber " / >
< / div >
< div class = "field col-2" >
< label id = "date" for = "date" > Date < / label >
< InputMask id = "date" mask = "99/99" v -model = " date " / >
< / div >
< div class = "field col-2" >
< label for = "cvv" > CVV < / label >
< InputMask id = "cvv" mask = "999" v -model = " cvv " / >
< / div >
< div class = "field-checkbox col-12" >
< Checkbox id = "remember" v -model = " remember " :binary ="true" / >
< label for = "remember" class = "p-checkbox-label" > Save credit card information for future < / label >
< / div >
< / div >
< / template >
< template v -slot : footer >
< div class = "grid grid-nogutter justify-content-between" >
< Button label = "Back" @click ="prevPage()" icon = "pi pi-angle-left" / >
< Button label = "Next" @click ="nextPage()" icon = "pi pi-angle-right" iconPos = "right" / >
< / div >
< / template >
< / Card >
< / div >
< / template >
< script >
export default {
data ( ) {
return {
cardholderName : '' ,
cardholderNumber : '' ,
date : '' ,
cvv : '' ,
remember : false
}
} ,
methods : {
nextPage ( ) {
this . $emit ( 'next-page' , { formData : { cardholderName : this . cardholderName , cardholderNumber : this . cardholderNumber , date : this . date , cvv : this . cvv } , pageIndex : 2 } ) ;
} ,
prevPage ( ) {
this . $emit ( 'prev-page' , { pageIndex : 2 } ) ;
}
}
}
< \ / script >
`
} ,
{
tabName : 'ConfirmationDemo' ,
content : `
< template >
< div class = "stepsdemo-content" >
< Card >
< template v -slot : title >
Confirmation
< / template >
< template v -slot : content >
< div class = "field col-12" >
< label for = "class" > Name < / label >
< b > { { formData . firstname ? formData . firstname : '-' } } { { formData . lastname ? formData . lastname : '-' } } < / b >
< / div >
< div class = "field col-12" >
< label for = "Age" > Age < / label >
< b > { { formData . age ? formData . age : '-' } } < / b >
< / div >
< div class = "field col-12" >
< label for = "Age" > Seat Class < / label >
< b > { { formData . class ? formData . class : '-' } } < / b >
< / div >
< div class = "field col-12" >
< label for = "Age" > Wagon Number < / label >
< b > { { formData . vagon ? formData . vagon : '-' } } < / b >
< / div >
< div class = "field col-12" >
< label for = "Age" > Seat < / label >
< b > { { formData . seat ? formData . seat : '-' } } < / b >
< / div >
< div class = "field col-12" >
< label for = "Age" > Cardholder Name < / label >
< b > { { formData . cardholderName ? formData . cardholderName : '-' } } < / b >
< / div >
< div class = "field col-12" >
< label for = "Age" > Card Number < / label >
< b > { { formData . cardholderNumber ? formData . cardholderNumber : '-' } } < / b >
< / div >
< div class = "field col-12" >
< label for = "Age" > Date < / label >
< b > { { formData . date ? formData . date : '-' } } < / b >
< / div >
< div class = "field col-12" >
< label for = "Age" > CVV < / label >
< b > { { formData . cvv && formData . cvv . length === 3 ? '**' + formData . cvv [ 2 ] : '-' } } < / b >
< / div >
< / template >
< template v -slot : footer >
< div class = "grid grid-nogutter justify-content-between" >
< Button label = "Back" @click ="prevPage()" icon = "pi pi-angle-left" / >
< Button label = "Complete" @click ="complete()" icon = "pi pi-check" iconPos = "right" class = "p-button-success" / >
< / div >
< / template >
< / Card >
< / div >
< / template >
< script >
export default {
props : {
formData : Object
} ,
methods : {
prevPage ( ) {
this . $emit ( 'prev-page' , { pageIndex : 3 } ) ;
} ,
complete ( ) {
this . $emit ( 'complete' ) ;
}
}
}
< \ / script >
`
}
]
}
} ;
} ,
methods : {
nextPage ( event ) {
for ( let field in event . formData ) {
this . formObject [ field ] = event . formData [ field ] ;
}
2023-10-16 12:11:16 +00:00
this . $router . push ( this . items [ event . pageIndex + 1 ] . route ) ;
2023-02-28 08:29:30 +00:00
} ,
prevPage ( event ) {
2023-10-16 12:11:16 +00:00
this . $router . push ( this . items [ event . pageIndex - 1 ] . route ) ;
2023-02-28 08:29:30 +00:00
} ,
complete ( ) {
this . $toast . add ( { severity : 'success' , summary : 'Order submitted' , detail : 'Dear, ' + this . formObject . firstname + ' ' + this . formObject . lastname + ' your order completed.' } ) ;
2023-08-31 14:02:09 +00:00
} ,
isActive ( item ) {
return item . route ? this . $router . resolve ( item . route ) . path === this . $route . path : false ;
2023-02-28 08:29:30 +00:00
}
}
} ;
< / script >