Soon Hang
Soon Hang

Reputation: 91

Why is my selectpicker field not updating the options visually?

I have 2 different select fields on my web application. The 2nd select field is a select picker field and the options will changed based on the selected value in the 1st select field. No matter how many times i tried to update the select picker, the options still does not update accordingly to the first select field. In the background, the data were fetched and populated into the select picker, just that it is not display it.

I wrote a short java script to help fetch new corresponding values for the select picker field according to the first select field. But the displayed options are not updating

HTML + Javascript

<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css">
        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.13.1/css/bootstrap-select.css" />
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
        <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.bundle.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.13.1/js/bootstrap-select.min.js"></script>
        <script src="https://code.jquery.com/jquery-3.3.1.js"></script>
        <script src="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css"></script>  

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <form method="POST">

        <select id="col1" onchange="refreshList();">
            {% for c in cols: %}
                <option value="{{c}}">{{c}}</option>
            {% endfor %}
        </select>
        <select id ="val1" class="selectpicker" multiple data-live-search="true">
            {% for uv in unique_val: %}
                <option value="{{uv}}">{{uv}}</option>
            {% endfor %}
        </select>
        <input type="submit">
    </form>
    <script>
        function refreshList(){
            var col_select = document.getElementById('col1');
            var uv_select = document.getElementById('val1');

            column = col_select.value;

            fetch('/col/' + column).then(function(response) {
                response.json().then(function(data) {
                    var optionHTML = '';
                    for (var uv of data.unique_val) {
                        optionHTML += '<option value="' + uv.id + '">' + uv.value + '</option>';
                    }
                    uv_select.innerHTML = optionHTML;

                })
            });
        }   
    </script>
    <script>
        $('#col1').on('change','#val1', function(){
             $('#val1').selectpicker('refresh'));
        });

    </script>
</body>
</html>

Expected: Options in select picker will update and display according to the value fetched from the system.

Actual: Options are fetched successfully but are not added into the the list of options of my select picker, newly fetched values only appear behind the previous set of options.

Upvotes: 2

Views: 5063

Answers (1)

yunzen
yunzen

Reputation: 33439

First: I had to simulate your fetch code since I don't know the response json

There are some issues with your code.

  1. Your code

    $('#col1').on('change','#val1', function(){
    $('#val1').selectpicker('refresh'));
    });

    Doesn't do anything.
    a) The change event only is triggered, if you select a different option than the currently selected. What you need is called mutation observer, which is a little bit more complicated. In my solution I just trigger the change event manually. $('#val1').trigger('change');
    b) You seem to have a slight misconception about jQuery on() method. What you code does is: If the #col1 select catches an event, which is triggered from the #val1 select, do this-and-that. But this will never happen. Any event on the #val1 will bubble up the DOM, but never sideways.

  2. You have two scripts which import jQuery. The later one will wipe out selectpicker methods
    <script src="https://code.jquery.com/jquery-3.3.1.js"></script>

console.clear()

function refreshList(e) {
  var col_select = document.getElementById('col1');
  var uv_select = document.getElementById('val1');

  column = col_select.value;


  var new_uv_list = [
    [{
        id: "01",
        value: "Zero One",
      },
      {
        id: "02",
        value: "Zero Two",
      },
    ],
    [{
      id: "11",
      value: "One One",
    }, ],
    [{
        id: "11",
        value: "Two One",
      },
      {
        id: "12",
        value: "Two Two",
      },
    ],
    [{
        id: "33",
        value: "Three Three",
      },
      {
        id: "36",
        value: "Three Six",
      },
      {
        id: "39",
        value: "Three Nine",
      },
    ],
  ]

  //  fetch('/col/' + column).then(function(response) {
  //    response.json().then(function(data) {
  var optionHTML = '';
  //      for (var uv of data.unique_val) {
  if (new_uv_list[column]) {
    for (var uv of new_uv_list[column]) {
      optionHTML += '<option value="' + uv.id + '">' + uv.value + '</option>';
    }
  }
  uv_select.innerHTML = optionHTML;
  $('#val1').trigger('change');

  //    })
  //  });
}

$('#val1').on('change', function() {
  $('#val1').selectpicker('refresh');
});
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.13.1/css/bootstrap-select.css" />

<link rel="stylesheet" href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.bundle.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.13.1/js/bootstrap-select.min.js"></script>
<!--<script src="https://code.jquery.com/jquery-3.3.1.js"></script>-->





<form method="POST">

  <select id="col1" class="selectpicker" onchange="refreshList(event);">
    <option value="">---</option>
    <option value="0">Zero</option>
    <option value="1">One</option>
    <option value="2">Two</option>
    <option value="3">Three</option>
  </select>
  <select id="val1" class="selectpicker" multiple data-live-search="true">
  </select>
  <input type="submit">
</form>

Upvotes: 3

Related Questions