Having difficulty managing the responses of two separate <select> elements with images in jQuery

I recently started using online jQuery to manage images within the "select" element of my HTML code. However, I've encountered a problem where events on each individual "select" element are not being separated correctly.

var selectedId = "";
      var langArray = [];
      $(".box").each(function () {
        selectedId = $(this).attr("id");
        $(this)
          .find(".vodiapicker option")
          .each(function () {
            var img = $(this).attr("data-thumbnail");
            var text = this.innerText;
            var value = $(this).val();
            var item =
              '<li><img src="' +
              img +
              '" alt="" value="' +
              value +
              '"/><span>' +
              text +
              "</span></li>";
            langArray.push(item);
          });

        $(this).find("#a").html(langArray);

        //Set the button value to the first el of the array
        $(this).find(".btn-select").html(langArray[0]);
        $(this).find(".btn-select").attr("value", "en");
      });
      //change button stuff on click
      $("li").click(function () {
        var img = $(this).find("img").attr("src");
        var value = $(this).find("img").attr("value");
        var text = this.innerText;
        var item =
          '<li><img src="' + img + '" alt="" /><span>' + text + "</span></li>";
        $(".btn-select").html(item);
        $(".btn-select").attr("value", value);
        $(".b").toggle();
        //console.log(value);
      });

      $(".btn-select").click(function () {
        $(".b").toggle();
      });

      //check local storage for the lang
      var sessionLang = localStorage.getItem("lang");
      if (sessionLang) {
        //find an item with value of sessionLang
        var langIndex = langArray.indexOf(sessionLang);
        $(".btn-select").html(langArray[langIndex]);
        $(".btn-select").attr("value", sessionLang);
      } else {
        var langIndex = langArray.indexOf("ch");
        $(".btn-select").html(langArray[langIndex]);
        //$('.btn-select').attr('value', 'en');
      }
      .vodiapicker {
        display: none;
      }

      #a {
        padding-left: 0px;
      }

      #a img,
      .btn-select img {
        width: 18px;
      }

      #a li {
        list-style: none;
        padding-top: 5px;
        padding-bottom: 5px;
      }

      #a li:hover {
        background-color: #f4f3f3;
      }

      #a li img {
        margin: 5px;
      }

      #a li span,
      .btn-select li span {
        margin-left: 30px;
      }

      /* item list */

      .b {
        display: none;
        width: 100%;
        max-width: 350px;
        box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
        border: 1px solid rgba(0, 0, 0, 0.15);
        border-radius: 5px;
      }

      .open {
        display: show !important;
      }

      .btn-select {
        margin-top: 10px;
        width: 100%;
        max-width: 350px;
        height: 34px;
        border-radius: 5px;
        background-color: #fff;
        border: 1px solid #ccc;
      }

      .btn-select li {
        list-style: none;
        float: left;
        padding-bottom: 0px;
      }

      .btn-select:hover li {
        margin-left: 0px;
      }

      .btn-select:hover {
        background-color: #f4f3f3;
        border: 1px solid transparent;
        box-shadow: inset 0 0px 0px 1px #ccc;
      }

      .btn-select:focus {
        outline: none;
      }

      .lang-select {
        margin-left: 50px;
      }
<script
      src="https://code.jquery.com/jquery-3.6.0.min.js"
      integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4="
      crossorigin="anonymous"
    ></script>
<div class="box" id="one">
      <select class="vodiapicker">
        <option>Select one</option>
        <option value="en" class="test" data-thumbnail="images/3.png">
          English
        </option>
        <option value="au" data-thumbnail="images/3.png">Engllish (AU)</option>
      </select>

      <div class="lang-select">
        <button class="btn-select" value=""></button>
        <div class="b">
          <ul id="a"></ul>
        </div>
      </div>
    </div>
    <div class="box" id="two">
      <select class="vodiapicker">
        <option>Select one</option>
        <option value="en" class="test" data-thumbnail="images/3.png">
          french
        </option>
        <option value="au" data-thumbnail="images/3.png">french F</option>
      </select>

      <div class="lang-select">
        <button class="btn-select" value=""></button>
        <div class="b">
          <ul id="a"></ul>
        </div>
      </div>
    </div>

Upon clicking on a select element, both elements open simultaneously and additionally, the HTML content is displayed separately for each div. However, when selecting dropdown two, it also displays the content from dropdown one.

Answer №1

This solution should work:

If you want to customize the image on the button and use CSS to add it, you may need to do so in order to prevent the button from being blocked by other elements like the text.

$(function() {
  $(".box").each(function() {
    let selectedId = "";
    let langArray = [];
    selectedId = $(this).attr("id");
    $(this)
      .find(".vodiapicker option")
      .each(function() {
        let img = $(this).attr("data-thumbnail");
        let text = this.innerText;
        let value = $(this).val();
        let item =
          '<li><img src="' +
          img +
          '" alt="" value="' +
          value +
          '"><span>' +
          text +
          "</span></li>";
        langArray.push(item);
      });

    $(this).find("#a").html(langArray);
    //Set the button value to the first el of the array
    $(this).find(".btn-select").html(langArray[0]);
    $(this).find(".btn-select").attr("value", "en");
  });
  $(document).click(function() {
    if ($(event.target).is("button.btn-select") === false) {
      $(".box").each(function() {
        if ($(this).find(".b").is(':visible')) {
          $(this).find(".b").toggle();
        }
      })
    }
  })
  $("li").click(function() {
    let img = $(this).find("img").attr("src");
    let value = $(this).find("img").attr("value");
    let text = this.innerText;
    let item =
      '<li><img src="' + img + '" alt="" /><span>' + text + "</span></li>";
    $(this).parents("div.lang-select").find(".btn-select").html(item);
    $(this).parents("div.lang-select").find(".btn-select").attr("value", value);
    $(this).parents("div.lang-select").find(".b").toggle();
  });

  $(".btn-select").click(function() {
    $(this).parents("div.lang-select").find(".b").toggle();
    if (($(this).parents("div, .box")[1].id === "two") &&
      ($("#one").children("div.lang-select").find(".b").is(':visible'))) {
      $("#one").children("div.lang-select").find(".b").toggle();
    } else if (($(this).parents("div, .box")[1].id === "one") &&
      ($("#two").children("div.lang-select").find(".b").is(':visible'))) {
      $("#two").children("div.lang-select").find(".b").toggle();
    }
  });
});
.vodiapicker {
  display: none;
}

#a {
  padding-left: 0px;
}

#a img,
.btn-select img {
  width: 18px;
}

#a li {
  list-style: none;
  padding-top: 5px;
  padding-bottom: 5px;
}

#a li:hover {
  background-color: #f4f3f3;
}

#a li img {
  margin: 5px;
}

#a li span,
.btn-select li span {
  margin-left: 30px;
}


/* item list */

.b {
  display: none;
  width: 100%;
  max-width: 350px;
  box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
  border: 1px solid rgba(0, 0, 0, 0.15);
  border-radius: 5px;
}

.open {
  display: show !important;
}

.btn-select {
  margin-top: 10px;
  width: 100%;
  max-width: 350px;
  height: 34px;
  border-radius: 5px;
  background-color: #fff;
  border: 1px solid #ccc;
}

.btn-select li {
  list-style: none;
  float: left;
  padding-bottom: 0px;
}

.btn-select:hover li {
  margin-left: 0px;
}

.btn-select:hover {
  background-color: #f4f3f3;
  border: 1px solid transparent;
  box-shadow: inset 0 0px 0px 1px #ccc;
}

.btn-select:focus {
  outline: none;
}

.lang-select {
  margin-left: 50px;
}
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
<div class="box" id="one">
  <select class="vodiapicker">
    <option>Select one</option>
    <option value="en" class="test" data-thumbnail="images/3.png">
      English
    </option>
    <option value="au" data-thumbnail="images/3.png">Engllish (AU)</option>
  </select>

  <div class="lang-select">
    <button class="btn-select" value=""></button>
    <div class="b">
      <ul id="a"></ul>
    </div>
  </div>
