Last active
August 20, 2025 12:48
-
-
Save Qubadi/ac7a99a26331afc8b38c69a9ea3c570d to your computer and use it in GitHub Desktop.
Jetformbuilder form, A custom code for auto detect country and land code phone ( New style and new version ).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| UPDATED: 18.08.2025 | |
| Copy the following PHP and create a PHP snippet using your snippet plugins. | |
| Paste the code into the plugin and save it. | |
| _____________________________________________ | |
| /** | |
| * JetFormBuilder: Phone field with flag + dial code, auto-detect country (no API key). | |
| * Detection order: saved value → time zone → browser language/region → fallback US. | |
| */ | |
| add_action('wp_footer', function () { ?> | |
| <link rel="dns-prefetch" href="https://cdn.jsdelivr.net"> | |
| <link rel="preconnect" href="https://cdn.jsdelivr.net" crossorigin> | |
| <link rel="preload" href="https://cdn.jsdelivr.net/npm/intl-tel-input@23.7.4/build/css/intlTelInput.css" as="style"> | |
| <link rel="preload" href="https://cdn.jsdelivr.net/npm/intl-tel-input@23.7.4/build/js/intlTelInput.min.js" as="script"> | |
| <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/intl-tel-input@23.7.4/build/css/intlTelInput.css" /> | |
| <script src="https://cdn.jsdelivr.net/npm/intl-tel-input@23.7.4/build/js/intlTelInput.min.js"></script> | |
| <script> | |
| (() => { | |
| "use strict"; | |
| const STORAGE_KEY = 'jfb_tel_cc'; | |
| const itiMap = new WeakMap(); | |
| // Time zone -> country (no external requests) | |
| const TZ2CC = { | |
| 'Europe/Oslo':'NO','Europe/Stockholm':'SE','Europe/Copenhagen':'DK','Europe/Helsinki':'FI','Atlantic/Reykjavik':'IS', | |
| 'Europe/Berlin':'DE','Europe/Vienna':'AT','Europe/Zurich':'CH','Europe/Brussels':'BE','Europe/Amsterdam':'NL','Europe/Luxembourg':'LU', | |
| 'Europe/London':'GB','Europe/Dublin':'IE', | |
| 'Europe/Paris':'FR','Europe/Madrid':'ES','Europe/Rome':'IT','Europe/Lisbon':'PT','Atlantic/Madeira':'PT','Atlantic/Azores':'PT', | |
| 'Europe/Warsaw':'PL','Europe/Prague':'CZ','Europe/Bratislava':'SK','Europe/Budapest':'HU', | |
| 'Europe/Athens':'GR','Europe/Bucharest':'RO','Europe/Sofia':'BG','Europe/Zagreb':'HR','Europe/Belgrade':'RS', | |
| 'Europe/Sarajevo':'BA','Europe/Skopje':'MK','Europe/Tirane':'AL','Europe/Ljubljana':'SI', | |
| 'Europe/Tallinn':'EE','Europe/Riga':'LV','Europe/Vilnius':'LT', | |
| 'America/New_York':'US','America/Detroit':'US','America/Toronto':'CA','America/Montreal':'CA', | |
| 'America/Chicago':'US','America/Winnipeg':'CA','America/Edmonton':'CA','America/Denver':'US', | |
| 'America/Los_Angeles':'US','America/Vancouver':'CA','America/Phoenix':'US','America/Anchorage':'US','Pacific/Honolulu':'US', | |
| 'America/Sao_Paulo':'BR','America/Buenos_Aires':'AR','America/Bogota':'CO','America/Lima':'PE','America/Santiago':'CL','America/Montevideo':'UY', | |
| 'Asia/Dubai':'AE','Asia/Jerusalem':'IL','Europe/Istanbul':'TR','Asia/Riyadh':'SA','Asia/Tehran':'IR','Asia/Qatar':'QA','Asia/Kuwait':'KW', | |
| 'Africa/Cairo':'EG','Africa/Johannesburg':'ZA','Africa/Nairobi':'KE','Africa/Lagos':'NG','Africa/Casablanca':'MA','Africa/Algiers':'DZ','Africa/Tunis':'TN', | |
| 'Asia/Tokyo':'JP','Asia/Seoul':'KR','Asia/Shanghai':'CN','Asia/Hong_Kong':'HK','Asia/Taipei':'TW', | |
| 'Asia/Singapore':'SG','Asia/Kuala_Lumpur':'MY','Asia/Bangkok':'TH','Asia/Jakarta':'ID','Asia/Manila':'PH','Asia/Ho_Chi_Minh':'VN', | |
| 'Asia/Kolkata':'IN', | |
| 'Australia/Sydney':'AU','Australia/Melbourne':'AU','Australia/Brisbane':'AU','Australia/Perth':'AU','Australia/Adelaide':'AU', | |
| 'Pacific/Auckland':'NZ' | |
| }; | |
| function detectCountry() { | |
| const saved = localStorage.getItem(STORAGE_KEY); | |
| if (saved && /^[A-Z]{2}$/.test(saved)) return saved; | |
| const langs = [ | |
| ...(navigator.languages || []), | |
| navigator.language, | |
| document.documentElement?.lang || '' | |
| ].filter(Boolean).map(String); | |
| try { | |
| const tz = Intl.DateTimeFormat().resolvedOptions().timeZone; | |
| if (tz && TZ2CC[tz]) return TZ2CC[tz]; | |
| } catch (_) {} | |
| for (const l of langs) { | |
| const m = l.match(/-([A-Za-z]{2})$/); | |
| if (m) return m[1].toUpperCase(); | |
| } | |
| let weak = null; | |
| for (const l of langs) { | |
| try { | |
| if (window.Intl && Intl.Locale) { | |
| const r = new Intl.Locale(l).maximize().region; | |
| if (r) { weak = r.toUpperCase(); break; } | |
| } | |
| } catch (_) {} | |
| } | |
| if (!weak && langs.length) { | |
| const map = {nb:'NO',nn:'NO',sv:'SE',da:'DK',fi:'FI',de:'DE',fr:'FR',es:'ES',it:'IT',nl:'NL',pl:'PL',pt:'PT',ru:'RU', | |
| tr:'TR',el:'GR',cs:'CZ',sk:'SK',hu:'HU',ro:'RO',bg:'BG',hr:'HR',sl:'SI',lt:'LT',lv:'LV',et:'EE',en:'GB'}; | |
| weak = map[langs[0].slice(0,2).toLowerCase()] || weak; | |
| } | |
| return weak || 'US'; | |
| } | |
| function syncDialColor(input) { | |
| try { | |
| const wrap = input.closest('.iti'); if (!wrap) return; | |
| const phColor = getComputedStyle(input, '::placeholder').color; | |
| const dc = wrap.querySelector('.iti__selected-dial-code'); | |
| if (dc && phColor) dc.style.color = phColor; | |
| } catch (_) {} | |
| } | |
| function initTel(input) { | |
| if (!window.intlTelInput || input.dataset.itiReady) return; | |
| input.dataset.itiReady = '1'; | |
| try { | |
| const iti = window.intlTelInput(input, { | |
| initialCountry: detectCountry().toLowerCase(), | |
| separateDialCode: true, // shows +CC immediately | |
| nationalMode: true, | |
| autoPlaceholder: 'polite', | |
| dropdownContainer: document.body, // dropdown only overlays when open | |
| // utilsScript loads async; not needed for the initial flag/dial code | |
| utilsScript: "https://cdn.jsdelivr.net/npm/intl-tel-input@23.7.4/build/js/utils.js" | |
| }); | |
| itiMap.set(input, iti); | |
| input.addEventListener('countrychange', () => { | |
| const d = iti.getSelectedCountryData(); | |
| if (d?.iso2) localStorage.setItem(STORAGE_KEY, d.iso2.toUpperCase()); | |
| syncDialColor(input); | |
| }); | |
| input.style.width = '100%'; | |
| const wrap = input.closest('.iti'); if (wrap) wrap.style.width = '100%'; | |
| syncDialColor(input); | |
| } catch(_) {} | |
| } | |
| const initNow = () => { | |
| document.querySelectorAll('.jet-form-builder input[type="tel"]').forEach(initTel); | |
| }; | |
| if (document.readyState !== 'loading') { | |
| initNow(); | |
| } else { | |
| document.addEventListener('DOMContentLoaded', initNow, { once:true }); | |
| } | |
| // SUBMIT (capture): ensure +<dial><local> BEFORE JFB serializes the form | |
| function normalizeOnSubmit(input, iti) { | |
| const data = iti.getSelectedCountryData() || {}; | |
| const dial = String(data.dialCode || '').replace(/\D/g, ''); | |
| let raw = String(input.value || '').trim(); | |
| if (raw.startsWith('00')) raw = '+' + raw.slice(2); | |
| let cleaned = raw.replace(/(?!^\+)[^\d]/g, ''); | |
| const digits = cleaned.replace(/^\+/, ''); | |
| const local = dial ? digits.replace(new RegExp('^' + dial), '') : digits; | |
| let e164 = null; | |
| try { e164 = iti.getNumber(); } catch(_) { e164 = null; } | |
| const built = '+' + dial + local; | |
| const finalVal = (e164 && /^\+\d{4,}$/.test(e164)) ? e164 : built; | |
| if (finalVal && finalVal !== input.value) input.value = finalVal; | |
| } | |
| document.addEventListener('submit', (e) => { | |
| const form = e.target; | |
| if (!(form instanceof HTMLFormElement)) return; | |
| form.querySelectorAll('.jet-form-builder input[type="tel"]').forEach(inp => { | |
| if (!inp.dataset.itiReady) initTel(inp); // ensure iti exists | |
| const iti = itiMap.get(inp); | |
| if (iti) normalizeOnSubmit(inp, iti); | |
| }); | |
| }, true); // capture=true so it runs before JFB | |
| })(); | |
| </script> | |
| <style> | |
| /* Respect the form’s placeholder color (no hardcoding) */ | |
| .jet-form-builder input[type="tel"]::placeholder, | |
| .jet-form-builder .iti input[type="tel"]::placeholder { color: inherit; opacity: inherit; } | |
| .jet-form-builder input[type="tel"]::-webkit-input-placeholder, | |
| .jet-form-builder input[type="tel"]::-moz-placeholder, | |
| .jet-form-builder input[type="tel"]:-ms-input-placeholder, | |
| .jet-form-builder input[type="tel"]::-ms-input-placeholder { color: inherit; opacity: inherit; } | |
| .jet-form-builder .iti__flag-container { z-index: auto !important; } | |
| .jet-form-builder .iti { z-index: auto !important; } | |
| .iti--container { position: absolute; z-index: 9999; } | |
| /* Layout helper */ | |
| .jet-form-builder .iti { width: 100%; } | |
| </style> | |
| <?php }); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment