UNPKG

5.96 kBPlain TextView Raw
1<template>
2 <form @submit.prevent="send"
3 v-form="contactForm"
4 class="borderRadius25 marginRightAuto marginLeftAuto displayFlex
5 bgWhisper">
6
7 <div class="flex1 padding30">
8
9 <!-- Name field -->
10 <div class="marginBottom30 widthTwelve">
11
12 <div class="marginBottom10">
13 <label for="name" class="colorMidGray fontSize14">
14 Your name
15 </label>
16 </div>
17
18 <input id="name"
19 type="text"
20 class="inputText widthTwelve"
21 v-model="contactData.name"
22 pattern="[A-Za-z\s'\-]+"
23 minlength="3"
24 required>
25
26 <div v-if="contactForm.$wasSubmitted"
27 class="marginTop12 widthTwelve colorRed fontSize14">
28 <div v-if="contactForm.name.valueMissing">
29 Name is required.
30 </div>
31 <div v-if="contactForm.name.tooShort">
32 Please enter your first and last name.
33 </div>
34 <div v-if="contactForm.name.patternMismatch">
35 Please use only letters, spaces, dashes, and apostrophes.
36 </div>
37 </div>
38
39 </div>
40
41 <!-- Email field -->
42 <div class="marginBottom30 widthTwelve">
43
44 <div class="marginBottom10">
45 <label for="email" class="colorMidGray fontSize14">
46 Your email address
47 </label>
48 </div>
49
50 <input id="email"
51 type="email"
52 class="inputText widthTwelve"
53 v-model="contactData.email"
54 required>
55
56 <div v-if="contactForm.$wasSubmitted"
57 class="marginTop12 widthTwelve colorRed fontSize14">
58 <div v-if="contactForm.email.valueMissing">
59 Email is required.
60 </div>
61 <div v-if="contactForm.email.typeMismatch">
62 Please enter a valid email address.
63 </div>
64 </div>
65
66 </div>
67
68 <!-- Phone field -->
69 <div class="marginBottom30 widthTwelve">
70
71 <div class="marginBottom10">
72 <label for="phone" class="colorMidGray fontSize14">
73 Your phone number
74 </label>
75 </div>
76
77 <input id="phone"
78 type="text"
79 class="inputText widthTwelve"
80 v-model="contactData.phone"
81 pattern="^(\+\d{1,2}\s)?\(?\d{3}\)?[\s.-]?\d{3}[\s.-]?\d{4}$"
82 required>
83
84 <div v-if="contactForm.$wasSubmitted"
85 class="marginTop12 widthTwelve colorRed fontSize14">
86 <div v-if="contactForm.phone.valueMissing">
87 Phone is required.
88 </div>
89 <div v-if="contactForm.phone.patternMismatch">
90 Please use only numbers, spaces, dashes, and parenthesis.
91 </div>
92 </div>
93
94 </div>
95
96 <!-- Project field -->
97 <div class="widthTwelve">
98
99 <div class="marginBottom10">
100 <label for="project" class="colorMidGray fontSize14">
101 Your company/project name
102 </label>
103 </div>
104
105 <input id="project"
106 type="text"
107 class="inputText widthTwelve"
108 v-model="contactData.project">
109
110 </div>
111
112 </div>
113
114 <div class="flex1 padding30">
115
116 <!-- Description field -->
117 <div class="marginBottom30">
118
119 <div class="marginBottom10">
120 <label for="description" class="colorMidGray fontSize14">
121 How can we help you?
122 </label>
123 </div>
124
125 <textarea id="description"
126 class="textArea widthTwelve resizeVertical"
127 rows="13"
128 @input="hasOneWordValidator"
129 v-model="contactData.description"
130 required>
131 </textarea>
132
133 <div v-if="contactForm.$wasSubmitted"
134 class="marginTop12 widthTwelve colorRed fontSize14">
135 <div v-if="contactForm.description.valueMissing">
136 Description is required.
137 </div>
138 <div v-if="contactForm.description.customError">
139 {{ contactForm.description.customMessage }}
140 </div>
141 </div>
142
143 </div>
144
145 <!-- Success message -->
146 <transition name="fade">
147 <div v-if="formSent" class="colorOlive fontSize18 textCenter">
148 Thanks! We'll be in touch soon.
149 </div>
150 </transition>
151
152 <!-- Form buttons -->
153 <div v-if="!formSent" class="textRight fontSize20">
154
155 <!-- Reset button -->
156 <button type="reset"
157 class="button circular width140 height50 marginRight30 bgGray">
158 <span class="verticalMiddle">Reset</span>
159 <reset-icon></reset-icon>
160 </button>
161
162 <!-- Submit button -->
163 <button type="submit"
164 class="button circular width140 height50"
165 :class="{ 'disabled': contactForm.$isInvalid }">
166 <span class="verticalMiddle">Send</span>
167 <plane-icon></plane-icon>
168 </button>
169
170 </div>
171
172 </div>
173
174 </form>
175</template>
176
177<script>
178 import VueForm from '../../dist/vueform'
179 import ResetIcon from './ResetIcon'
180 import PlaneIcon from './PlaneIcon'
181
182 export default {
183 name: 'ContactForm',
184 components: { ResetIcon, PlaneIcon },
185 data () {
186 return {
187 formSent: false,
188 contactData: {},
189 contactForm: new VueForm()
190 }
191 },
192 methods: {
193 send () {
194 if (this.contactForm.$isValid) {
195 console.log('VALID')
196 this.formSent = true
197 } else {
198 console.log('INVALID')
199 }
200 },
201 hasOneWordValidator ({ target }) {
202 const id = target.getAttribute('id')
203 if (target.value.match(/\w+/)) {
204 this.contactForm.$setCustomValidity(id)
205 } else {
206 const errorMessage = 'Description must contain at least one word.'
207 this.contactForm.$setCustomValidity(id, errorMessage)
208 }
209 }
210 }
211 }
212</script>