</div>
<div class="box" id="two">
  <select class="vodiapicker">
    <option>Select one</option>
    <option value="en" class="test" data-thumbnail="images/3.png">
      french
    </option>
    <option value="au" data-thumbnail="images/3.png">french F</option>
  </select>

  <div class="lang-select">
    <button class="btn-select" value=""></button>
    <div class="b">
      <ul id="a"></ul>
    </div>
  </div>
</div>

I trust that these instructions are helpful!

Answer №2

Hopefully, this solution will be effective for you

$(".box").each(function() {
  let selectedId = "";
  let langArray = [];
  selectedId = $(this).attr("id");
  $(this)
    .find(".vodiapicker option")
    .each(function() {
      let img = $(this).attr("data-thumbnail");
      let text = this.innerText;
      let value = $(this).val();
      let item =
        '<li><img src="' +
        img +
        '" alt="" value="' +
        value +
        '"/><span>' +
        text +
        "</span></li>";
      langArray.push(item);
    });

  $(this).find("#a").html(langArray);
  //Set the button value to the first el of the array
  $(this).find(".btn-select").html(langArray[0]);
  $(this).find(".btn-select").attr("value", "en");
});
//change button stuff on click
$("li").click(function() {
  let img = $(this).find("img").attr("src");
  let value = $(this).find("img").attr("value");
  let text = this.innerText;
  let item =
    '<li><img src="' + img + '" alt="" /><span>' + text + "</span></li>";

  $(this).parents("div.lang-select").find(".btn-select").html(item);
  $(this).parents("div.lang-select").find(".btn-select").attr("value", value);
  $(this).parents("div.lang-select").find(".b").toggle();
  //console.log(value);
});

$(".btn-select").click(function() {
  $(this).parents("div.lang-select").find(".b").toggle();
});
.vodiapicker {
  display: none;
}

#a {
  padding-left: 0px;
}

#a img,
.btn-select img {
  width: 18px;
}

#a li {
  list-style: none;
  padding-top: 5px;
  padding-bottom: 5px;
}

#a li:hover {
  background-color: #f4f3f3;
}

#a li img {
  margin: 5px;
}

#a li span,
.btn-select li span {
  margin-left: 30px;
}


/* item list */

.b {
  display: none;
  width: 100%;
  max-width: 350px;
  box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
  border: 1px solid rgba(0, 0, 0, 0.15);
  border-radius: 5px;
}

.open {
  display: show !important;
}

.btn-select {
  margin-top: 10px;
  width: 100%;
  max-width: 350px;
  height: 34px;
  border-radius: 5px;
  background-color: #fff;
  border: 1px solid #ccc;
}

.btn-select li {
  list-style: none;
  float: left;
  padding-bottom: 0px;
}

.btn-select:hover li {
  margin-left: 0px;
}

.btn-select:hover {
  background-color: #f4f3f3;
  border: 1px solid transparent;
  box-shadow: inset 0 0px 0px 1px #ccc;
}

.btn-select:focus {
  outline: none;
}

.lang-select {
  margin-left: 50px;
}
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
<div class="box" id="one">
  <select class="vodiapicker">
    <option>Select one</option>
    <option value="en" class="test" data-thumbnail="images/3.png">
      English
    </option>
    <option value="au" data-thumbnail="images/3.png">Engllish (AU)</option>
  </select>

  <div class="lang-select">
    <button class="btn-select" value=""></button>
    <div class="b">
      <ul id="a"></ul>
    </div>
  </div>
</div>
<div class="box" id="two">
  <select class="vodiapicker">
    <option>Select one</option>
    <option value="en" class="test" data-thumbnail="images/3.png">
      french
    </option>
    <option value="au" data-thumbnail="images/3.png">french F</option>
  </select>

  <div class="lang-select">
    <button class="btn-select" value=""></button>
    <div class="b">
      <ul id="a"></ul>
    </div>
  </div>
</div>

I trust that this information is beneficial

Answer №3

Consider the following.

