PageSourceSearch

https://20beauty.com.hk/marketing/component/ui/submitButton/function/checkRequiredFields.js

js 20beauty.com.hk collected 2026-10-03 23:19:13 UTC 5,166 bytes, 183 lines download raw bytes

1window.submitButton = window.submitButton || {};
2(function (ns) {
3  "use strict";
4
5  ns.getMobileValidationResult = function (mobile) {
6    var digits = String(mobile || "").replace(/\D/g, "");
7
8    if (!digits) {
9      return {
10        valid: false,
11        digits: "",
12        normalized: "",
13        region: "",
14        reason: "empty",
15      };
16    }
17
18    if (/^852([45689]\d{7})$/.test(digits)) {
19      return {
20        valid: true,
21        digits: digits,
22        normalized: digits.slice(3),
23        region: "HK",
24        reason: "",
25      };
26    }
27
28    if (/^853([45689]\d{7})$/.test(digits)) {
29      return {
30        valid: true,
31        digits: digits,
32        normalized: digits.slice(3),
33        region: "MO",
34        reason: "",
35      };
36    }
37
38    if (/^86(1\d{10})$/.test(digits)) {
39      return {
40        valid: true,
41        digits: digits,
42        normalized: digits.slice(2),
43        region: "CN",
44        reason: "",
45      };
46    }
47
48    if (/^[45689]\d{7}$/.test(digits)) {
49      return {
50        valid: true,
51        digits: digits,
52        normalized: digits,
53        region: "HK_MO",
54        reason: "",
55      };
56    }
57
58    if (/^1\d{10}$/.test(digits)) {
59      return {
60        valid: true,
61        digits: digits,
62        normalized: digits,
63        region: "CN",
64        reason: "",
65      };
66    }
67
68    return {
69      valid: false,
70      digits: digits,
71      normalized: "",
72      region: "",
73      reason: "format",
74    };
75  };
76
77  // exported helper: check required fields based on window.__formRequiredList
78  ns.checkRequiredFields = function () {
79    var ok = true;
80    var missing = [];
81    var details = {};
82    var validationAlertMessage = "";
83    var required = Array.isArray(window.__formRequiredList)
84      ? window.__formRequiredList
85      : [];
86    // hide all previous error displays first
87    document.querySelectorAll(".field-error").forEach(function (el) {
88      el.style.display = "none";
89      el.textContent = "";
90    });
91
92    required.forEach(function (name) {
93      try {
94        var nodes = document.getElementsByName(name);
95        if (!nodes || nodes.length === 0) {
96          return;
97        }
98        // check at least one has a non-empty value (for checkboxes/radios take checked)
99        var hasValue = false;
100        for (var i = 0; i < nodes.length; i++) {
101          var n = nodes[i];
102          var tag = (n.tagName || "").toLowerCase();
103          if (
104            tag === "input" &&
105            (n.type === "checkbox" || n.type === "radio")
106          ) {
107            if (n.checked) {
108              hasValue = true;
109              break;
110            }
111          } else {
112            var v = (n.value || "").toString().trim();
113            if (v !== "" && v !== "沒有選擇" && v !== "0") {
114              hasValue = true;
115              break;
116            }
117          }
118        }
119        if (!hasValue) {
120          ok = false;
121          try {
122            missing.push(name);
123            details[name] = "missing";
124          } catch (e) {}
125          // show error message in placeholder (if present)
126          var err = document.querySelector(
127            '.field-error[data-field="' + name + '"]',
128          );
129          if (err) {
130            err.textContent = "此欄位為必填";
131            err.style.display = "block";
132          }
133          if (!validationAlertMessage) {
134            validationAlertMessage = "請先填寫所有必填欄位";
135          }
136        } else {
137          // special mobile length check: ensure digits >= 8
138          if (name === "mobile") {
139            var m = "";
140            for (var j = 0; j < nodes.length; j++) {
141              if (nodes[j].value) {
142                m = nodes[j].value;
143                break;
144              }
145            }
146            var mobileValidation = ns.getMobileValidationResult(m);
147            if (!mobileValidation.valid) {
148              ok = false;
149              try {
150                if (missing.indexOf("mobile") === -1) missing.push("mobile");
151                details.mobile = mobileValidation.reason || "invalid_format";
152              } catch (e) {}
153              var errm = document.querySelector(
154                '.field-error[data-field="mobile"]',
155              );
156              if (errm) {
157                //香港/澳門須為 8 位並以 4、5、6、8、9 開頭;中國須為 11 位並以 1 開頭
158                errm.textContent = "請輸入有效電話號碼";
159                errm.style.display = "block";
160              }
161              if (!validationAlertMessage) {
162                validationAlertMessage = "請輸入有效電話號碼";
163              }
164            }
165          }
166        }
167      } catch (e) {}
168    });
169
170    // expose for upstream logger (bind_buttons.js)
171    try {
172      ns.__lastRequiredValidation = {
173        ok: !!ok,
174        missing: missing,
175        details: details,
176      };
177    } catch (e) {}
178    if (!ok && validationAlertMessage) {
179      alert(validationAlertMessage);
180    }
181    return ok;
182  };
183})(window.submitButton);

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.