Skip to content

How do I prevent my html select tag from populating with duplicate data, on every click?

When I click my <select> tag, then it sends an AJAX request to the server script, which returns an array of values, which then populate the dropdown. My code is as following:

HTML:

<p id="cln_cd">Colony code :&nbsp;<select name="colony_code" id="colony_code" style="max-width:90%;" onclick="get_code()">
                <option value="" selected="selected_code">Select your colony code</option>
</select></p>

JS:

function get_code(){
    var select = document.getElementById("colony_code");

    $.ajax({
            url : 'index_backend.php',
            type : 'POST',
            data : {"input":"code"},
            success : function(response) {
                
                var parsedResponse = JSON.parse(response);
                parsedResponse = parsedResponse.filter( function( item, index, inputArray ) {
                    return inputArray.indexOf(item) == index;
                }); //removes duplicates
                
                for(var i=0; i<parsedResponse.length; i++){
                    var opt = parsedResponse[i];
                    var el = document.createElement("option");
                    el.textContent = opt;
                    el.value = opt;
                    select.appendChild(el);
                }
            },
            complete: function(){
            }
    });
}

Now, the more I press the <select> tag, the more the same data keeps on populating my dropdown menu.

As you can see, the more I click the dropdown, the more it keeps on getting populated with duplicates


To prevent this, I tried emptying my dropdown list before inserting data into it, like this:

function removeOptions(selectElement) {
    var i, L = selectElement.options.length - 1;
    for(i = L; i >= 1; i--) {
       selectElement.remove(i);
    } //only the "Select your colony code" stays as default, rest is removed
 }
 

function get_code(){
    var select = document.getElementById("colony_code");
    removeOptions(select);
    
    $.ajax({
            url : 'index_backend.php',
            type : 'POST',
            data : {"input":"code"},
            success : function(response) {
                
                var parsedResponse = JSON.parse(response);
                parsedResponse = parsedResponse.filter( function( item, index, inputArray ) {
                    return inputArray.indexOf(item) == index;
                }); //removes duplicates
                
                for(var i=0; i<parsedResponse.length; i++){
                    var opt = parsedResponse[i];
                    var el = document.createElement("option");
                    el.textContent = opt;
                    el.value = opt;
                    select.appendChild(el);
                }
            },
            complete: function(){
            }
    });
}

Now, although my dropdown is not taking in duplicate values any more, but no matter what <option> value, I press, it just shows the Select your colony code option. I have no idea as to why this is happening. How do I fix this?

Answer

Firstly you have a mix of jQuery and plain JS methods in your code. It’s best to stick to one or the other. As you’ve included the jQuery library in the page, you may as well stick with that to make the code more succinct.

With regard to the issue, I assume you’re expecting to retain the current selected item when reloading the option elements. As such you need to save that value in a variable, remove the existing option, re-populate them and then re-assign the value. The code would look something like this:

function get_code() {
  let $select = $("#colony_code");

  $.ajax({
    url: 'index_backend.php',
    type: 'POST',
    data: { "input": "code" }, // should 'code' be a variable...?
    dataType: 'json', // add this property to avoid the need to call JSON.parse in success
    success: function(response) {
      let selectedValue = $select.val();
      let html = response.filter((e, i, a) => a.indexOf(e) === i).map(item => `<option value="${item}">${item}</option>`);
      $select.html(html).val(selectedValue);
    },
    complete: function() {}
  });
}