PageSourceSearch

https://chswf.org/wp-content/plugins/smart-phone-field-for-gravity-forms/assets/js/spf_main.js?ver=1791397565

js chswf.org collected 2026-10-09 16:54:50 UTC 6,572 bytes, 200 lines download raw bytes

1class SmartPhoneFieldFree {
2    constructor(options) {
3        this.options = options;
4        this.init();
5    }
6
7    init() {
8        this.initSmartPhoneFieldFree();
9        this.addCountryCodeInputHandler();
10    }
11
12    initSmartPhoneFieldFree() {
13        if (typeof intlTelInput === 'undefined') {
14            return;
15        }
16        const input = document.querySelector(this.options.inputId);
17
18        if (!input) {
19            console.warn(`Input element not found: ${this.options.inputId}`);
20            return;
21        }
22
23        const preValue = input.value;
24        const iti = window.intlTelInput(input, this.configuration());
25        const fieldId = `${this.options.formId}_${this.options.fieldId}`;
26
27        input.addEventListener('blur', (e) => {
28            this.validateNumber(e.currentTarget, fieldId, iti);
29        });
30
31        input.addEventListener('keyup', (e) => {
32            this.formatValidation(e.currentTarget, iti);
33        });
34
35        if (preValue) {
36            iti.setNumber(preValue);
37            this.validateNumber(input, fieldId, iti);
38        }
39    }
40
41    configuration() {
42        const field_id = `input_${this.options.fieldId}`;
43
44        let config = {
45            initialCountry: this.options.defaultCountry,
46            formatOnDisplay: false,
47            formatAsYouType: false,
48            fixDropdownWidth: true,
49            hiddenInput: function (telInputName) {
50                return {
51                    phone: field_id
52                };
53            },
54            useFullscreenPopup: false
55        };
56
57        if (this.options.countrySearch) {
58            config.countrySearch = true;
59        }
60
61        if (this.options.flag === "flagcode") {
62            config.nationalMode = false;
63            config.autoHideDialCode = false;
64        } else if (this.options.flag === "flagdial" || this.options.flag === "flagwithcode") {
65            config.nationalMode = false;
66            config.separateDialCode = true;
67        } else {
68            config.nationalMode = true;
69        }
70
71        if (this.options.exIn === 'ex_only') {
72            config.onlyCountries = this.options.countries.split(',');
73        }
74
75        if (this.options.exIn === 'pre_only') {
76            config.excludeCountries = this.options.countries.split(',');
77        }
78
79        if (this.options.autoIp) {
80            this.detectIPAddress(config);
81        }
82
83        if (this.options.placeholder) {
84            config.autoPlaceholder = 'off';
85        }
86
87        config = gform.applyFilters('gform_spf_options_pre_init', config, this.options.formId, this.options.fieldId);
88
89        return config;
90    }
91
92    detectIPAddress(config) {
93        const api_url = "https://ipinfo.io/json";
94        config.initialCountry = "auto";
95        config.geoIpLookup = function (callback) {
96            fetch(api_url)
97                .then(r => r.json())
98                .then(data => {
99                    const country = (data && data.country) ? data.country.toLowerCase() : 'us';
100                    callback(country);
101                })
102                .catch(() => callback('us'));
103        };
104    }
105
106    validateNumber(input, fieldId, iti) {
107        if (!input.value) {
108            const errorMsg = input.parentNode?.parentNode?.querySelector('.error-msg');
109            const validMsg = input.parentNode?.parentNode?.querySelector('.valid-msg');
110            if (errorMsg) errorMsg.classList.add('hide');
111            if (validMsg) validMsg.classList.add('hide');
112            return;
113        }
114
115        const isValid = iti.isValidNumber();
116        const errorMsg = input.parentNode?.parentNode?.querySelector('.error-msg');
117        const validMsg = input.parentNode?.parentNode?.querySelector('.valid-msg');
118        const hiddenInput = input.parentNode?.parentNode?.querySelector('input[type="hidden"]');
119        const number = iti.getNumber(intlTelInput.utils.numberFormat.E164);
120
121        if (errorMsg && validMsg && input.value) {
122            if (isValid) {
123                errorMsg.classList.add('hide');
124                validMsg.classList.remove('hide');
125                input.setAttribute('aria-invalid', 'false');
126            } else {
127                validMsg.classList.add('hide');
128                errorMsg.classList.remove('hide');
129                input.setAttribute('aria-invalid', 'true');
130            }
131            hiddenInput.value = number;
132        } else {
133            validMsg.classList.add('hide');
134	        errorMsg.classList.add('hide');
135        }
136    }
137
138    formatValidation(input, iti) {
139        if (!input.value) {
140            const errorMsg = input.parentNode?.parentNode?.querySelector('.error-msg');
141            const validMsg = input.parentNode?.parentNode?.querySelector('.valid-msg');
142            if (errorMsg) errorMsg.classList.add('hide');
143            if (validMsg) validMsg.classList.add('hide');
144            return;
145        }
146
147        const isValid = iti.isValidNumber();
148        const errorMsg = input.parentNode?.parentNode?.querySelector('.error-msg');
149        const validMsg = input.parentNode?.parentNode?.querySelector('.valid-msg');
150
151        if (errorMsg && validMsg) {
152            if (isValid) {
153                errorMsg.classList.add('hide');
154                validMsg.classList.remove('hide');
155            } else {
156                validMsg.classList.add('hide');
157                errorMsg.classList.add('hide');
158            }
159        }
160    }
161
162    addCountryCodeInputHandler() {
163        if (this.options.flag !== 'flagcode') {
164            return;
165        }
166
167        const input = document.querySelector(this.options.inputId);
168        if (!input) {
169            return;
170        }
171
172        const iti = intlTelInput.getInstance(input);
173        if (!iti) {
174            return;
175        }
176
177        const handleCountryChange = (event) => {
178            const currentCountryData = iti.getSelectedCountryData();
179            const currentCode = `+${currentCountryData.dialCode}`;
180            this.updateCountryCodeHandler(event.currentTarget, currentCode);
181        };
182
183        input.addEventListener('keydown', handleCountryChange);
184        input.addEventListener('input', handleCountryChange);
185        input.addEventListener('countrychange', handleCountryChange);
186    }
187
188    updateCountryCodeHandler(element, currentCode) {
189        let value = element.value;
190
191        if (!currentCode || currentCode === '+undefined' || ['', '+'].includes(value)) {
192            return;
193        }
194
195        if (!value.startsWith(currentCode)) {
196            value = value.replace(/\+/g, '');
197            element.value = currentCode + value;
198        }
199    }
200}

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.