WEBLEB
Home
Editor
Accedi
Pro
Italiano
English
Français
Español
Português
Deutsch
Italiano
हिंदी
1108
Andev.web
Apri nell'Editor
Pubblica il Tuo Codice
Consigliato
10 September 2024
LETTORE MUSICALE
16 February 2025
Un codice di NotYoEA
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);