App
Source
<template>
<div class="form-group" v-bind:class="{ 'has-error': errorMsg }">
<label class="form-label" v-bind:for="label + '-date'">{{ label }}</label
><input
v-bind:id="label + '-date'"
class="form-input"
type="text"
v-bind:value="date"
v-on:input="e => onSetDate(e.target.value)"
v-bind:disabled="disabled || false"
/>
<p v-if="errorMsg" class="form-input-hint">{{ errorMsg }}</p>
</div>
</template>
<script>
export default {
props: ["errorMsg", "label", "date", "disabled", "onSetDate"]
};
</script>
<template>
<TripType v-on:setTripType="newTripType => (tripType = newTripType)" />
<DateEntry
label="Departing"
v-bind:date="departing"
v-bind:errorMsg="departingError"
v-on:setDate="newDate => (departing = newDate)"
/>
<DateEntry
label="Returning"
v-bind:date="returning"
v-bind:errorMsg="returningError"
v-on:setDate="newDate => (returning = newDate)"
v-bind:disabled="tripType == oneWayFlight"
/>
<div class="form-group">
<button
class="btn btn-primary"
v-on:click="bookFlight"
v-bind:disabled="isBookDisabled"
>
book
</button>
</div>
</template>
<script>
import { today, validateDate } from "../../../../lib/date";
import TripType from "./TripType.vue";
import DateEntry from "./DateEntry.vue";
const oneWayFlight = "one-way";
const returnFlight = "return";
function getErrorMessage(date) {
try {
validateDate(date);
return null;
} catch (error) {
return error.message;
}
}
export default {
components: { TripType, DateEntry },
data() {
let currentDate = today();
return {
oneWayFlight,
returnFlight,
tripType: oneWayFlight,
departing: currentDate,
returning: currentDate
};
},
methods: {
bookFlight() {
const type = this.tripType == returnFlight ? "return" : "one-way";
let message = `You have booked a ${type} flight, leaving ${this.departing}`;
if (type === "return") {
message += ` and returning ${this.returning}`;
}
alert(message);
}
},
computed: {
departingError() {
return getErrorMessage(this.departing);
},
returningError() {
let returningError = getErrorMessage(this.returning);
if (
this.departingError == null &&
returningError == null &&
this.tripType == returnFlight &&
this.returning < this.departing
) {
returningError = "Returning date must be on or after departing date.";
}
return returningError;
},
isBookDisabled() {
return this.departingError || this.returningError;
}
}
};
</script>
<template>
<div class="form-group">
<label class="form-label" for="trip-type">Trip type</label
><select
id="trip-type"
class="form-select"
v-on:input="e => onSetTripType(e.target.value)"
>
<option value="one-way">one-way flight</option>
<option value="return">return flight</option>
</select>
</div>
</template>
<script>
export default {
props: ["onSetTripType"]
};
</script>
import { createApp } from "vue";
import FlightBooker from "./FlightBooker.vue";
createApp(FlightBooker).mount("#app");