Search code examples
javascripthtmljqueryjquery-ui-selectmenu

Is it possible to create a custom object as a replacement for a HTML select?


I'm a little new to Javascript and I was wondering if it is possible to create a custom 3-column <div> or another object to replace <option> in my select menu as shown in the image below. I would like an image, the name of the option, and then another detail like an ID. Is this possible?

I know I can use Jquery's select2 to have an image and a string, but I'm not quite sure where to begin to get the third column.


Solution

  • Hopefully, this helps someone and any critiques are welcome. Here is the full code and then I will break it down into pieces.

    <!DOCTYPE html>
    <html>
      <head>
    
      <meta name="viewport" content="width=device-width, initial-scale=1">
        <style>
    
            .col{
              display: flex;
              flex-direction: column;
            }
            .col20{
              text-align: center;
              flex: 20%;
              margin: auto;
              display: flex;
              flex-direction: column;
              padding: 5px 0px;
            }
            .col40{
              text-align: center;
              flex: 40%;
              margin: auto;
              display: flex;
              flex-direction: column;
              padding: 5px 0px;
            }
            .leftCol{
                text-align: center;
                padding-right: 10px;
                flex: 25%;
                display: flex;
                flex-direction: column;
                }
            .rightCol{
                background-color: white;
                text-align: center;
                flex: 75%;
                flex-grow: 1;
                display: flex;
                flex-direction: column;
                }
            .row {
              display: flex;
              flex-wrap: nowrap;
              margin: 0;
              /* flex-grow: 1; */
            }
            .selectableDiv{
                border:1px solid black ;
                background-color:white;
            }
            .selectableDiv:not(:last-child){
                border-bottom: 0px;
            }
            .activeDiv, .selectableDiv:hover {
                background-color: lightblue;
            }
        </style>
    </head>
    
    <body >
      <div class="row" style="padding-bottom: 5%;">
        <div class="leftCol" style="text-align: center;" >
            <div class="row selectableDiv">
                <div class="col20">Picture</div>
                <div class="col40">Name</div>
                <div class="col20">ID</div>
            </div>
            <div class="row selectableDiv">
                <div class="col20"><img src="https://fakeimg.pl/75x75/?text=Image1" style=" margin: auto;"></div>
                <div class="col40">John</div>
                <div class="col20">52343</div>
            </div>
            <div class="row selectableDiv">
                <div class="col20"><img src="https://fakeimg.pl/75x75/?text=Image2" style="margin: auto;"></div>
                <div class="col40">Jane</div>
                <div class="col20">12345</div>
            </div>
        </div>
        <div class="rightCol">
        </div>
      </div>
    
    <script>
        var selectedDiv;
        var selectableDivs = document.getElementsByClassName("selectableDiv");
    
        var i;
    
        for (i = 0; i < selectableDivs.length; i++) {
            selectableDivs[i].addEventListener("click", function() {
                console.log("Click");
                //Toggle this specific div to be "activeDiv"
                this.classList.toggle("activeDiv");
                if (selectedDiv != null){
                    selectedDiv.classList.remove("activeDiv"); //Remove activeDiv class from previous active div if exists
                }
                selectedDiv = this;                     // Set selectedDiv to this one
          });
        }
    
    </script>
    
    </body>
    </html>
    

    For the styling, I used flexbox to create the columns and rows. I'm certain there is room to improve when it comes to styling since I am still pretty new to CSS. I gave the divs that I wanted to be options a special class I called "selectableDiv" with a black border and a white background.

    .selectableDiv{
        border:1px solid black ;
        background-color:white;
        }
    

    I created another CSS class for the selected divs called "activeDiv". I gave it a different background color along with the hover effect for the selectableDiv.

    .activeDiv, .selectableDiv:hover {
        background-color: lightblue;
        }
    

    Then using JavaScript I initialized a variable selectedDiv to be my selected Dvi.got all of the elements with the class "selectable div" var selectableDivs = document.getElementsByClassName("selectableDiv");

    Then I looped through each selectable div and assigned a click event listener, when upon clicked will toggle the activeDiv class for the clickedDiv. It will then remove the activeDiv class from any previous selectedDiv (if it exists) and then assign the variable selectedDiv to be the clicked div.

    var i;
    
    for (i = 0; i < selectableDivs.length; i++) {
        selectableDivs[i].addEventListener("click", function() {
            //Toggle this specific div to be "activeDiv"
            this.classList.toggle("activeDiv");
            if (selectedDiv != null){
                selectedDiv.classList.remove("activeDiv"); //Remove activeDiv class from previous active div if exists
            }
            selectedDiv = this;                     // Set selectedDiv to this one
          });
        }