2 let breadcrumbs = await _require('/_lib/breadcrumbs.jst')
3 let fa_envelope = await env.site.get_min_svg('/_svg/fa_envelope.svg')
4 let get_placeholder = await _require('/_lib/get_placeholder.jst')
5 let get_session = await _require('/_lib/get_session.jst')
6 let icon_cross = await env.site.get_min_svg('/_svg/icon_cross.svg')
7 let icon_tick = await env.site.get_min_svg('/_svg/icon_tick.svg')
8 let navbar = await _require('/_lib/navbar.jst')
10 // preload draft details if any
11 let transaction = await env.site.database.Transaction()
15 let root = await transaction.get({})
16 let session = await get_session(env, root)
18 placeholder = await get_placeholder(env, session)
20 contact_draft = await session.get_json('contact_draft')
21 if (contact_draft === undefined || env.now >= contact_draft.expires)
26 transaction.rollback()
36 await breadcrumbs(env, _out)
38 p {'Do you require more information, or assistance with integrating the projects on this site? We’d love to hear from you.'}
44 label.form-label(for="given-names") {'Given names *'}
45 input.form-control#given-names(type="text" value=contact_draft ? contact_draft.given_names : '' placeholder=placeholder.given_names required maxlength=256) {}
46 div.invalid-feedback {'Please enter a name we can address you by.'}
51 label.form-label(for="family-name") {'Family name'}
52 input.form-control#family-name(type="text" value=contact_draft ? contact_draft.family_name : '' placeholder=placeholder.family_name maxlength=256) {}
59 label.form-label(for="company") {'Company'}
60 input.form-control#company(type="company" value=contact_draft ? contact_draft.company : '' placeholder=placeholder.company maxlength=256) {}
65 label.form-label(for="email") {'Email *'}
66 input.form-control#email(type="email" value=contact_draft ? contact_draft.email : '' placeholder=placeholder.email required maxlength=256) {}
67 div.invalid-feedback {'Please enter an email address we can contact you on.'}
74 label.form-label(for="message1") {'Message *'}
75 textarea.form-control#message1(placeholder="I would like to..." required rows=6 maxlength=65536) {
77 `${contact_draft.message}`
79 div.invalid-feedback {'Please let us know your application or question.'}
85 if (contact_draft !== null)
86 button.btn.btn-success#send-enquiry(type="button") {
87 div.icon24-outer.mr-2#icon {
88 div.icon24-inner {_out.push(fa_envelope)}
90 div.icon24-outer.mr-2#tick(hidden) {
91 div.icon24-inner {_out.push(icon_tick)}
93 div.icon24-outer.mr-2#cross(hidden) {
94 div.icon24-inner {_out.push(icon_cross)}
96 div.icon24-outer.mr-2#spinner(hidden) {
98 div.spinner-border.spinner-border-sm(role="status") {}
104 button.btn.btn-success#send-enquiry(type="button" disabled) {
105 div.icon24-outer.mr-2#icon {
106 div.icon24-inner {_out.push(fa_envelope)}
108 div.icon24-outer.mr-2#tick(hidden) {
109 div.icon24-inner {_out.push(icon_tick)}
111 div.icon24-outer.mr-2#cross(hidden) {
112 div.icon24-inner {_out.push(icon_cross)}
114 div.icon24-outer.mr-2#spinner(hidden) {
116 div.spinner-border.spinner-border-sm(role="status") {}
122 p.'mt-3'.mb-0#message(hidden) {}
124 p.text-muted.mt-3 {'* These fields are required.'}
128 //script(src="/js/utils.js") {}
131 document.addEventListener(
134 let id_company = document.getElementById('company')
135 let id_cross = document.getElementById('cross')
136 let id_email = document.getElementById('email')
137 let id_family_name = document.getElementById('family-name')
138 let id_form = document.getElementById('form')
139 let id_given_names = document.getElementById('given-names')
140 let id_icon = document.getElementById('icon')
141 let id_message = document.getElementById('message')
142 let id_message1 = document.getElementById('message1')
143 let id_send_enquiry = document.getElementById('send-enquiry')
144 let id_spinner = document.getElementById('spinner')
145 let id_tick = document.getElementById('tick')
147 let input_semaphore = new BinarySemaphore(false)
151 await input_semaphore.acquire()
152 await new Promise(resolve => setTimeout(resolve, 3000))
153 input_semaphore.try_acquire()
155 '/api/contact/set_draft.json',
156 id_given_names.value.length === 0 &&
157 id_family_name.value.length === 0 &&
158 id_company.value.length === 0 &&
159 id_email.value.length === 0 &&
160 id_message1.value.length === 0 ?
163 given_names: id_given_names.value.slice(0, 256),
164 family_name: id_family_name.value.slice(0, 256),
165 company: id_company.value.slice(0, 256),
166 email: id_email.value.slice(0, 256).toLowerCase(),
167 message: id_message1.value.slice(0, 65536)
172 )() // ignore returned promise (start thread)
175 input_semaphore.release()
177 id_send_enquiry.disabled =
178 id_given_names.value.length === 0 &&
179 id_family_name.value.length === 0 &&
180 id_company.value.length === 0 &&
181 id_email.value.length === 0 &&
182 id_message1.value.length === 0
183 id_icon.hidden = false
184 id_tick.hidden = true
185 id_cross.hidden = true
186 id_spinner.hidden = true
187 id_message.hidden = true
190 id_given_names.addEventListener('input', edited)
191 id_family_name.addEventListener('input', edited)
192 id_company.addEventListener('input', edited)
193 id_email.addEventListener('input', edited)
194 id_message1.addEventListener('input', edited)
196 id_send_enquiry.addEventListener(
199 id_icon.hidden = false
200 id_tick.hidden = true
201 id_cross.hidden = true
202 id_spinner.hidden = true
203 // the below causes an ugly flicker, so just keep the message
204 //id_message.hidden = true
206 if (!id_form.checkValidity()) {
207 id_form.classList.add('was-validated');
209 id_icon.hidden = true
210 id_cross.hidden = false
213 id_form.classList.remove('was-validated');
216 given_names: id_given_names.value.slice(0, 256),
217 family_name: id_family_name.value.slice(0, 256),
218 company: id_company.value.slice(0, 256),
219 email: id_email.value.slice(0, 256).toLowerCase(),
220 message: id_message1.value.slice(0, 65536)
223 id_icon.hidden = true
224 id_spinner.hidden = false
227 '/api/contact/send_enquiry.json',
232 let problem = Problem.from(error)
234 id_cross.hidden = false
235 id_spinner.hidden = true
237 id_message.textContent = problem.detail
238 //id_message.classList.remove('text-success')
239 id_message.classList.add('text-danger')
240 id_message.hidden = false
243 id_tick.hidden = false
244 id_spinner.hidden = true
245 id_message.textContent = 'We have received your enquiry. We will be in touch as soon as possible.'
246 //id_message.classList.add('text-success')
247 id_message.classList.remove('text-danger')
248 id_message.hidden = false