jQuery Select 转换为 Select2 没有下拉选项

jQuery Select converts to Select2 with no dropdown options

我的应用程序使用 API 提取下拉列表选项,并在用户单击编辑按钮时在 table 中动态创建内联下拉列表。使用 jQuery 的基本“Select”功能,一切都按预期工作。 Aaaa 然后我看到了 Select2,它闪闪发光,内置搜索框。因为我的列表在生产中会变得很长,所以这是我真正应该拥有的功能。我见过许多片段,人们只需在 select 项上调用 .select2() 即可立即使用。我得到了框,但它不工作 :) Select2 框出现并有正确的下拉项 selected,但是当我点击框时没有下拉选项。

我复制了应用程序的基本功能和结构,包括模拟的 API 数据响应。有没有办法让现有的 select 功能正常工作,或者我是否需要使用 Select2 从头开始​​构建它?此外,根据我的数据结构,这甚至可能吗?

感谢观看!

JS Fiddle 包含相同的代码,但包含在内是为了您的编辑方便: https://jsfiddle.net/tekowalski/amrhjo6y/9/

$(document).ready(function () {
  $('#edit_btn').click(function () {
    let clickedRow = $($(this).closest('td')).closest('tr');
    $(clickedRow).find('td').each(function () {
      if ($(this).hasClass('edit_account')) {
        fnCreateDropdown($(this), option_data);
      }
    });
  });

  function fnCreateDropdown(obj, options) {
    let html = '<select type="dropdown-menu dropdown-menu-end">';
    let account_type = '';
    let grouped = false;

    for (var idx in options) {
      let my_act_type = options[idx]['account_type_name']; // Set Account Type
      if(my_act_type !== account_type) {
        if(grouped === true) { // Close out option group if one has been made
          html += '</optgroup>'
        }
        
        html += '<optgroup label="' + my_act_type + '">'
        grouped = true;
        
        account_type = my_act_type; // Set account_type for next loop

      }
      if (options[idx]['id'] === 2) {
        selected = ' selected ';
      } else {
        selected = '';
      }
      html += '<option ' + selected + 'id="' + options[idx]['id'] + '">' + options[idx]['name'] + '</option>';
    }

    html += '</optgroup></select>';
    obj.html($(html));
    $(obj).select2(); // Comment out this line for a functional select with dropdown options
  }

  option_data = [
    {account_type_id: 1, account_type_name: 'Asset', id: 1, name: 'Asset Account'},
    {account_type_id: 2, account_type_name: 'Expense', id: 2, name: 'Expense Account'}
    ]
});
  
<link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>
<table>
<thead>
  <tr>
    <th>Account Name</th>
    <th></th>
  </tr>
</thead>
<tbody>
  <tr>
    <td class="edit_account">
      Expense Account
    </td>
    <td>
      <button id='edit_btn'>Edit</button>
      </td>
  </tr>
</tbody>
</table>

.select2() 必须应用于 <select> 元素。

在这种情况下,obj.select2() 不适用于 <select>,因为它是动态生成的 select 插入的容器。

改变

$(obj).select2();

obj.find("select").select2()

应用于容器内的select

旁注:obj 已经是一个 jquery 对象,因此无需再次包装它,但除了一点点开销之外没有坏处。

更新的代码段:

$(document).ready(function () {
  $('#edit_btn').click(function () {
    let clickedRow = $($(this).closest('td')).closest('tr');
    $(clickedRow).find('td').each(function () {
      if ($(this).hasClass('edit_account')) {
        fnCreateDropdown($(this), option_data);
      }
    });
  });

  function fnCreateDropdown(obj, options) {
    let html = '<select type="dropdown-menu dropdown-menu-end">';
    let account_type = '';
    let grouped = false;

    for (var idx in options) {
      let my_act_type = options[idx]['account_type_name']; // Set Account Type
      if(my_act_type !== account_type) {
        if(grouped === true) { // Close out option group if one has been made
          html += '</optgroup>'
        }
        
        html += '<optgroup label="' + my_act_type + '">'
        grouped = true;
        
        account_type = my_act_type; // Set account_type for next loop

      }
      if (options[idx]['id'] === 2) {
        selected = ' selected ';
      } else {
        selected = '';
      }
      html += '<option ' + selected + 'id="' + options[idx]['id'] + '">' + options[idx]['name'] + '</option>';
    }

    html += '</optgroup></select>';
    obj.html($(html));
    obj.find("select").select2(); 
  }

  option_data = [
    {account_type_id: 1, account_type_name: 'Asset', id: 1, name: 'Asset Account'},
    {account_type_id: 2, account_type_name: 'Expense', id: 2, name: 'Expense Account'}
    ]
});
<link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>
<table>
<thead>
  <tr>
    <th>Account Name</th>
    <th></th>
  </tr>
</thead>
<tbody>
  <tr>
    <td class="edit_account">
      Expense Account
    </td>
    <td>
      <button id='edit_btn'>Edit</button>
      </td>
  </tr>
</tbody>
</table>