PageSourceSearch

https://www.pingdom.com/wp-content/themes/sw-global/dev/scripts/form-logic/helpers.js?ver=1786605102

js pingdom.com collected 2026-09-24 06:23:18 UTC 4,929 bytes, 137 lines download raw bytes

1// Form Logic: Generic form helpers
2// Dependencies: none
3//
4// Provides shared utilities consumed by other form-logic scripts:
5//   - setDropdownValue      — programmatic select value setter
6//   - swGetCookie           — unified cookie reader (replaces getCookie + sw19_get_cookie)
7//   - swIsIE                — IE 11 detection
8//   - swIsEdgeLegacy        — Legacy Edge (pre-Chromium) detection
9//   - swIsMobileDevice      — mobile user-agent detection
10//   - swCountryOptinToggle  — show/hide marketing optin based on selected country
11//   - swFieldListeners      — focus/blur/invalid/input UX listeners for .sw19s-corp-field wrappers
12
13function setDropdownValue(selectElem, value) {
14  const opts = selectElem.querySelectorAll("option");
15  const vals = Array.from(opts).map((el) => el.value);
16  if (vals.includes(value)) {
17    selectElem.value = value;
18    selectElem.dispatchEvent(new Event("change"));
19  }
20}
21
22// Unified cookie reader.
23// Replaces getCookie() in corp-form.js and sw19_get_cookie() in signup-form.js.
24function swGetCookie(name) {
25  const cookies = document.cookie ? document.cookie.split("; ") : [];
26  for (let i = 0; i < cookies.length; i++) {
27    const eqIdx = cookies[i].indexOf("=");
28    if (eqIdx === -1) continue;
29    const key = cookies[i].substring(0, eqIdx);
30    if (key !== name) continue;
31    const rawVal = cookies[i].substring(eqIdx + 1);
32    try {
33      return decodeURIComponent(rawVal);
34    } catch (_) {
35      return rawVal;
36    }
37  }
38  return null;
39}
40
41// Browser detection helpers.
42// Replaces sw19_is_ie() / sw19_is_edge_legacy() duplicated across signup-form.js
43function swIsIE() {
44  var ua = window.navigator.userAgent;
45  return ua.indexOf("MSIE ") > 0 || ua.indexOf("Trident/") > 0;
46}
47
48function swIsEdgeLegacy() {
49  return window.navigator.userAgent.indexOf("Edge/") > 0;
50}
51
52// Replaces sw19_is_mobile_device() in signup-form.js.
53function swIsMobileDevice() {
54  return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
55    navigator.userAgent
56  );
57}
58
59// Reads optin visibility rules from the form's country picker and the
60// promotions element's data attributes, then adds/removes 'show-optin'.
61// Replaces: sw19_corp_form_country(), hide_or_show_optin(),
62//           sw19_signup_form_country(), sw_ps_country_optin().
63function swCountryOptinToggle(form) {
64  var countryDrop = form.querySelector("select.country-picker");
65  if (!countryDrop) return;
66
67  var selected = countryDrop.options[countryDrop.selectedIndex].value;
68  var promotionsEl =
69    form.querySelector("div#promotions-signup-area") ||
70    form.querySelector(".promotions");
71  var isShown = false;
72
73  if (promotionsEl && promotionsEl.dataset.country) {
74    if (promotionsEl.dataset.country.includes("all")) {
75      var excluded = promotionsEl.dataset.countryExclude
76        ? promotionsEl.dataset.countryExclude.split(" ")
77        : [];
78      isShown = !excluded.includes(selected);
79    } else {
80      isShown = promotionsEl.dataset.country.split(" ").includes(selected);
81    }
82  } else {
83    isShown = ["DE", "CH", "AT"].includes(selected);
84  }
85
86  if (isShown) {
87    form.classList.add("show-optin");
88  } else {
89    form.classList.remove("show-optin");
90  }
91}
92
93// Attaches focus / blur / invalid / input class-based UX listeners to all
94// .sw19s-corp-field wrappers within the given container element.
95// Replaces: sw19_corp_field_listeners() in corp-fields.js and
96//           sw_ps_field_listeners() in signup-pingdom-scripts.js.
97function swFieldListeners(container) {
98  var fields = container.querySelectorAll(".sw19s-corp-field");
99  for (var i = 0; i < fields.length; i++) {
100    var field = fields[i];
101    var input = field.querySelector("input, select, textarea");
102    if (!input) continue;
103
104    (function (scopedField) {
105      input.addEventListener("focus", function (e) {
106        var label = e.target.labels && e.target.labels[0];
107        if (label) label.classList.add("selected");
108        scopedField.classList.add("focused");
109      });
110
111      input.addEventListener("blur", function (e) {
112        if (!e.target.validity.valid) {
113          e.target.closest(".sw19s-corp-field").classList.add("invalid");
114        }
115        if (e.target.value === "") {
116          var lbl = e.target.labels && e.target.labels[0];
117          if (lbl) lbl.classList.remove("selected");
118          e.target.closest(".sw19s-corp-field").classList.add("invalid");
119        }
120        scopedField.classList.remove("focused");
121      });
122
123      input.addEventListener("invalid", function (e) {
124        e.target.closest(".sw19s-corp-field").classList.add("invalid");
125      });
126
127      input.addEventListener("input", function (e) {
128        if (e.target.validity.valid) {
129          e.target.closest(".sw19s-corp-field").classList.remove("invalid");
130        }
131        if (e.target.value === "") {
132          e.target.closest(".sw19s-corp-field").classList.add("invalid");
133        }
134      });
135    })(field);
136  }
137}

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.