WEBLEB
Inicio
Editora de código
Iniciar sesión
Pro
Español
English
Français
Español
Português
Deutsch
Italiano
हिंदी
CodePen - Campo de entrada de número de teléfono
1765
Andev.web
Abrir en el editor
Publica tu código
Recomendado
29 July 2025
Un código del texto
23 May 2025
Menú de hamburguesa de inicio de sesión en 3D
21 October 2024
Reglas de contraseña + alternar componentes web
HTML
Copy
Andev Web
Phonenumber*
This is not a valid phone number
No results found
CSS
Copy
@import url("https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500&display=swap"); html { box-sizing: border-box; height: 100%; font-size: 16px; } *, *:before, *:after { box-sizing: inherit; } body { background: #efefef; height: 100%; display: flex; align-items: center; justify-content: center; font-family: "Inter", sans-serif; font-weight: 400; line-height: 1.5; padding: 0 1em; color: #081627; } input[type=search], input[type=tel], input[type=text] { font-size: 1rem; border: 0; font-family: inherit; outline: none; color: inherit; margin: 0; padding: 0; width: auto; max-width: 100%; } input[type=search]::-webkit-input-placeholder, input[type=tel]::-webkit-input-placeholder, input[type=text]::-webkit-input-placeholder { font-weight: 300; color: #6b7280; } input[type=search]::-moz-placeholder, input[type=tel]::-moz-placeholder, input[type=text]::-moz-placeholder { font-weight: 300; color: #6b7280; } input[type=search]:-ms-input-placeholder, input[type=tel]:-ms-input-placeholder, input[type=text]:-ms-input-placeholder { font-weight: 300; color: #6b7280; } input[type=search]:-moz-placeholder, input[type=tel]:-moz-placeholder, input[type=text]:-moz-placeholder { font-weight: 300; color: #6b7280; } :root { --border-radius: 0.75em; --border-color: #c3c3c3; --border-color-active: #0047a5; --dropdown-border-color: #eaeaec; --dropdown-trigger-background-color: #f3f5f9; --dropdown-trigger-hover-background-color: #e6eaf1; --input-error-color: #ff0000; --input-label-color: #85898f; --input-prefix-color: #656b73; --input-phonenumber-color: #081627; --list-item-hover-background: #f3f5f9; } .pn-select { position: relative; border-width: 1px; border-style: solid; border-color: var(--border-color); display: grid; grid-template-columns: 4.5em 1fr; border-radius: var(--border-radius); box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.1); transition: all 0.2s ease-out; max-width: 20em; width: 100%; z-index: 1; } .pn-select:focus, .pn-select:focus-within { border-color: var(--border-color-active); box-shadow: 0 0 2px 0 var(--border-color-active); } .pn-dropdown { background: #ffffff; border-radius: var(--border-radius); border-width: 1px; border-style: solid; border-color: var(--dropdown-border-color); box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.135); opacity: 0; padding: 0 0.5em 0.5em; pointer-events: none; position: absolute; top: 140%; transform-origin: left top; transition: all 0.15s ease-out; width: 100%; visibility: hidden; } .pn-select--open .pn-dropdown { pointer-events: all; transform: none; opacity: 1; top: 120%; visibility: visible; } .pn-search { position: relative; display: flex; border-bottom-width: 1px; border-style: solid; border-color: var(--dropdown-border-color); margin-bottom: 0.5em; } .pn-search svg { display: block; height: 1.25rem; left: 0.5em; pointer-events: none; position: absolute; top: 50%; transform: translateY(-50%); width: 1.25rem; } .pn-search input[type=search] { padding-left: 2.5rem; height: 3rem; width: 100%; } .pn-search input[type=search]::-webkit-search-decoration, .pn-search input[type=search]::-webkit-search-cancel-button, .pn-search input[type=search]::-webkit-search-results-button, .pn-search input[type=search]::-webkit-search-results-decoration { display: none; } .pn-list { margin-right: -0.5em; max-height: 10.5em; overflow-y: auto; scrollbar-width: thin; scrollbar-color: #ffffff #ffffff; position: relative; } .pn-list::-webkit-scrollbar { width: 10px; } .pn-list:hover { --scrollbar-background: #ffffff; --thumb-background: #c0c4ca; scrollbar-color: var(--thumb-background) var(--scrollbar-background); } .pn-list:hover::-webkit-scrollbar-track { background: var(--scrollbar-background); } .pn-list:hover::-webkit-scrollbar-thumb { background-color: var(--thumb-background); border-radius: 6px; border: 3px solid var(--scrollbar-background); } .pn-list--no-scroll { margin-right: 0; } .pn-selected-prefix { align-items: center; -webkit-appearance: none; -moz-appearance: none; appearance: none; background: var(--dropdown-trigger-background-color); border-radius: var(--border-radius) 0 0 var(--border-radius); border: 0; cursor: pointer; display: flex; justify-content: center; margin: 0; outline: none; padding: 0; transition: background 0.2s ease-out; } .pn-selected-prefix:hover, .pn-selected-prefix:focus { background: var(--dropdown-trigger-hover-background-color); } .pn-selected-prefix__flag { height: auto; width: 1.25rem; } .pn-selected-prefix__icon { display: block; height: 1.25rem; margin-left: 0.5em; margin-right: -0.25em; transition: all 0.15s ease-out; width: 1.25rem; } .pn-select--open .pn-selected-prefix__icon { transform: rotate(180deg); } .pn-input { background: #ffffff; border-radius: 0 var(--border-radius) var(--border-radius) 0; line-height: 1; overflow: hidden; padding: 0.5em 1em; } .pn-input__container { display: flex; flex-direction: row; } .pn-input__label { color: var(--input-label-color); font-size: 0.7rem; position: relative; top: -0.25em; } .pn-input__error { bottom: 0; color: var(--input-error-color); font-size: 0.785rem; left: 0; opacity: 0; pointer-events: none; position: absolute; transition: all 0.2s ease-out; z-index: -1; } .pn-input input[type=text] { background: transparent; position: absolute; color: var(--input-prefix-color); max-width: 3rem; pointer-events: none; } .pn-input input[type=tel] { color: var(--input-phonenumber-color); padding-left: calc(calc(var(--prefix-length) * 1ch) + 1.5ch); font-weight: 500; } .pn-input input[type=tel]:not(:-moz-placeholder-shown):invalid + .pn-input__error { opacity: 1; transform: translateY(175%); } .pn-input input[type=tel]:not(:-ms-input-placeholder):invalid + .pn-input__error { opacity: 1; transform: translateY(175%); } .pn-input input[type=tel]:not(:placeholder-shown):invalid + .pn-input__error { opacity: 1; transform: translateY(175%); } .pn-list-item { align-items: center; border-radius: 0.5em; display: flex; font-weight: 400; padding: 0.6em 0.75em; transition: background-color 0.2s ease-out; cursor: pointer; outline: none; } .pn-list-item__flag { width: 1.25em; height: auto; margin-right: 1em; display: block; } .pn-list-item__country { margin-right: 0.25em; } .pn-list-item:hover, .pn-list-item:focus { background-color: var(--list-item-hover-background); } .pn-list-item--selected { pointer-events: none; font-weight: 500; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23103155' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-check'%3E%3Cpolyline points='20 6 9 17 4 12'/%3E%3C/svg%3E"); background-position: right 0.75em top 50%; background-repeat: no-repeat; background-size: 1.25rem; background-position: right 0.75em top 50%; } .pn-list-item--no-results { pointer-events: none; } .dribble-creds { bottom: 2em; font-size: 0.875rem; left: 0; position: fixed; right: 0; text-align: center; } .dribble-creds a { color: #ea4c89; text-decoration: underline; }
JS
Copy
const selectContainer = document.getElementById("js_pn-select"); const countrySearchInput = document.getElementById("js_search-input"); const noResultListItem = document.getElementById("js_no-results-found"); const dropdownTrigger = document.getElementById("js_trigger-dropdown"); const phoneNumberInput = document.getElementById("js_input-phonenumber"); const dropdownContainer = document.getElementById("js_dropdown"); const selectedPrefix = document.getElementById("js_number-prefix"); const selectedFlag = document.getElementById("js_selected-flag"); const listContainer = document.getElementById("js_list"); let countryList; const init = async countries => { const selectCountry = e => { const { flag, prefix } = e.target.closest("li").dataset; setNewSelected(prefix, flag); closeDropdown(); addSelectedModifier(flag); }; // -------------- Update the 'Selected country flag' to reflect changes const setNewSelected = (prefix, flag) => { selectedFlag.src = `https://flagpedia.net/data/flags/icon/36x27/${flag}.png`; selectedPrefix.value = `+${prefix}`; selectContainer.style.setProperty("--prefix-length", prefix.length); }; // -------------- Removes and adds modifier to selected country const addSelectedModifier = flag => { const previousSelected = document.getElementsByClassName( "pn-list-item--selected")[ 0]; const newSelected = document.querySelectorAll( `.pn-list-item[data-flag=${flag}]`)[ 0]; previousSelected.classList.remove("pn-list-item--selected"); newSelected.classList.add("pn-list-item--selected"); }; // -------------- Close dropdown const closeDropdown = () => { selectContainer.classList.remove("pn-select--open"); listContainer.scrollTop = 0; countrySearchInput.value = ""; countryList.search(); phoneNumberInput.focus(); removeDropdownEvents(); }; // -------------- Open dropdown const openDropdown = () => { selectContainer.classList.add("pn-select--open"); attatchDropdownEvents(); }; // -------------- Dropdown event listeners let countdown; const closeOnMouseLeave = () => { // console.log("countdown activated"); countdown = setTimeout(() => closeDropdown(), 2000); }; const clearTimeOut = () => clearTimeout(countdown); const attatchDropdownEvents = () => { // console.log("Adding event listeners"); dropdownContainer.addEventListener("mouseleave", closeOnMouseLeave); dropdownContainer.addEventListener("mouseenter", clearTimeOut); }; const removeDropdownEvents = () => { // console.log("Removing event listeners and countdown"); clearTimeout(countdown); dropdownContainer.removeEventListener("mouseleave", closeOnMouseLeave); dropdownContainer.removeEventListener("mouseenter", clearTimeOut); }; // -------------- Close when clicked outside the dropdown document.addEventListener("click", e => { if ( e.target !== selectContainer && !selectContainer.contains(e.target) && selectContainer.classList.contains("pn-select--open")) { closeDropdown(); } }); // -------------- Append generated listItems to list element const createList = () => new Promise((resolve, _) => { countries.forEach((country, index, countries) => { const { name, prefix, flag } = country; const element = `<li class="pn-list-item ${ flag === "nl" ? "pn-list-item--selected" : "" } js_pn-list-item" data-flag="${flag}" data-prefix="${prefix}" tabindex="0" role="button" aria-pressed="false"> <img class="pn-list-item__flag" src="https://flagpedia.net/data/flags/icon/36x27/${flag}.png" /> <span class="pn-list-item__country js_country-name">${name}</span> <span class="pn-list-item__prefix js_country-prefix">(+${prefix})</span> </li>`; listContainer.innerHTML += element; if (index === countries.length - 1) { resolve(); } }); }); // -------------- After all the listItems are created we loop over the items to attach the eventListeners const attatchListItemEventListeners = () => new Promise((resolve, _) => { const listItems = [...document.getElementsByClassName("js_pn-list-item")]; listItems.forEach((item, index, listItems) => { item.addEventListener("click", event => { selectCountry(event); }); // Keydown event listener - https://dev.to/tylerjdev/when-role-button-is-not-enough-dac item.addEventListener("keydown", function (e) { const keyD = e.key !== undefined ? e.key : e.keyCode; if ( keyD === "Enter" || keyD === 13 || ["Spacebar", " "].indexOf(keyD) >= 0 || keyD === 32) { e.preventDefault(); this.click(); } }); if (index === listItems.length - 1) { resolve(); } }); }); // -------------- After all the listItems are created we initate list and it's listeners const initiateList = () => { countryList = new List("js_pn-select", { valueNames: ["js_country-name", "js_country-prefix"] }); // Add 'updated' listener for search results countryList.on("updated", list => { if (list.matchingItems.length < 5) listContainer.classList.toggle("pn-list--no-scroll"); noResultListItem.style.display = list.matchingItems.length > 0 ? "none" : "block"; }); }; await createList(); await attatchListItemEventListeners(); initiateList(); dropdownTrigger.addEventListener("click", () => { const isOpen = selectContainer.classList.contains("pn-select--open"); isOpen ? closeDropdown() : openDropdown(); }); }; const countries = [ { name: "Austria", prefix: 43, flag: "at" }, { name: "Belgium", prefix: 32, flag: "be" }, { name: "Bulgaria", prefix: 359, flag: "bg" }, { name: "Croatia", prefix: 385, flag: "hr" }, { name: "Cyprus", prefix: 357, flag: "cy" }, { name: "Czech Republic", prefix: 420, flag: "cz" }, { name: "Denmark", prefix: 45, flag: "dk" }, { name: "Estonia", prefix: 372, flag: "ee" }, { name: "Finland", prefix: 358, flag: "fi" }, { name: "France", prefix: 33, flag: "fr" }, { name: "Germany", prefix: 49, flag: "de" }, { name: "Greece", prefix: 30, flag: "gr" }, { name: "Hungary", prefix: 36, flag: "hu" }, { name: "Iceland", prefix: 354, flag: "is" }, { name: "Republic of Ireland", prefix: 353, flag: "ie" }, { name: "Italy", prefix: 39, flag: "it" }, { name: "Latvia", prefix: 371, flag: "lv" }, { name: "Liechtenstein", prefix: 423, flag: "li" }, { name: "Lithuania", prefix: 370, flag: "lt" }, { name: "Luxembourg", prefix: 352, flag: "lu" }, { name: "Malta", prefix: 356, flag: "mt" }, { name: "Netherlands", prefix: 31, flag: "nl" }, { name: "Norway", prefix: 47, flag: "no" }, { name: "Poland", prefix: 48, flag: "pl" }, { name: "Portugal", prefix: 351, flag: "pt" }, { name: "Romania", prefix: 40, flag: "ro" }, { name: "Slovakia", prefix: 421, flag: "sk" }, { name: "Slovenia", prefix: 386, flag: "si" }, { name: "Spain", prefix: 34, flag: "es" }, { name: "Sweden", prefix: 46, flag: "se" }]; init(countries);