1/* Compiled from forms.jsx â DO NOT EDIT BY HAND. Edit the .jsx and rebuild (see BUILD.md). */ 2(function () { 3/* global React */ 4/* ============================================================ 5 EWA 2026, Dynamic form engine 6 Renders a form from a field schema (editable in WordPress under 7 EWA Content), so fields and field types can be changed without code. 8 9 Field schema (array of objects): 10 { name, label, type, required, placeholder, options, width, help, 11 condField, condValues } 12 type: text | email | tel | number | url | date | textarea | select 13 | radio | checkboxes (pick many) | checkbox (single opt-in) 14 | consent (alias of checkbox) | file (stores "name (size KB)") 15 options: array of strings (select / radio / checkboxes) OR newline-separated 16 width: 'full'/'100' | 'half'/'50'/'33' (textarea/select default to full) 17 18 PROPS (beyond fields/formId): heading, intro, submitLabel, successTitleHtml, 19 successBody, backHref/backLabel, onDone(payload), noSuccess (parent renders 20 its own success screen), persistKey (draft auto-saved to localStorage and 21 cleared on submit), reviewStep (adds a check-your-answers screen before 22 the real submit; reviewLabel overrides âContinue to Reviewâ), plus 23 onReviewingChange(bool) + editSignal (bump the number to force back to 24 edit mode â lets a parent stepper control the review stage). 25 26 CONDITIONAL FIELDS 27 A field with condField only renders when the field with that id/name 28 has an answer. condValues (comma-separated, case-insensitive) narrows 29 it to specific answers â e.g. condField "role", condValues "Speaker, 30 Performer". Hidden fields are skipped by validation and excluded from 31 the submitted payload. 32 ============================================================ */ 33(function () { 34 const { 35 useState, 36 useEffect 37 } = React; 38 const DFArr = () => /*#__PURE__*/React.createElement("span", { 39 className: "btn-arrow" 40 }, /*#__PURE__*/React.createElement("svg", { 41 width: "10", 42 height: "10", 43 viewBox: "0 0 10 10", 44 fill: "none" 45 }, /*#__PURE__*/React.createElement("path", { 46 d: "M2 8L8 2M8 2H3M8 2V7", 47 stroke: "currentColor", 48 strokeWidth: "1.6", 49 strokeLinecap: "round" 50 }))); 51 const EMAIL_RE = /.+@.+\..+/; 52 const labelSlug = s => String(s || '').toLowerCase().replace(/<[^>]+>/g, ' ').replace(/[^a-z0-9]+/g, '_').replace(/(^_+|_+$)/g, '').slice(0, 40); 53 const keyOf = (f, i) => f && (f.name || f.id) ? f.name || f.id : labelSlug(f && f.label) || 'field_' + i; 54 const optVal = o => { 55 if (o == null) return ''; 56 if (typeof o === 'object') { 57 const v = o.opt != null ? o.opt : o.option != null ? o.option : o.label != null ? o.label : o.value != null ? o.value : ''; 58 return String(v == null ? '' : v); 59 } 60 return String(o); 61 }; 62 const optsOf = f => (Array.isArray(f.options) ? f.options : typeof f.options === 'string' ? f.options.split(/\n|,/) : []).map(optVal).map(s => s.trim()).filter(Boolean); 63 const isCheck = t => t === 'checkbox' || t === 'consent'; 64 const isMulti = t => t === 'checkboxes'; 65 66 /* ---- conditional visibility ---- */ 67 const condValsOf = f => String(f.condValues || '').split(/[,|]/).map(s => s.trim().toLowerCase()).filter(Boolean); 68 function fieldVisible(f, form) { 69 if (!f || !f.condField) return true; 70 const v = form[f.condField]; 71 const vals = condValsOf(f); 72 const answered = Array.isArray(v) ? v.length > 0 : typeof v === 'boolean' ? v : !!(v && String(v).trim()); 73 if (!vals.length) return answered; // blank = "has any answer" 74 if (!answered) return false; 75 const match = x => vals.indexOf(String(x).trim().toLowerCase()) >= 0; 76 if (Array.isArray(v)) return v.some(match); 77 if (typeof v === 'boolean') return v && (vals.indexOf('yes') >= 0 || vals.indexOf('true') >= 0 || vals.indexOf('1') >= 0 || vals.indexOf('checked') >= 0); 78 return match(v); 79 } 80 function Field({ 81 f, 82 id, 83 wrapId, 84 value, 85 onChange, 86 err, 87 forceFull 88 }) { 89 const req = f.required ? /*#__PURE__*/React.createElement("span", { 90 className: "req" 91 }, "*") : null; 92 const ph = f.placeholder || ''; 93 const errEl = err ? /*#__PURE__*/React.createElement("span", { 94 className: "ap-err", 95 role: "alert" 96 }, err) : null; 97 const errCls = err ? ' is-error' : ''; 98 if (isCheck(f.type)) { 99 return /*#__PURE__*/React.createElement("div", { 100 className: 'ap-consent ap-field full' + errCls, 101 id: wrapId 102 }, /*#__PURE__*/React.createElement("input", { 103 id: id, 104 type: "checkbox", 105 checked: !!value, 106 onChange: e => onChange(e.target.checked) 107 }), /*#__PURE__*/React.createElement("label", { 108 htmlFor: id 109 }, /*#__PURE__*/React.createElement("span", { 110 dangerouslySetInnerHTML: { 111 __html: f.label 112 } 113 }), req), errEl); 114 } 115 if (f.type === 'radio') { 116 return /*#__PURE__*/React.createElement("div", { 117 className: 'ap-field full' + errCls, 118 id: wrapId 119 }, /*#__PURE__*/React.createElement("label", null, f.label, req), /*#__PURE__*/React.createElement("div", { 120 className: "df-radio-row" 121 }, optsOf(f).map(o => /*#__PURE__*/React.createElement("label", { 122 className: 'df-radio' + (value === o ? ' is-on' : ''), 123 key: o 124 }, /*#__PURE__*/React.createElement("input", { 125 type: "radio", 126 name: id, 127 value: o, 128 checked: value === o, 129 onChange: () =>
129 onChange(o) 130 }), /*#__PURE__*/React.createElement("span", null, o)))), f.help ? /*#__PURE__*/React.createElement("span", { 131 className: "df-help" 132 }, f.help) : null, errEl); 133 } 134 if (isMulti(f.type)) { 135 const cur = Array.isArray(value) ? value : []; 136 const toggle = o => onChange(cur.indexOf(o) >= 0 ? cur.filter(x => x !== o) : cur.concat([o])); 137 return /*#__PURE__*/React.createElement("div", { 138 className: 'ap-field full' + errCls, 139 id: wrapId 140 }, /*#__PURE__*/React.createElement("label", null, f.label, req), /*#__PURE__*/React.createElement("div", { 141 className: "df-radio-row" 142 }, optsOf(f).map(o => /*#__PURE__*/React.createElement("label", { 143 className: 'df-radio' + (cur.indexOf(o) >= 0 ? ' is-on' : ''), 144 key: o 145 }, /*#__PURE__*/React.createElement("input", { 146 type: "checkbox", 147 value: o, 148 checked: cur.indexOf(o) >= 0, 149 onChange: () => toggle(o) 150 }), /*#__PURE__*/React.createElement("span", null, o)))), f.help ? /*#__PURE__*/React.createElement("span", { 151 className: "df-help" 152 }, f.help) : null, errEl); 153 } 154 if (f.type === 'file') { 155 const pick = e => { 156 const file = e.target.files && e.target.files[0]; 157 onChange(file ? file.name + ' (' + Math.max(1, Math.round(file.size / 1024)) + ' KB)' : ''); 158 }; 159 return /*#__PURE__*/React.createElement("div", { 160 className: 'ap-field full' + errCls, 161 id: wrapId 162 }, /*#__PURE__*/React.createElement("label", null, f.label, req), /*#__PURE__*/React.createElement("label", { 163 className: 'df-file' + (value ? ' has-file' : '') + errCls 164 }, /*#__PURE__*/React.createElement("input", { 165 id: id, 166 type: "file", 167 onChange: pick 168 }), /*#__PURE__*/React.createElement("span", { 169 className: "df-file-ic", 170 "aria-hidden": "true" 171 }, /*#__PURE__*/React.createElement("svg", { 172 width: "15", 173 height: "15",
174 viewBox: "0 0 16 16", 175 fill: "none" 176 }, /*#__PURE__*/React.createElement("path", { 177 d: "M8 11V3m0 0L5 6m3-3l3 3M3 13h10", 178 stroke: "currentColor", 179 strokeWidth: "1.6", 180 strokeLinecap: "round", 181 strokeLinejoin: "round" 182 }))), /*#__PURE__*/React.createElement("span", { 183 className: "df-file-txt" 184 }, value || f.placeholder || 'Choose a file\u2026'), /*#__PURE__*/React.createElement("span", { 185 className: "df-file-btn" 186 }, value ? 'Replace' : 'Browse')), f.help ? /*#__PURE__*/React.createElement("span", { 187 className: "df-help" 188 }, f.help) : null, errEl); 189 } 190 const w = String(f.width == null ? '' : f.width); 191 const wide = forceFull || w === 'full' || w === '100' || w !== '50' && w !== '33' && w !== 'half' && (f.type === 'textarea' || f.type === 'select'); 192 let input; 193 if (f.type === 'textarea') { 194 input = /*#__PURE__*/React.createElement("textarea", { 195 id: id, 196 className: "ap-textarea", 197 value: value || '', 198 onChange: e => onChange(e.target.value), 199 placeholder: ph 200 }); 201 } else if (f.type === 'select') { 202 input = /*#__PURE__*/React.createElement("select", { 203 id: id, 204 className: "ap-select", 205 value: value || '', 206 onChange: e => onChange(e.target.value) 207 }, /*#__PURE__*/React.createElement("option", { 208 value: "" 209 }, ph || 'Selectâ¦'), optsOf(f).map(o => /*#__PURE__*/React.createElement("option", { 210 key: o, 211 value: o 212 }, o))); 213 } else { 214 input = /*#__PURE__*/React.createElement("input", { 215 id: id, 216 className: "ap-input", 217 type: f.type || 'text', 218 value: value || '', 219 onChange: e => onChange(e.target.value), 220 placeholder: ph 221 }); 222 } 223 return /*#__PURE__*/React.createElement("div", { 224 className: 'ap-field' + (wide ? ' full' : '') + errCls, 225 id: wrapId 226 }, /*#__PURE__*/React.createElement("label", null, f.label, req), input, f.help ? /*#__PURE__*/React.createElement("span", { 227 className: "df-help" 228 }, f.help) : null, errEl); 229 } 230 /* Stable per-draft id (survives reloads) for abandoned-application capture. */ 231 function draftKeyFor(persistKey) { 232 let k = ''; 233 try { 234 k = localStorage.getItem(persistKey + ':k') || ''; 235 } catch (e) {} 236 if (!k) { 237 k = (Math.random().toString(36).slice(2, 10) + Date.now().toString(36)).slice(0, 20); 238 try { 239 localStorage.setItem(persistKey + ':k', k); 240 } catch (e) {} 241 } 242 return k; 243 } 244 245 function DynamicForm(props) { 246 const fields = Array.isArray(props.fields) ? props.fields : []; 247 const formId = props.formId || 'ewa_form'; 248 const [form, setForm] = useState(() => { 249 const o = {}; 250 fields.forEach((f, i) => { 251 o[keyOf(f, i)] = isCheck(f.type) ? false : isMulti(f.type) ? [] : ''; 252 }); 253 // Draft restore â so a refresh mid-application never loses work. 254 if (props.persistKey) { 255 try { 256 const raw = localStorage.getItem(props.persistKey); 257 if (raw) { 258 const d = JSON.parse(raw); 259 Object.keys(o).forEach(k => { 260 if (d && d[k] !== undefined) o[k] = d[k]; 261 }); 262 } 263 } catch (e) {} 264 } 265 return o; 266 }); 267 const [done, setDone] = useState(false); 268 const [reviewing, setReviewing] = useState(false); 269 const [errors, setErrors] = useState({}); 270 const [hp, setHp] = useState(''); // honeypot â humans never see or fill it 271 const set = (k, v) => { 272 setForm(s => ({ 273 ...s, 274 [k]: v 275 })); 276 setErrors(er => er[k] ? Object.assign({}, er, { 277 [k]: '' 278 }) : er); 279 }; 280 useEffect(() => { 281 if (!props.persistKey || done) return; 282 try { 283 localStorage.setItem(props.persistKey, JSON.stringify(form)); 284 } catch (e) {} 285 }, [form, done]); 286 /* External prefill (contact route cards pre-select the enquiry type). */ 287 useEffect(() => { 288 const h = e => { 289 const d = e && e.detail || {}; 290 setForm(s => { 291 const n = Object.assign({}, s); 292 fields.forEach((f, i) => { if (f && f.name && d[f.name] !== undefined) n[keyOf(f, i)] = d[f.name]; }); 293 return n; 294 }); 295 }; 296 window.addEventListener('ewa:prefill', h); 297 return () => window.removeEventListener('ewa:prefill', h); 298 }, []); 299 /* Abandoned-application capture: once a valid email is typed on a 300 persistKey form, snapshot progress to the server (debounced; final 301 flush on tab-hide) so the team sees drop-offs and the 30-minute 302 resume reminder can fire. No-op without CMS.saveDraft. */ 303 useEffect(() => { 304 if (!props.persistKey || done || !(window.CMS && window.CMS.saveDraft)) return; 305 const snap = () => { 306 const ei = fields.findIndex(f => f && f.type === 'email'); 307 const email = ei >= 0 ? String(form[keyOf(fields[ei], ei)] || '').trim() : ''; 308 if (!/^\S+@\S+\.\S+$/.test(email)) return null; 309 const vis = fields.filter(f => fieldVisible(f, form)); 310 const data = {}; 311 let nf = 0; 312 vis.forEach(f => {
313 const k = keyOf(f, fields.indexOf(f)); 314 const v = form[k]; 315 const has = isCheck(f.type) ? !!v : isMulti(f.type) ? Array.isArray(v) && v.length > 0 : !!(v && String(v).trim()); 316 if (has) { 317 nf++; 318 data[k] = Array.isArray(v) ? v.slice(0, 12) : typeof v === 'boolean' ? v : String(v).slice(0, 300); 319 } 320 }); 321 const nm = ['firstName', 'fullName', 'name', 'contactName'].map(k => form[k]).filter(v => v && String(v).trim())[0] || ''; 322 return { 323 key: draftKeyFor(props.persistKey), 324 email: email, 325 name: String(nm).slice(0, 80), 326 step: reviewing ? 'review' : 'form', 327 filled: nf, 328 total: vis.length, 329 pg: location.pathname, 330 data: data 331 }; 332 }; 333 const send = beacon => { 334 const d = snap(); 335 if (d) window.CMS.saveDraft(formId, d, beacon); 336 }; 337 const t = setTimeout(() => send(false), 5000); 338 const onHide = () => { 339 if (document.visibilityState === 'hidden') send(true); 340 }; 341 document.addEventListener('visibilitychange', onHide); 342 return () => { 343 clearTimeout(t); 344 document.removeEventListener('visibilitychange', onHide); 345 }; 346 }, [form, reviewing, done]); 347 useEffect(() => { 348 if (props.onReviewingChange) props.onReviewingChange(reviewing); 349 }, [reviewing]); 350 useEffect(() => { 351 if (props.editSignal) setReviewing(false); 352 }, [props.editSignal]); 353 useEffect(() => { 354 if (!props.reviewStep && reviewing) setReviewing(false); 355 }, [props.reviewStep]); 356 const shown = fields.filter(f => fieldVisible(f, form)); 357 const filled = (f, i) => { 358 const v = form[keyOf(f, i)]; 359 if (isCheck(f.type)) return !!v; 360 if (isMulti(f.type)) return Array.isArray(v) && v.length > 0; 361 if (f.type === 'email') return EMAIL_RE.test(v || ''); 362 return !!(v && String(v).trim()); 363 }; 364 /* Human error message for one field ('' = fine). Required first, then 365 format checks (an optional-but-filled email/link must still be valid). */ 366 const coerceUrl = s => { 367 let t = String(s == null ? '' : s).trim(); 368 if (!t) return t; 369 if (!/^https?:\/\//i.test(t)) t = 'https://' + t; 370 try { 371 new URL(t); 372 return /\./.test(t.replace(/^https?:\/\//i, '')) ? t : null; 373 } catch (e) { 374 return null; 375 } 376 }; 377 const errOf = (f, i) => { 378 const v = form[keyOf(f, i)]; 379 if (f.required && !filled(f, i)) { 380 if (isCheck(f.type)) return 'Please tick this box to continue.'; 381 if (isMulti(f.type)) return 'Please pick at least one option.'; 382 if (f.type === 'file') return 'Please attach a file.'; 383 if (f.type === 'email') return v && String(v).trim() ? 'Please enter a valid email address.' : 'Please enter your email address.'; 384 if (f.type === 'select' || f.type === 'radio') return 'Please choose an option.'; 385 return 'This field is required â please fill it in.'; 386 } 387 if (f.type === 'email' && v && String(v).trim() && !EMAIL_RE.test(v)) return 'Please enter a valid email address.'; 388 if (f.type === 'url' && v && String(v).trim() && coerceUrl(v) === null) return 'Please enter a valid link (e.g. https://â¦).'; 389 return ''; 390 }; 391 const validateAll = () => { 392 const e = {}; 393 shown.forEach(f => { 394 const i = fields.indexOf(f); 395 const m = errOf(f, i); 396 if (m) e[keyOf(f, i)] = m; 397 }); 398 return e; 399 }; 400 const valid = Object.keys(validateAll()).length === 0; 401 const errCount = shown.reduce((n, f) => n + (errors[keyOf(f, fields.indexOf(f))] ? 1 : 0), 0); 402 const btnClass = 'btn ' + (props.submitClass || 'btn-lime'); 403 404 /* scroll the first broken field into view and focus it */ 405 const focusField = k => { 406 setTimeout(() => { 407 const wrap = document.getElementById('dfw-' + formId + '-' + k); 408 const inp = document.getElementById('df-' + formId + '-' + k); 409 const el = wrap || inp; 410 if (el) { 411 try { 412 window.scrollTo({ 413 top: el.getBoundingClientRect().top + window.scrollY - 150, 414 behavior: 'smooth' 415 }); 416 } catch (e) {} 417 } 418 if (inp && inp.focus) { 419 try { 420 inp.focus({ 421 preventScroll: true 422 }); 423 } catch (e) { 424 try { 425 inp.focus(); 426 } catch (e2) {} 427 } 428 } 429 }, 40); 430 }; 431 const finalSubmit = () => { 432 /* re-validate at the last gate: a silent return here looked like a dead 433 Submit button (rage clicks). Broken answers bounce back to edit mode 434 with the first bad field focused + error text visible. */ 435 const lastErrs = validateAll(); 436 if (Object.keys(lastErrs).length) { 437 setErrors(lastErrs); 438 setReviewing(false); 439 const firstBad = shown.map(f =>
439 keyOf(f, fields.indexOf(f))).filter(k => lastErrs[k]); 440 if (firstBad.length) focusField(firstBad[0]); 441 return; 442 } 443 /* payload hygiene: trim strings, cap runaway lengths, normalise links, 444 and carry the empty honeypot so the server-side bot trap is live */ 445 const cleanVal = (f, v) => { 446 if (typeof v === 'string') { 447 let s = v.trim().slice(0, 4000); 448 if (f.type === 'url' && s) { 449 const c = coerceUrl(s); 450 if (c) s = c; 451 } 452 return s; 453 } 454 if (Array.isArray(v)) return v.map(x => String(x).slice(0, 400)); 455 return v; 456 }; 457 const payload = { 458 _hp: hp 459 }; 460 shown.forEach(f => { 461 const i = fields.indexOf(f); 462 payload[keyOf(f, i)] = cleanVal(f, form[keyOf(f, i)]); 463 }); 464 const summary = shown.filter(f => f.type === 'text' || f.type === 'email').slice(0, 2).map(f => form[keyOf(f, fields.indexOf(f))]).filter(Boolean).join(' · '); 465 if (window.CMS && window.CMS.submit) window.CMS.submit(formId, payload, summary); 466 if (props.persistKey && window.CMS && window.CMS.completeDraft) window.CMS.completeDraft(formId, draftKeyFor(props.persistKey)); 467 if (props.persistKey) { 468 try { 469 localStorage.removeItem(props.persistKey); 470 localStorage.removeItem(props.persistKey + ':k'); 471 } catch (e3) {} 472 } 473 setDone(true); 474 if (props.onDone) props.onDone(payload); 475 if (!props.noSuccess) { 476 try { 477 window.scrollTo({ 478 top: 0, 479 behavior: 'smooth' 480 }); 481 } catch (e2) {} 482 } 483 }; 484 const submit = e => { 485 if (e) e.preventDefault(); 486 const errs = validateAll(); 487 setErrors(errs); 488 const bad = shown.map(f => keyOf(f, fields.indexOf(f))).filter(k => errs[k]); 489 if (bad.length) { 490 focusField(bad[0]); 491 return; 492 } 493 if (props.reviewStep && !reviewing) { 494 setReviewing(true); 495 return; 496 } 497 finalSubmit(); 498 }; 499 const backToEdit = focusKey => { 500 setReviewing(false); 501 if (focusKey) { 502 setTimeout(() => { 503 const el = document.getElementById('df-' + formId + '-' + focusKey); 504 if (!el) return; 505 try { 506 window.scrollTo({ 507 top: el.getBoundingClientRect().top + window.scrollY - 140, 508 behavior: 'smooth' 509 }); 510 } catch (e) {} 511 if (el.focus) el.focus(); 512 }, 60); 513 } 514 }; 515 if (done && props.noSuccess) return null; 516 if (done) { 517 return /*#__PURE__*/React.createElement("div", { 518 className: "ct-success" 519 }, /*#__PURE__*/React.createElement("div", { 520 className: "ct-success-mark" 521 }, /*#__PURE__*/React.createElement("svg", { 522 width: "38", 523 height: "38",
524 viewBox: "0 0 24 24", 525 fill: "none" 526 }, /*#__PURE__*/React.createElement("path", { 527 d: "M4 12.5L9.5 18L20 6", 528 stroke: "currentColor", 529 strokeWidth: "2.4", 530 strokeLinecap: "round", 531 strokeLinejoin: "round" 532 }))), /*#__PURE__*/React.createElement("h2", { 533 dangerouslySetInnerHTML: { 534 __html: props.successTitleHtml || 'Message <em>sent</em>' 535 } 536 }), /*#__PURE__*/React.createElement("p", null, props.successBody || "Thanks, your enquiry is in and the right team will get back to you shortly."), props.backHref ? /*#__PURE__*/React.createElement("a", { 537 className: btnClass, 538 href: props.backHref 539 }, props.backLabel || 'Back to Home') : null); 540 } 541 542 /* ââ REVIEW: check-your-answers screen (reviewStep) ââ */ 543 if (reviewing && !done) { 544 const stripTags = s => String(s == null ? '' : s).replace(/<[^>]+>/g, ''); 545 const fmtVal = (f, v) => { 546 if (isCheck(f.type)) return v ? 'Yes, agreed' : 'â'; 547 if (Array.isArray(v)) return v.length ? v.join(', ') : 'â'; 548 const s = (v == null ? '' : String(v)).trim(); 549 return s || 'â'; 550 }; 551 return /*#__PURE__*/React.createElement("div", { 552 className: "df-review" 553 }, /*#__PURE__*/React.createElement("div", { 554 className: "ap-review" 555 }, shown.map(f => { 556 const i = fields.indexOf(f); 557 const k = keyOf(f, i); 558 return /*#__PURE__*/React.createElement("div", { 559 className: "ap-review-row", 560 key: k 561 }, /*#__PURE__*/React.createElement("span", { 562 className: "ap-review-k" 563 }, stripTags(f.label || k)), /*#__PURE__*/React.createElement("span", { 564 className: "ap-review-v" 565 }, fmtVal(f, form[k])), /*#__PURE__*/React.createElement("button", { 566 type: "button", 567 className: "ap-review-edit", 568 onClick: () => backToEdit(k) 569 }, "Edit")); 570 })), /*#__PURE__*/React.createElement("div", { 571 className: "ap-actions", 572 style: { 573 marginTop: 26 574 } 575 }, /*#__PURE__*/React.createElement("button", { 576 type: "button", 577 className: "btn btn-outline", 578 onClick: () => backToEdit('') 579 }, /*#__PURE__*/React.createElement("span", { 580 className: "btn-arrow" 581 }, /*#__PURE__*/React.createElement("svg", { 582 width: "10", 583 height: "10",
584 viewBox: "0 0 10 10", 585 fill: "none" 586 }, /*#__PURE__*/React.createElement("path", { 587 d: "M8 2L2 8M2 8H7M2 8V3", 588 stroke: "currentColor", 589 strokeWidth: "1.6", 590 strokeLinecap: "round" 591 }))), " Edit answers"), /*#__PURE__*/React.createElement("div", { 592 className: "spacer" 593 }), /*#__PURE__*/React.createElement("button", { 594 type: "button", 595 className: btnClass, 596 onClick: finalSubmit 597 }, props.submitLabel || 'Submit', " ", /*#__PURE__*/React.createElement(DFArr, null)))); 598 } 599 return /*#__PURE__*/React.createElement("form", { 600 onSubmit: submit 601 }, props.heading ? /*#__PURE__*/React.createElement("h2", { 602 className: "ct-form-h", 603 dangerouslySetInnerHTML: { 604 __html: props.heading 605 } 606 }) : null, props.intro ? /*#__PURE__*/React.createElement("p", { 607 className: "ct-form-desc" 608 }, props.intro) : null, /*#__PURE__*/React.createElement("div", { 609 className: "ewa-hp", 610 "aria-hidden": "true" 611 }, /*#__PURE__*/React.createElement("label", null, "Leave this field empty", /*#__PURE__*/React.createElement("input", { 612 type: "text", 613 tabIndex: "-1", 614 autoComplete: "off", 615 value: hp, 616 onChange: e => setHp(e.target.value) 617 }))), /*#__PURE__*/React.createElement("div", { 618 className: "ap-fields" 619 }, (() => { 620 /* Row packing: half-width fields render side by side; a half with 621 no half NEXT to it (last, or followed by a full-width field) 622 stretches to 100% so no row is left with an empty column. */ 623 const isHalf = f => { 624 if (isCheck(f.type) || isMulti(f.type) || f.type === 'radio' || f.type === 'file') return false; 625 const w = String(f.width == null ? '' : f.width); 626 if (w === '50' || w === '33' || w === 'half') return true; 627 return false; 628 }; 629 const promote = {}; 630 let pending = -1; 631 shown.forEach((f, si) => { 632 if (isHalf(f)) { 633 if (pending < 0) { 634 pending = si; 635 } else { 636 pending = -1; 637 } 638 } else if (pending >= 0) { 639 promote[pending] = true; 640 pending = -1; 641 } 642 }); 643 if (pending >= 0) promote[pending] = true; 644 return shown.map((f, si) => { 645 const i = fields.indexOf(f); 646 const k = keyOf(f, i); 647 return /*#__PURE__*/React.createElement(Field, { 648 key: k, 649 f: f, 650 id: 'df-' + formId + '-' + k, 651 wrapId: 'dfw-' + formId + '-' + k, 652 value: form[k], 653 onChange: v => set(k, v), 654 err: errors[k] || '', 655 forceFull: !!promote[si] 656 }); 657 }); 658 })()), /*#__PURE__*/React.createElement("div", { 659 className: "ap-actions", 660 style: { 661 marginTop: 26 662 } 663 }, errCount > 0 ? /*#__PURE__*/React.createElement("span", { 664 className: "ap-err ap-err-block", 665 role: "alert" 666 }, "Please fix the ", errCount, " highlighted field", errCount > 1 ? 's' : '', " above.") : /*#__PURE__*/React.createElement("span", null), /*#__PURE__*/React.createElement("div", { 667 className: "spacer" 668 }), props.onChangeRole ? /*#__PURE__*/React.createElement("button", { 669 type: "button", 670 className: "btn btn-outline df-changerole", 671 onClick: props.onChangeRole 672 }, "Change role") : null, /*#__PURE__*/React.createElement("button", { 673 className: btnClass, 674 type: "submit" 675 }, props.reviewStep && !reviewing ? props.reviewLabel || 'Continue to Review' : props.submitLabel || 'Submit', " ", /*#__PURE__*/React.createElement(DFArr, null)))); 676 } 677 window.DynamicForm = DynamicForm; 678})(); 679})();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.