<template>
<FormulateForm
v-model="formData"
@submit="submitHandler"
>
<h2>Purchase your ticket(s) for FormulateConf 2020!</h2>
<FormulateInput
type="group"
repeatable="true"
name="attendees"
add-label="+ Add Attendee"
validation="required"
:validation-messages="{
required: 'You must purchase at least one ticket'
}"
class="attendee-details"
>
<FormulateInput
name="name"
label="Attendee Name"
validation="required"
help="First & last name please."
/>
<FormulateInput
name="email"
label="Attendee Email"
validation="^required|email"
help="Your ticket will be emailed to you."
/>
<FormulateInput
name="tier"
type="select"
label="Ticket Type"
value="basic"
validation="required"
help="Tickets are not upgradable."
:options="{
basic: 'Regular Ticket - $75',
plus: 'Executive Ticket - $100',
vip: 'Platinum Ticket - $250'
}"
/>
</FormulateInput>
<div class="payment-details">
<p>Your total payment will be: <strong>{{ total }}</strong></p>
<FormulateInput
name="payment_method"
type="radio"
validation="required"
:validation-messages="{
required: 'Please choose your payment method.'
}"
:options="{
paypal: 'PayPal',
credit: 'Credit Card'
}"
/>
</div>
<FormulateInput
type="submit"
name="Proceed to Payment"
/>
<pre v-html="formData" />
</FormulateForm>
</template>
<script>
export default {
data () {
return {
formData: {}
}
},
computed: {
total () {
if (this.formData && this.formData.attendees && this.formData.attendees.length) {
let cost = 0
this.formData.attendees.map((entry) => {
cost += this.getTicketCost(entry.tier)
})
return new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD'}).format(cost)
}
return '$0.00'
}
},
methods: {
submitHandler () {
alert('Tada! You would now be successfully directed to the next step...')
},
getTicketCost (ticket) {
console.log(ticket)
// this is only for demo front-end dislpay. Your application
// back-end would tally its own total for payment.
let cost = 0
switch (ticket) {
case 'basic':
cost = 75
break
case 'plus':
cost = 100
break
case 'vip':
cost = 250
break
}
return cost
}
}
}
</script>
<style lang="scss">
body {
min-height: 100vh;
padding: 2em;
display: flex;
align-items: center;
justify-content: center;
background: linear-gradient(to bottom right, springgreen, limegreen);
}
form {
display: flex;
flex-direction: column;
background-color: #fff;
border: 1px solid #999;
width: 90%;
max-width: 680px;
padding: 2.5em 2em;
border-radius: 0.3em;
box-shadow: 0.25em 0.15em 12em 0 rgba(#000, 0.25);
* {
box-sizing: border-box;
}
h2 {
margin-top: 0;
color: #555;
}
}
.attendee-details .formulate-input-group-repeatable {
@media (min-width: 600px) {
display: flex;
justify-content: space-between;
}
& > .formulate-input {
@media (min-width: 600px) {
margin-bottom: 0;
max-width: 32%;
}
}
}
.payment-details {
margin-bottom: 1em
}
pre {
background-color: darkslategray;
color: white;
padding: 1em;
}
</style>