Home > Software engineering >  Select dropdown value using a button click addEventListener
Select dropdown value using a button click addEventListener

Time:09-09

I am currently working with dynamic dropdowns that are populated based on values fetched from an api. I am using this jquery cascading dropdown library which works well out of the box. I am trying to figure the right way to select values of the dropdown through a button trigger event. I placed two buttons that when clicked it should select a value from the dropdown. This works well on the first click but on subsequent clicks nothing happens after. What would be the best way to achieve this?

Here is running example: https://jsfiddle.net/3jxvzrmw/2/

const editBtn = document.querySelectorAll('.editButton');
for (const button of editBtn) {
    button.addEventListener('click', (e) => {
        let make = e.target.dataset.make
        
        $("#dropdowns").cascadingDropdown({
            selectBoxes: [{
              selector: '.step1',
              source: function (request, response) {
                $.getJSON("https://private-anon-f7832ff619-carsapi1.apiary-mock.com/cars", request, function (data) {
                  response($.map(data, function (item, index) {
                    return {
                      label: item.make,
                      value: item.make,
                    };
                  }));
                }).done(function () {
                  $("#make").val(make).change();
                }).fail(function () {
                  alert("unable to load data for dropdown make");
                });
              },
            }]
        });

    });
}

CodePudding user response:

I don't know why you need to fetch data everytime you click a button. But here is the problem:

At the second click, that cascadingDropdown is applied already, so you are appling it again, then error. You need to destroy it before you can call it again. AND put it in try-catch if not you will get error for the first time (because at the first click, it doesn't load yet, then you can't destroy it).

...
let make = e.target.dataset.make

try{
   $("#dropdowns").cascadingDropdown("destroy");
}catch{}

$("#dropdowns").cascadingDropdown({
...

CodePudding user response:

You can do it like this:

(function($) {
  $('#dropdowns').cascadingDropdown({
    selectBoxes: [{
      selector: '.step1',
      source: function(request, response) {
        $.getJSON(
            'https://private-anon-f7832ff619-carsapi1.apiary-mock.com/cars',
            request,
            function(data) {
              response(
                $.map(data, function(item, index) {
                  return {
                    label: item.make,
                    value: item.make,
                  };
                })
              );
            }
          )
          .done(() => {
            $('.editButton').prop('disabled', false);
          })
          .fail(() => {
            alert('unable to load data for dropdown make');
          });
      },
    }],
  });

  $(document).on('click', '.editButton', function(e) {
    $('#make').val($(this).attr('data-make')).change();
  });
}(jQuery));
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-cascading-dropdown/1.2.9/jquery.cascadingdropdown.min.js"></script>
<button type="button"  data-make="audi" title="Car" disabled>Audi</button>
<button type="button"  data-make="bmw" title="Car" disabled>Bmw</button>

<div id="dropdowns">
  <label>Make</label>
  <select name="make" id="make" style="width:170px;" >
    <option value=""></option>
  </select>
</div>

CodePudding user response:

if I am not wrong with your expectation, then the problem is that you are re-fetching data each time you click the button. This might be the root cause.

Simply add a check flag like this:


// other code

let loaded = false // this is the flag

for (const button of editBtn) {
    button.addEventListener('click', (e) => {
        let make = e.target.dataset.make

        // wrap your code in an `if..else`
        if (loaded) { // if loaded, then just select
            $('#make').val(make).change();
        } else { // else do fetching
            $('#dropdowns').cascadingDropdown({
            selectBoxes: [{
              selector: '.step1',
              source: function (request, response) {
                $.getJSON("https://private-anon-f7832ff619-carsapi1.apiary-mock.com/cars", request, function (data) {
                  response($.map(data, function (item, index) {
                    return {
                      label: item.make,
                      value: item.make,
                    };
                  }));
                }).done(function () {

                  loaded = true // once done, mark as `loaded`

                  $("#make").val(make).change();
                }).fail(function () {
                  alert("unable to load data for dropdown make");
                });
              },
            }]
        });
                }
    });
}

  • Related