HTML select 在通过 JQuery 填充后不刷新

HTML select not refreshing after being populated via JQuery

我一直在使用 JQuery 在单击 HTML select 元素时填充下拉列表。选项会被创建,但是在第一次单击时选项会显示在一个带有滚动条的非常小的框中。见下文

incorrect

如果我关闭并重新打开下拉菜单,它会正确显示。如下。

correct

感觉下拉列表是在 jquery 呈现新的选项元素之前出现的。我试图找到重新渲染它的方法,但没有成功。

这感觉应该是一个很容易解决的问题,但我是脚本编写的新手并且正在苦苦挣扎。

HTML

<select class="custom-select" id="templateGroupName" name="templateGroupName">
    <option selected>Please Select a group</option>
</select>

JS - 包装在 document.ready

$('#templateGroupName').click(function () {
    $.ajax({
        type: "GET",
        url: '/Layout/GetGroups',
        success: function (data) {
            helpers.buildDropdown(
                data,
                $('#templateGroupName'),
                'Select an option'
            );
        }
    });

});

var helpers =
{
    buildDropdown: function (result, dropdown, emptyMessage) {
        // Remove current options
        dropdown.html('');
        // Add the empty option with the empty message
        dropdown.append('<option value="">' + emptyMessage + '</option>');
        // Check result isnt empty
        if (result != '') {
            // Loop through each of the results and append the option to the dropdown
            $.each(result, function (k, v) {
                dropdown.append('<option value="' + v.Id + '">' + v.Name + '</option>');
            });
        }
    }
}

首先,你需要一个<select>作为父元素,而不是一个空元素,

dropdown = $('#templateGroupName');

然后将其作为文档元素而不是字符串插入:

var opt = document.createElement('option');
opt.value = v.Id;
opt.innerHTML = v.Name;
dropdown.appendChild(opt);

当您在 <select> 打开时注入选项时,浏览器会感到困惑。公平地说,您的用户可能也会感到困惑。

如果您正在等待加载某些内容,告诉他们等待。 如果某些东西不可用,禁用它

将这两个放在一起:第一次 用户将鼠标悬停在 <select> 上时,禁用它并将光标设置为加载轮。等到您的数据加载完毕,然后插入选项,重新启用它并将光标切换回来。

var helpers = {
  buildDropdown: function(result, dropdown, emptyMessage) {
    dropdown.html('');
    dropdown.append(`<option value="">${emptyMessage}</option>`);
    if (!!result) {
      $.each(result, function(k, v) {
        dropdown.append(`
            <option value="${v.Id}">
              ${v.Name}
            </option>
         `);
      });
    }
  }
}

const $DROPDOWN = $('#templateGroupName');
// using jQuery#one to only fire the click event once
$DROPDOWN.one('mouseenter', _ => {
  // disable dropdown while loading options
  $DROPDOWN.attr('disabled', true)
  console.log('loading options...');
  // replace contents with your GET request
  setTimeout(function() {
    helpers.buildDropdown(
      Array.from({
        length: 30
      }, (_, i) => ({
        Id: i,
        Name: i
      })),
      $DROPDOWN,
      'Select an option'
    );
    // un-disable after options are loaded and inserted
    $DROPDOWN.attr('disabled', false)
  }, 1000);
})
/* Show "loading" wheel while loading */

select.custom-select[disabled] {
  cursor: wait;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select class="custom-select" id="templateGroupName" name="templateGroupName">
  <option selected>Please Select a group</option>
</select>