Aks
Aks

Reputation: 112

Select drop-down and styling it's options

I want my select box and the options drop down to be styled as shown in the image below. Please help me with the same. If only CSS can do that it would be great, else a javascript solution. Thanks in advance.

Current select drop-down

New Requirement

I am very new to Javascript and the front-end technologies. Currently, the below code is being used for the select box and getting it's options.

                        <div class="selectWrapper">
                                <label for="ext-comp-1001" class="inputLabel"><span class="required">*</span><fmt:message key="registration.country"/></label> 
                                <div class="x-form-element" id="x-form-el-ext-comp-1001">
                                    <input id="brand" name="spEntityID" type="hidden" value="<%=spEntityID%>" />
                                    <select autocomplete="off" id="ext-comp-1001" name="country" value="" class=" x-form-select-one x-form-field select_one select_one" onchange="changeStateList()"></select>
                                </div>
                            </div>

In the above code some Javascript code brings all the countries and the Javascript code for it is all written in hexadecimal(UTF-8). Can I achieve this without touching the existing Javascript code which is difficult to decrypt and implement all the functionalities.

Upvotes: 0

Views: 184

Answers (1)

ThS
ThS

Reputation: 4783

To achieve your task, you'll need some JavaScript along with a touch of CSS.

I prepared a demo for you so you can build on it even though it does include all the functionalities you want (I mean you'll probably not going to add that much as I had it all done for you).

So, how we'll we proceed :

  • Firstly, we'll prepare our HTML (especially the select element) as usual and we'll add another element that will host the new or the custom select which has :

    • an element to show the selected option's text.
    • an element that represents an arrow on the right (as that one which appears in the image included in the question).
    • an element to wrap the options (JavaScript will populate that element along with changing the selected element text accordingly).
  • populate the custom select with based on the "real" select options.

  • change the custom select text with the selected option with JavaScript.

The next example illustrates what's being said, also it has some helpful comments :

/** select the elements that are going to build the main functionalities of this task **/
const select = document.getElementById("select-box"),
  realOptions = select.options,
  customSelect = document.getElementById("custom-select"),
  selectedText = customSelect.querySelector(".selected-option-text"),
  optionsContainer = customSelect.querySelector(".options-container");
let idx = 0; /** this will help us get the correct index of the option when assigning the click event listener to the newly added custom options **/

/** add click listener to the custom "select" to open the custom options container **/
customSelect.addEventListener("click", () =>
  optionsContainer.classList.add("visible")
);


/** looping through the "option" elements of the real "select" **/
[...realOptions].forEach(el => {
  let currIdx = idx++; /** that will help us change the selected "option" on the real "select" eleement **/
  /** if the current real "option" is not disabled we add a custom one (in the custom "select") **/
  if (el.disabled === false) {
    /** create a new "p" element that will act as an "option" **/
    const customOption = document.createElement("p");
    customOption.classList.add("custom-option");
    /** the text of the "p" element is the same as the current (we're in a loop !) real "option" element **/
    customOption.textContent = el.textContent;
    /** add click listener to the "p" element that handles the click on a custom option which is the "p" element **/
    customOption.addEventListener("click", e => {
      /** the event doesn't propagate to the parent element to prevent the custom "select" from staying opened always (remember the click listener above for the parent (the custom "select")) **/
      e.stopPropagation();
      optionsContainer.classList.remove("visible");
      realOptions.selectedIndex = currIdx;
      selectedText.textContent = el.textContent;
    });
    /** add the "p" element which acts as an "option" to the custom "select" **/
    optionsContainer.append(customOption);
  }
});
* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

/** for demo purposes **/
select#select-box {
  display: block;
  margin-bottom: 25px;
}

.custom-select {
  position: relative;
  max-width: 50%; /** changes this per your requirements it's not that necessary **/
  padding-right: 10px;
  border: 2px solid #595859;
  border-radius: 6px;
  cursor: pointer;
}

.custom-select .arrows {
  position: absolute;
  top: 50%;
  right: 6px;
  transform: translate3d(0, -50%, 0);
  font-size: 0.75rem;
}

.custom-select .arrows>.fa {
  display: inline-block;
  vertical-align: middle;
}

.custom-select .selected-option-text {
  padding: 8px 6px;
  color: #595859;
  font-weight: bold;
}

.custom-select .options-container {
  display: none;
  position: absolute;
  width: 98%;
  max-height: 250px;
  top: 8px;
  left: 0;
  right: 0;
  margin: auto;
  overflow-x: hidden;
  overflow-y: auto;
  background-color: #595859;
  color: #f5f5f5;
  border-radius: 4px;
}

.custom-select .options-container.visible {
  display: block;
}

.custom-select .options-container>.custom-option {
  padding: 4px;
  cursor: default;
  transition: all .2s 0s ease;
}

.custom-select .options-container>.custom-option:hover {
  background-color: #ca2128;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.9.0/css/all.min.css" />
<select id="select-box">
  <option value="" disabled selected>select option</option>
  <option value="1">option 1</option>
  <option value="2">option 2</option>
  <option value="3">option 3</option>
  <option value="4">option 4</option>
  <option value="5">option 5</option>
  <option value="6">option 6</option>
  <option value="7">option 7</option>
  <option value="8">option 8</option>
  <option value="9">option 9</option>
  <option value="10">option 10</option>
</select>

<!-- nothing too fancy here just the "#custom-select" elemnt that will contain the custom select -->
<div id="custom-select" class="custom-select">
  <div class="selected-option-text">Please select an option</div>
  <div class="arrows">
    <i class="fa fa-sort"></i>
  </div>
  <div class="options-container"></div>
</div>

You can customize that example to more fulfill your wanted end result.

I also didn't hide the real select so you can see it changes based on the option you select on the custom one.

I'm here for any clarification you want.

Hope I pushed you further.

Upvotes: 1

Related Questions