<template>
<FormulateForm
id="basic-signup-form"
@submit="submitHandler"
>
<h2>Sign up for FormulateConf 2020 in Charlottesville, VA</h2>
<FormulateInput
name="username"
label="Username"
validation="^required|^min:4,length|^max:8,length|^alpha:latin|unique"
:validation-rules="{ unique: checkUsername }"
:validation-messages="{ unique: 'Sorry, that username is already taken' }"
help="Usernames must be lowercase and between 4-8 characters in length. (psst, try 'bossman' for a failing username)"
/>
<FormulateInput
name="email"
label="Email"
type="email"
validation="^required|email"
/>
<FormulateInput
name="bio"
label="Bio"
type="textarea"
validation="required"
help="Help others get to know you a bit."
/>
<FormulateInput
name="password"
label="Password"
validation="^required|min:6,length"
help="Your password must be at least 6 characters long."
autocomplete="off"
/>
<FormulateInput
name="password_confirm"
label="Confirm Password"
validation="^required|^min:6,length|confirm"
validation-name="Password"
autocomplete="off"
/>
<FormulateInput
type="submit"
name="Register!"
/>
</FormulateForm>
</template>
<script>
export default {
data () {
return {
takenNamePartials: [
'dawg',
'js',
'boss',
'oy'
]
}
},
methods: {
submitHandler () {
alert('Thank you for signing up!')
},
async checkUsername ({ value }) {
// check to see if the username contains any of
// our partial matches to simulate taken usernames.
// wrap it in a promise and timeout to simulate an xhr request.
let match = false
await new Promise((resolve) => {
setTimeout(() => {
// use .find() to check for matches and bail on first success
match = this.takenNamePartials.find(partial => value.includes(partial))
resolve()
}, 2000)
})
// return the cooreced boolean value of !match
return !!!match
}
}
}
</script>
<style lang="scss">
body {
min-height: 100vh;
padding: 2em;
display: flex;
align-items: center;
justify-content: center;
background: linear-gradient(to bottom right, cyan, magenta);
}
form {
display: flex;
flex-direction: column;
background-color: #fff;
border: 1px solid #999;
width: 90%;
max-width: 320px;
padding: 3em 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;
}
}
.formulate-input[data-classification=button] {
display: flex;
.formulate-input-wrapper {
margin: auto;
}
button {
appearance: none;
border: 1px solid deeppink;
background-color: magenta;
font-weight: bold;
color: #fff;
text-transform: uppercase;
padding: 1em 1.5em;
border-radius: 0.5em;
margin: 1em auto 0 auto;
&:active,
&:focus {
border: 1px solid deeppink;
background-color: magenta;
color: #fff;
}
}
}
</style>