$(function() {
  function convertSelect(target) {
    var opts = $("option", target);
    var container = $("<div>", {
      class: "ui-selectmenu"
    }).insertAfter(target);
    // Move original inside container
    $(target).detach().appendTo(container).hide();

    var list = $("<ul>", {
      class: "ui-selectmenu-list collapsed"
    }).appendTo(container);
    opts.each(function(i, o) {
      // Make List Option
      $("<li>", {
        class: "ui-selectmenu-option"
      }).data("value", $(o).val()).html("<span>" + $(o).text() + "</span>").appendTo(list);
      // Select Original selected item
      if ($(o).is(":selected")) {
        $("li:last", list).addClass("selected");
      }
      // Add Thumbnail, if present
      if ($(o).data("thumbnail") != undefined) {
        $("li:last span", list).before("<img src='" + $(o).data("thumbnail") + "' alt='" + $(o).val() + "' />");
      }
    });

    if ($(".selected", list).length == 0) {
      // Default to Item 0 if none is selected in Original
      $("li", list).eq(0).addClass("selected");
    }
    // Psudeo Collapse
    $("li:not('.selected')", list).hide();

    $("li", list).click(function(event) {
      if ($(this).hasClass("selected") && list.hasClass("collapsed")) {
        // Exapnd Menu
        list.removeClass("collapsed");
        $("li", list).show();
        return false;
      }
      if ($(this).hasClass("selected") && !list.hasClass("collapsed")) {
        // Same Item selected, collapse
        $("li:not('.selected')", list).hide();
        list.addClass("collapsed");
        console.log("Selected", $(".selected", list).data("value"));
        return false;
      }
      // Menu Expanded, new Item selected
      $(".selected", list).removeClass("selected");
      $(this).addClass("selected");
      $("li:not('.selected')", list).hide();
      list.addClass("collapsed");
      console.log("Selected", $(".selected", list).data("value"));
    });
  }

  $(".vodiapicker").each(function() {
    convertSelect(this);
  });

});
.ui-selectmenu {
  background: #fff;
  width: 350px;
}

.ui-selectmenu-list {
  padding-left: 0px;
  margin-top: 10px;
  width: 100%;
  border-radius: 5px;
  border: 1px solid #ccc;
  z-index: 1001;
}

.ui-selectmenu-list li {
  background: #fff;
  list-style: none;
  padding-top: 5px;
  padding-bottom: 0px;
}

.ui-selectmenu-list li:hover {
  background-color: #f4f3f3;
}

.ui-selectmenu-list li img {
  width: 18px;
  margin: 5px;
}

.ui-selectmenu-list li span {
  margin-left: 30px;
}
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>

<select class="vodiapicker">
  <option>Select One</option>
  <option value="en" class="test" data-thumbnail="images/3.png">English</option>
  <option value="au" data-thumbnail="images/3.png">Engllish (AU)</option>
</select>

<select class="vodiapicker">
  <option>Select One</option>
  <option value="en" class="test" data-thumbnail="images/3.png">french</option>
  <option value="au" data-thumbnail="images/3.png">french F</option>
</select>

This code implementation functions as intended with added jQuery functionality for hiding and styling select elements within a styled menu structure.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

A guide on utilizing ClassName to insert new items into a DIV

Original HTML code: <span class="specLink"> <specialty><a title="Plastic Surgery" href="link2.aspx">Plastic Surgery</a></specialty> </span> <br /> <span class="specLink"> <specialty2><a titl ...

Issue with Angular 2 NgFor Pattern Error Message Display Absence

I am attempting to incorporate inputs with a regex requirement within an ngFor loop, but I am not receiving the expected error message when entering something that does not match the required pattern. Even when I input an incorrect pattern, "Test" remains ...

I am unable to view the GridView features that have been set using jQuery in the JavaScript code on the webpage

I'm facing an issue with the properties of a GridView. On the aspx page, I have a container using a <div>. <div id="DivRecords"> Within this container, I am dynamically adding a GridView using jQuery. In the js file, I am creating the Gr ...

Is it considered acceptable to employ an endless loop to continually monitor the connection to a server?

Today marks the beginning of my journey in creating an Angular App. My goal is to establish a connection to a server and display a message on screen if the connection is offline, prompting the user to check their network settings. I currently have a JavaSc ...

What is the best way to reduce the width of the navigation bar?

