I have a International country code selection option in my site and for that I want to implement a smooth slide-down and slide-up animation toggle function to my website. In in my case both the side up and down is not working. if the slide down is working than the up is not working and if the up is working than the down is not working. that's why I need experts help to implement this animation effect.
I also found various tutorials in codepen but here also both the animation is not present. I need both slide down and up animation for my dropdown.
const countryData = [
{ name: "Afganistan", code: "93", flag: "afg" },
{ name: "Albania", code: "355", flag: "alb" },
{ name: "Algeria", code: "213", flag: "dza" },
{ name: "American Samoa", code: "1-684", flag: "asm" },
{ name: "Andorra", code: "376", flag: "and" },
{ name: "Angola", code: "244", flag: "ago" },
{ name: "Anguilla", code: "1-264", flag: "aia" },
{ name: "Antarctica", code: "672", flag: "ata" },
{ name: "Antigua and Barbuda", code: "1-268", flag: "atg" },
{ name: "Argentina", code: "54", flag: "arg" },
{ name: "Armenia", code: "374", flag: "arm" },
{ name: "Aruba", code: "297", flag: "abw" },
{ name: "Australia", code: "61", flag: "aus" },
{ name: "Austria", code: "43", flag: "aut" },
{ name: "Azerbaijan", code: "994", flag: "aze" },
{ name: "Bahamas", code: "1-242", flag: "bhs" },
{ name: "Bahrain", code: "973", flag: "bhr" },
{ name: "Bangladesh", code: "880", flag: "bgd" },
{ name: "Barbados", code: "1-246", flag: "brb" },
{ name: "Belarus", code: "375", flag: "blr" },
{ name: "Belgium", code: "32", flag: "bel" },
{ name: "Belize", code: "501", flag: "blz" },
{ name: "Benin", code: "229", flag: "ben" },
{ name: "Bermuda", code: "1-441", flag: "bmu" },
{ name: "Bhutan", code: "975", flag: "btn" },
{ name: "Bolivia", code: "591", flag: "bol" },
{ name: "Bosnia and Herzegovina", code: "387", flag: "bih" },
{ name: "Botswana", code: "267", flag: "bwa" },
{ name: "Brazil", code: "55", flag: "bra" },
{ name: "British Indian Ocean Territory", code: "246", flag: "iot" },
{ name: "British Virgin Islands", code: "1-284", flag: "vgb" },
{ name: "Brunei", code: "673", flag: "brn" },
{ name: "Bulgaria", code: "359", flag: "bgr" },
{ name: "Burkina Faso", code: "226", flag: "bfa" },
{ name: "Burundi", code: "257", flag: "bdi" },
{ name: "Cambodia", code: "855", flag: "khm" },
{ name: "Cameroon", code: "237", flag: "cmr" },
{ name: "Canada", code: "1", flag: "can" },
{ name: "Cape Verde", code: "238", flag: "cpv" },
{ name: "Cayman Islands", code: "1-345", flag: "cym" },
{ name: "Central African Republic", code: "236", flag: "caf" },
{ name: "Chad", code: "235", flag: "tcd" },
{ name: "Chile", code: "56", flag: "chl" },
{ name: "China", code: "86", flag: "chn" },
{ name: "Christmas Island", code: "61", flag: "cxr" },
{ name: "Cocos Islands", code: "61", flag: "cck" },
{ name: "Colombia", code: "57", flag: "col" },
{ name: "Comoros", code: "269", flag: "com" },
{ name: "Cook Islands", code: "682", flag: "cok" },
{ name: "Costa Rica", code: "506", flag: "cri" },
{ name: "Croatia", code: "385", flag: "hrv" },
{ name: "Cuba", code: "53", flag: "cub" },
{ name: "Curacao", code: "599", flag: "cuw" },
{ name: "Cyprus", code: "357", flag: "cyp" },
{ name: "Czech Republic", code: "420", flag: "cze" },
{ name: "Democratic Republic of the Congo", code: "243", flag: "cod" },
{ name: "Denmark", code: "45", flag: "dnk" },
{ name: "Djibouti", code: "253", flag: "dji" },
{ name: "Dominica", code: "1-767", flag: "dma" },
{ name: "Dominican Republic", code: "1-809", flag: "dom" },
/*------- MORE --------*/
];
function registerForm(formRoot) {
const ccButton = formRoot.querySelector(".cc-telcode");
const ccContainer = formRoot.querySelector(".cc-container");
const ccSearchInput = formRoot.querySelector(".cc-search-box");
const ccList = formRoot.querySelector(".cc-data-list");
let selectedCountry = "";
ccButton.addEventListener("click", handleButton);
ccSearchInput.addEventListener("input", handleInput);
ccList.addEventListener("click", handleListClick);
document.addEventListener("click", handleDocumentClick);
function handleDocumentClick(e) {
const { parentElement } = e.target;
document.addEventListener("click", (event) => {
if (!formRoot.contains(event.target)) {
ccContainer.classList.remove("show-cc-list");
}
});
}
function handleButton() {
ccContainer.classList.toggle("show-cc-list");
ccList.innerHTML = createListHtml(countryData);
}
function createListHtml(countryData) {
return countryData.map((obj) => {
const { name, code, flag } = obj;
let isSelected = "";
if (obj.name == selectedCountry) isSelected = "selected-country";
return `
<li class="cc-list-items ${isSelected}" data-name="${name}" data-code="${code}" data-flag="${flag}">
<div class="flag-icon flag-icon-${flag}"></div>
<div class="name">${name} (+${code})</div>
</li>
`;
}).join("");
}
function handleInput(e) {
const { value } = e.target;
if (value) {
const filtered = filterData(countryData, value);
if (filtered.length) {
ccList.innerHTML = createListHtml(filtered);
} else {
ccList.innerHTML = createNoDataHtml();
}
} else {
ccList.innerHTML = createListHtml(countryData);
}
}
function handleListClick(e) {
const item = e.target.closest("li") || e.target;
if (item.classList.contains("cc-list-items")) {
const { code, flag } = item.dataset;
selectedCountry = item.dataset.name;
ccButton.innerHTML = createButtonHtml(code, flag);
ccContainer.classList.remove("show-cc-list");
}
}
}
function filterData(countryData, value) {
return countryData.filter((obj) => {
return (
obj.name.toLowerCase().startsWith(value.toLowerCase()) ||
obj.code.toLowerCase().startsWith(value.toLowerCase())
);
});
}
function createButtonHtml(code, flag) {
return `
<div class="flag-icon flag-icon-${flag}"></div>
<option class="cc-code" value="+${code}">+${code}</option>
`;
}
function createNoDataHtml() {
return '<li class="no-data-found">Sorry, No Data Found</li>';
}
const contactDiv = document.querySelector(".contact-frm-cc");
registerForm(contactDiv);
.cc-telcode {
margin-bottom: 1em;
display: flex;
justify-content: center;
width: 100%;
}
.cc-telcode div.cc-code,
.cc-list-items div.name {
margin-left: 0.25em;
}
.cc-container {
display: none;
width: 300px;
position: absolute;
}
.show-cc-list {
display: block;
z-index: +999;
}
.cc-data-list {
max-height: 100px;
list-style: none;
margin: 1em 0 0 0;
padding: 0;
overflow-y: scroll;
border: 1px soldi darkgray;
}
.cc-list-items {
display: flex;
padding: 0.25em;
border: 1px solid lightgray;
}
.cc-list-items:hover {
cursor: pointer;
background-color: lightyellow;
}
.selected-country {
cursor: pointer;
background-color: rgb(73, 118, 241);
}
.contact-frm-cc {
width: 100px;
}
<link rel="stylesheet" href="https://amitdutta.co.in/flag/css/flag-icon.css">
<div class="contact-frm-cc">
<button class="cc-telcode">Tel code</button>
<section class="cc-container">
<input type="text" class="cc-search-box" placeholder="Search for country" />
<ul class="cc-data-list">
</ul>
</section>
</div>
If I understand correctly, and you need the dropdown options to show up gradually when the button is clicked, you might use the
transitionover themax-heightproperty since it will suffice and won't require more complex keyframes.https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Transitions/Using_CSS_transitions
The strategy is having your list container with
max-height: 0by default when it has theslideinclass. And when the classopenis added, gradually turns tomax-width: 100px(or any arbitrary size you'll choose for your dropdown options) with a velocity determined bytransition: max-height 1s ease-in-out;.Then with javascript you just toggle the class on the element when button is clicked:
The animation will apply also when the class is removed, thus the size will go back to zero smoothly when you click the button the second time.
I had to simplify your code to make a shorter answer and for example I used the template strategy to craft the dynamic option elements.