<template>
  <FormulateForm @submit="submitHandler">
    <h2>Purchase your ticket for FormulateConf 2020!</h2>
    <div 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
        v-model="tier"
        name="tier"
        type="select"
        label="Ticket Type"
        validation="required"
        help="Tickets are not upgradable."
        :options="{
          basic: 'Regular Ticket - $75',
          plus: 'Executive Ticket - $100',
          vip: 'Platinum Ticket - $250'
        }"
      />
    </div>
    <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"
    />
  </FormulateForm>
</template>

<script>
export default {
  data () {
    return {
      tier: 'basic'
    }
  },
  computed: {
    total () {
      if (this.tier) {
        const cost = this.getTicketCost(this.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) {
      // 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: 600px;
  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 {
  @media (min-width: 600px) {
    display: flex;
    justify-content: space-between;
  }
  
  & > .formulate-input {
    @media (min-width: 600px) {
      max-width: 32%;
    }
  }
}

.payment-details {
  margin-bottom: 1em
}
</style>

External CSS

  1. https://s3-us-west-2.amazonaws.com/s.cdpn.io/15253/codepen-2.3.0-snow.min.css

External JavaScript

  1. https://s3-us-west-2.amazonaws.com/s.cdpn.io/15253/codepen-2.3.0-bootstrap.js