I've been working on creating a website for my friend, and I decided to include a table navigation bar to make it easier to navigate. Instead of duplicating the code, I separated the bar code into another file and used JavaScript to load it into each ...

When a text is wrapped by an HTML div using absolute positioning, is there a way to prevent it from wrapping without relying on white space

I have a group of div elements positioned absolutely on the screen. If any div contains content that is too big for the screen, the browser wraps it into multiple lines to fit. However, I do not want this behavior. Instead, I want the overflowing content ...

Tips for customizing the calendar icon on a date input in Firefox versions greater than 108

Prior to version 109, Firefox allowed for the selection of the date picker's icon similar to Chromium: input[type="date"]::-webkit-calendar-picker-indicator { display: none; /* Hides the icon in Chrome and Firefox < v109 */ } This func ...

Error in the Angular-UI calendar

I'm encountering an issue while trying to set up the angular-ui calendar. When I run it, I get the following error: TypeError: undefined is not a function at Object.eventsWatcher.onChanged (http://localhost/fisioGest/js/calendar.js:262:41) Despite b ...

Issues identified with High Charts functionality

I visited a helpful link to learn how to create bar graphs using the HighCharts Charting library. While it works perfectly on jsfiddle, I encountered an issue when trying to build an HTML file with the code as it doesn't display anything. Below is m ...

Navigation Menu in Motion

I'm currently working on a website for my F1 in Schools team and I'm looking to implement a feature where the button in the navigation bar changes its background color and font color when that section of the page is active, even while scrolling o ...

Django was unable to load the static image

Currently, my Django application is hosted on PythonAnywhere. In order to generate a PDF, I am utilizing WeasyPrint which includes an image that should be displayed in the PDF. However, within the error log, I am encountering the message "Failed to load im ...

What is the best way to integrate my company's global styles CDN for development purposes into a Vue cli project using Webpack?

After attempting to import through the entry file (main.js)... import Vue from 'vue' import App from '@/App' import router from '@/router/router' import store from '@/store/store' import BootstrapVue from 'boot ...

Which is quicker: making a jQuery GET request or using Angular's $http.get method

Recently, I came across an interesting observation while working on my angular app. I noticed that replacing $http.get calls with jQuery ajax calls significantly boosted the speed of the application. This made me wonder if jQuery calls are actually faster ...

Creating an interactive map on WordPress: A step-by-step guide

I have successfully created a clickable image on Codepen <div style="width: 1000px; height: 993.73px;"> <img src="https://www.dyfedarchaeology.org.uk/wp/wp-content/uploads/Testmap.svg" alt=&q ...

Creating a string-based template that can be included in Django

I need to create a list of clickable links for my navigation bar with the URLs provided using the url-tag. To achieve this, I have a list of dictionaries containing all the necessary information for each link, and I am creating a template string with them ...

Differences between encoding URL variables in HREF and using JS window.location for onclick events

For some reason, this particular hyperlink is not functioning properly. I have a Javascript redirect (window.opener.location) where I pass several variables through the URL. The problem arises when these variables contain apostrophes. In PHP, I am using UR ...

Code snippet causing element block JavaScript malfunction

I'm attempting to create a basic automatic slideshow using JavaScript. let currentIndex = 0; startSlideshow(); function startSlideshow() { let slides = document.getElementsByClassName("slide"); for (let i = 0; i < slides.length; i++) { ...

Tips on preventing the insertion of special characters into a form field with the help of jQuery

I'm implementing a feature to restrict users from using special characters in the text input field. While I have successfully prevented users from typing these characters, I am also looking to prevent the pasting of any special characters as well. FID ...

Flexbox columns with equal widths for Internet Explorer

I am currently working on a flexbox column layout that needs to be compatible with IE10. One issue I have encountered is that IE tends to expand a flex child based on its contents, while other browsers keep each flexbox at an equal width. To address this ...

The AJAX data submission did not go through as expected

I am facing an issue with two files on my site - home.php (view) and home.php (controller). In the home.php (view) file, I have a jQuery function that sends an AJAX request based on the W3 example. However, in the home.php (controller) file, the PHP variab ...