skip to Main Content

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");
                });
              },
            }]
        });

    });
}

3

Answers


  1. 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({
    ...
    
    Login or Signup to reply.
  2. 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" class="editButton" data-make="audi" title="Car" disabled>Audi</button>
    <button type="button" class="editButton" data-make="bmw" title="Car" disabled>Bmw</button>
    
    <div id="dropdowns">
      <label>Make</label>
      <select name="make" id="make" style="width:170px;" class="step1">
        <option value=""></option>
      </select>
    </div>
    Login or Signup to reply.
  3. 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");
                    });
                  },
                }]
            });
                    }
        });
    }
    
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search