Search code examples
javascriptjqueryhtmldropdown

Custom created dropdown onclick function not firing


I am trying to fire an on click function whenever the user selects any dropdown item, I am doing this because we cannot style the dropdown.

If a user selects any dropdown item it will update a field with its id so tht when search is selected the input value is passed. But I cannot fire the event when a user clicks on a item in the custom dropdown.

Any help is appreciated. Run the snippet and try it.

$(document).ready(function () {
	$(".dropdown-show").focus(function () {
		$(this).parent().addClass("show-dropdown");
	}).blur(function () {
		$(this).parent().removeClass("show-dropdown");
	});
	
});
function selectCountry(CountryId) {
	alert(CountryId);
}
.dropdown_menu {
	position: relative;
}

.dropdown-holder {
	background: #efefef;
	width: 250px;
	opacity: 0;
	visibility: hidden;
	overflow: hidden;
	border-width: 0 1px 1px;
	border-style: solid;
	border-color: #dcdcdc;
	position: absolute;
	top: 100%;
	left: 0;
	z-index: 15;
	transform: scaleY(0);
	transform-origin: center top 0;
	transition: opacity 0.4s ease-in-out, visibility 0.4s ease-in-out, transform 0.1s ease-in-out;
}

.dropdown_menu.show-dropdown .dropdown-holder {
	opacity: 1;
	visibility: visible;
	transform: scaleY(1);
	transition: opacity 0.4s ease-in-out 0.1s, visibility 0.4s ease-in-out 0.1s, transform 0.3s ease-in-out;
}

.dropdown_header {
	background: #3351a6;
	color: #fff;
	font: 200 13px/1.38;
	display: block;
	padding: 11px 15px;
	border-bottom: .1rem solid #d8d8d8;
	position: relative;
}

.dropdown-list {
	max-height: 200px;
	padding: 0;
	overflow-y: auto;
	overflow-x: hidden;
}

.dropdown-list li {
	border-bottom: 1px solid #dcdcdc;
	display: block !important;
	width: 100% !important;
}

.dropdown-list li:last-child {
	background: transparent !important;
	text-align: inherit !important;
	color: inherit !important;
	text-transform: capitalize !important;
	height: auto !important;
	line-height: inherit !important;
	width: auto !important;
	float: inherit !important;
}

.dropdown-list li:last-child a {
	color: inherit !important;
	font-weight: normal !important;
}

.dropdown-list a {
	color: #212529;
	display: flex;
	flex-wrap: wrap;
	justify-content: space-between;
	align-content: center;
	padding: 10px 15px;
	font-weight: 400;
}

.dropdown-list em {
	font-style: normal;
	text-align: left;
	width: 16%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<div class="resp-tab-content hor_1 resp-tab-content-active" aria-labelledby="hor_1_tab_item-0" style="display:block">
    <ul class="list-unstyled search-barlist">

        <li>
            <div class="dropdown_menu">
                <input type="text" name="country_name" class="btn dropdown-show country_name" placeholder="Nationality">
                <input type="hidden" name="country" class="country">
                <div class="dropdown-holder">
                    <p class="dropdown_header">Select your country</p>
                    <ul class="dropdown-list">

                        <li>
                            <a href="javascript:void(0);" onclick="selectCountry('1')">
                                Afghanistan
                            </a>
                        </li>

                        <li>
                            <a href="javascript:void(0);" onclick="selectCountry('2')">
                                Albania
                            </a>
                        </li>

                        <li>
                            <a href="javascript:void(0);" onclick="selectCountry('3')">
                                Algeria
                            </a>
                        </li>

                        <li>
                            <a href="javascript:void(0);" onclick="selectCountry('4')">
                                Andorra
                            </a>
                        </li>

                        <li>
                            <a href="javascript:void(0);" onclick="selectCountry('5')">
                                Angola
                            </a>
                        </li>

                        <li>
                            <a href="javascript:void(0);" onclick="selectCountry('6')">
                                Antigua and Barbuda
                            </a>
                        </li>

                        <li>
                            <a href="javascript:void(0);" onclick="selectCountry('7')">
                                Argentina
                            </a>
                        </li>

                        <li>
                            <a href="javascript:void(0);" onclick="selectCountry('8')">
                                Armenia
                            </a>
                        </li>

                        <li>
                            <a href="javascript:void(0);" onclick="selectCountry('9')">
                                Australia
                            </a>
                        </li>


                        <li>
                            <a href="javascript:void(0);" onclick="selectCountry('240')">
                                Guernsey
                            </a>
                        </li>

                        <li>
                            <a href="javascript:void(0);" onclick="selectCountry('241')">
                                Isle of Man
                            </a>
                        </li>

                        <li>
                            <a href="javascript:void(0);" onclick="selectCountry('242')">
                                Jersey
                            </a>
                        </li>

                        <li>
                            <a href="javascript:void(0);" onclick="selectCountry('243')">
                                Montenegro
                            </a>
                        </li>

                        <li>
                            <a href="javascript:void(0);" onclick="selectCountry('244')">
                                Saint Martin
                            </a>
                        </li>

                        <li>
                            <a href="javascript:void(0);" onclick="selectCountry('245')">
                                Mayotte
                            </a>
                        </li>

                        <li>
                            <a href="javascript:void(0);" onclick="selectCountry('246')">
                                Sint Maarten
                            </a>
                        </li>

                        <li>
                            <a href="javascript:void(0);" onclick="selectCountry('247')">
                                South Sudan
                            </a>
                        </li>
                    </ul>
                </div>
            </div>
        </li>
        <li>
            <button type="submit" class="btn btn-primary wrn-btn">Search</button>
        </li>
    </ul>
</div>


Solution

  • When show-dropdown class is removed by

    .blur(function () {
      $(this).parent().removeClass("show-dropdown");
    })
    

    code, each list's a element within dropdown starts to shrink up with transform: scaleY(0) CSS rule, which takes 0.1 second (transition: ..., ..., transform 0.1s ease-in-out;). So, what actually happens, when user clicks on a element, it is already on its way up to be hidden, thus js script not executed.

    There are 3 solutions that I can see:

    1. add setTimeout to the blur event, something like:

      .blur(function () {
        setTimeout(_ => $(this).parent().removeClass("show-dropdown"), 500);
      })
      
    2. Remove both transform: scaleY(0) and transform: scaleY(1) CSS rules

    3. Increase transition time for transform, something like:

      transition: opacity 0.4s ease-in-out, visibility 0.4s ease-in-out, transform 0.5s ease-in-out;
      

      (transform 0.1s ease-in-out changed to transform 0.5s ease-in-out)

    Also, you do not need to assign transition under .dropdown_menu.show-dropdown .dropdown-holder selector, assigning it under .dropdown_menu .dropdown-holder is enough.

    I would go with my second solution - removing CSS rules