PageSourceSearch

https://screens.tv/lead.js?v=2

js screens.tv collected 2026-10-02 13:54:11 UTC 3,821 bytes, 80 lines download raw bytes

1/* ============================================================================
2   lead.js, behaviour for the shared lead-capture form component.
3   The markup lives in each page (component: LeadCaptureForm); its copy lives in
4   src/content/site/forms.json → leadForm. Any [data-open-lead] element opens it;
5   add data-lead-service="Subtitling" to pre-select a service chip.
6   No-ops on pages without the component.
7   ========================================================================= */
8(function () {
9  var modal = document.getElementById('leadModal');
10  if (!modal || modal.__leadBound) return;
11  modal.__leadBound = true;
12
13  var form = document.getElementById('leadForm');
14  var success = document.getElementById('leadSuccess');
15  var eyebrow = document.getElementById('leadEyebrow');
16  var chips = Array.prototype.slice.call(modal.querySelectorAll('.lead-chip'));
17  var defaultEyebrow = eyebrow ? eyebrow.textContent : '';
18  var lastFocus = null;
19
20  var open = function (e) {
21    if (e) e.preventDefault();
22    lastFocus = document.activeElement;
23
24    // pre-select a service if the trigger requested one
25    var trigger = e && e.currentTarget ? e.currentTarget : null;
26    var preset = trigger ? trigger.getAttribute('data-lead-service') : null;
27    chips.forEach(function (c) { c.classList.remove('active'); });
28    if (preset) {
29      chips.forEach(function (c) { if (c.dataset.service === preset) c.classList.add('active'); });
30      if (eyebrow) eyebrow.textContent = '// ' + preset + ' request';
31    } else if (eyebrow) {
32      eyebrow.textContent = defaultEyebrow;
33    }
34
35    form.hidden = false; success.hidden = true;
36    modal.hidden = false; document.body.style.overflow = 'hidden';
37    setTimeout(function () { var f = form.querySelector('input[name="name"]'); if (f) f.focus(); }, 60);
38  };
39  var close = function () {
40    modal.hidden = true; document.body.style.overflow = '';
41    if (lastFocus && lastFocus.focus) lastFocus.focus();
42  };
43
44  document.querySelectorAll('[data-open-lead]').forEach(function (b) { b.addEventListener('click', open); });
45  modal.querySelectorAll('[data-close-lead]').forEach(function (b) { b.addEventListener('click', close); });
46  document.addEventListener('keydown', function (e) { if (e.key === 'Escape' && !modal.hidden) close(); });
47
48  chips.forEach(function (chip) { chip.addEventListener('click', function () { chip.classList.toggle('active'); }); });
49
50  form.addEventListener('submit', function (e) {
51    e.preventDefault();
52    var name = form.name.value.trim();
53    var email = form.email.value.trim();
54    if (!name) { form.name.focus(); return; }
55    if (!email || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) { form.email.reportValidity(); return; }
56
57    var services = chips.filter(function (c) { return c.classList.contains('active'); }).map(function (c) { return c.dataset.service; }).join(', ');
58    var data = new FormData(form);
59    data.set('form-name', 'lead');
60    data.set('services', services);
61
62    var btn = form.querySelector('button[type="submit"]');
63    if (btn) btn.disabled = true;
64    fetch('/', {
65      method: 'POST',
66      headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
67      body: new URLSearchParams(data).toString()
68    }).then(function (res) {
69      if (!res.ok) throw new Error('HTTP ' + res.status);
70      document.getElementById('leadName').textContent = name.split(' ')[0] || 'there';
71      document.getElementById('leadEmail').textContent = email;
72      form.hidden = true; success.hidden = false;
73      form.reset(); chips.forEach(function (c) { c.classList.remove('active'); });
74    }).catch(function () {
75      alert('Something went wrong sending your request. Please try again, or email [email protected].');
76    }).finally(function () {
77      if (btn) btn.disabled = false;
78    });
79  });
80})();

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.