简体   繁体   English

使用带有过滤器的 Bootstrap Selectpicker 克隆表行

[英]Clone Table Row with Bootstrap Selectpicker with Filter

I have a Laravel application using Bootstrap.我有一个使用 Bootstrap 的 Laravel 应用程序。 I have a form (shown below) where I want to add more rows (via JS) by clicking the Add Row button.我有一个表单(如下所示),我想通过单击“添加行”按钮添加更多行(通过 JS)。 I have a Select/Selectpicker ("Opponent") that I want to be able to type and live filter to find the right option.我有一个 Select/Selectpicker(“Opponent”),我希望能够键入并实时过滤以找到正确的选项。

The Selectpicker works fine in row 1. However, when I clone the row, the Selectpicker does 2 weird things: (1) The new Select loses all its options, so there is nothing to choose from, and (2) It retains the selected value of the cloned element instead of clearing like the rest of the inputs. Selectpicker 在第 1 行工作正常。但是,当我克隆该行时,Selectpicker 做了 2 件奇怪的事情:(1) 新的 Select 失去了所有选项,所以没有什么可供选择,并且 (2) 它保留了选定的克隆元素的值,而不是像输入的 rest 那样清除。

Note: In the HTML code below, you'll see a commented-out Select for a static Select that does NOT use filtering.注意:在下面的 HTML 代码中,您将看到一个注释掉的 Select 用于 static ZE062625 不使用过滤器的 ZE0626222614BDEE311。 This works perfectly fine;这工作得很好; clones successfully, clears the value, and has all the options in the drop-down.克隆成功,清除值,并在下拉列表中包含所有选项。 Only the Selectpicker has issues cloning.只有 Selectpicker 有克隆问题。

我要复制的表格行

JavaScript function: JavaScript function:

<script>
  function cloneRow() {

    var table = document.getElementById("gameBody"); // find table to append to
    var count = table.rows.length + 1;
    var gameStr = "game";
    var oppString = "opponent";

    var row = document.getElementById("game1"); // find row to copy

    var clone = row.cloneNode(true); // copy children too
    clone.id = gameStr + count; // change id of new row

    table.appendChild(clone); // add new row to end of table

    // Clear fields in new row
    var newRow = document.getElementById(gameStr.concat(count));
    inputs = newRow.getElementsByTagName('input');
    for (index = 0; index < inputs.length; ++index) {
      if(inputs[index].type == "text" || inputs[index].type == "date")
        inputs[index].value = '';
    }
  }
</script>

CSS/JS includes: CSS/JS 包括:

<!-- Inside the Head tag -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css" integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous">
<link href="https://cdn.jsdelivr.net/gh/gitbrent/bootstrap4-toggle@3.6.1/css/bootstrap4-toggle.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-select@1.13.18/dist/css/bootstrap-select.min.css">

<!-- At the bottom of the Body -->
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js" integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/js/bootstrap.min.js" integrity="sha384-w1Q4orYjBQndcko6MimVbzY0tgp4pWB4lZ7lr30WKz0vr/aWKhXdBNmNb5D92v7s" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/gh/gitbrent/bootstrap4-toggle@3.6.1/js/bootstrap4-toggle.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap-select@1.13.18/dist/js/bootstrap-select.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap-select@1.13.18/dist/js/i18n/defaults-*.min.js"></script>

HTML table: HTML 表:

<table class="table table-sm table-striped" id="game_table">
  <thead>
    <tr>
      <th>Date*</th>
      <th>Opponent</th>
      <th>Name Override</th>
      <th>Location*</th>
      <th>Site Name</th>
      <th>Game Type*</th>
    </tr>
  </thead>
  <tbody id="gameBody">
    <tr class="dummy-row" id='game1'>

      <!-- Date -->
      <td>
        <input type="date" name='gameDate[]' id="gameDate1" class="form-control" required/>
      </td>

      <!-- Opponent -->
      <td>
        <select name='opponent[]' id="opponent1" class="selectpicker form-control" data-live-search="true" title="Select an opponent" data-hide-disabled="true">
        <!--<select name='opponent[]' class="form-control"title="Select an opponent">-->
          <option value="">Select a Team</option>
            @foreach($allschools as $school)
              <option value="{{ $school->id }}">{{ isset($school->nickname) ? $school->nickname : $school->name }}
              @if($school->name != $school->city)
                ({{ $school->city }})
              @endif
              </option>
            @endforeach
        </select>
      </td>

      <!-- Opponent Override -->
      <td>
        <input type="text" name='opponentOverride[]' id="opponentOverride1" class="form-control"/>
      </td>

      <!-- Location -->
      <td>
        <select name='location[]' id="location1" class="form-control" required>
          <option value="HOME">Home</option>
          <option value="AWAY">Away</option>
        </select>
      </td>

      <!-- Site Name -->
      <td>
        <input type="text" name='site[]' id="site1" class="form-control"/>
      </td>

      <!-- Game Type -->
      <td>
        <select name='gameType[]' id="gameType1" class="form-control" required>
          <option value="REGULAR SEASON">Reg. Season</option>
          <option value="POSTSEASON">Postseason</option>
          <option value="SCRIMMAGE">Scrimmage</option>
        </select>
      </td>
    </tr>
  </tbody>
</table>

<table class="table tabls-sm table-borderless">
  <tr>
    <td class="text-left" width="50%">
      <a id='add_row' onclick="cloneRow()" class="btn btn-sm btn-warning">Add Row</a>
    </td>
    <td class="text-right" width="50%">
      <a id='delete_row' onclick="deleteLastRow()" class="btn btn-sm btn-danger">Delete Last Row</a>
    </td>
  </tr>
</table>

Thank you for your help!谢谢您的帮助!

I figured it out using this as a blueprint: Add Row dynamically with SelectPicker我用它作为蓝图想出来了: 使用 SelectPicker 动态添加行

At a high level, this is what I had to do:在高层次上,这是我必须做的:

  1. Remove the "selectpicker" class from the Selectpicker ("Opponent")从 Selectpicker(“对手”)中移除“selectpicker”class
  2. In the add_row() function, initialize the Selectpicker class在add_row() function中,初始化Selectpicker class
  3. Dynamically append the resulting HTML as the new row动态地将 append 生成的 HTML 作为新行

I guess it comes down to how Bootstrap treats the Selectpicker class.我想这取决于 Bootstrap 如何处理 Selectpicker class。 I don't fully understand it, but the best I can explain is... When you use <select class="selectpicker"... Bootstrap changes the object so that it is no longer a pure Select with options belonging to it.我不完全理解它,但我能解释的最好的是...当您使用 <select class="selectpicker"... Bootstrap 更改 object 使其不再是带有属于它的选项的纯 Select。 Rather, it wraps it in other, dynamically-created layers on-the-fly (div=>select=>button=>div=>options, etc).相反,它会将其包装在其他动态创建的层中(div=>select=>button=>div=>options 等)。 This causes issues when cloning because the object you're cloning (the Select) no longer contains those Options, as they are lost somewhere else in the hierarchy (for lack of better terms).这会导致克隆时出现问题,因为您正在克隆的 object(选择)不再包含这些选项,因为它们在层次结构中的其他位置丢失(因为缺少更好的术语)。 I remember reading that in another post, but didn't really get it until now (kinda).我记得在另一篇文章中读过,但直到现在才真正明白(有点)。

Here is my functioning code:这是我的功能代码:

HTML Table: HTML 表:

<table class="table table-sm table-striped" id="gameTable">
  <thead>
    <tr>
      <th>Date*</th>
      <th>Opponent</th>
      <th>Name Override</th>
      <th>Location*</th>
      <th>Site Name</th>
      <th>Game Type*</th>
    </tr>
  </thead>
  <tbody id="gameBody">
    <tr id="gameRow">

      <!-- Date -->
      <td>
        <input type="date" name='gameDate[]' id="gameDate1" class="form-control" required/>
      </td>

      <!-- Opponent -->
      <td>
        <select name='opponent[]' id="opponent1" class="form-control" data-live-search="true" title="Select an opponent" data-hide-disabled="true">
        <!--<select name='opponent[]' class="form-control" title="Select an opponent">-->
          <option value="">Select a Team</option>
            @foreach($allschools as $school)
              <option value="{{ $school->id }}">{{ isset($school->nickname) ? $school->nickname : $school->name }}
              @if($school->name != $school->city)
                ({{ $school->city }})
              @endif
              </option>
            @endforeach
        </select>
      </td>

      <!-- Opponent Override -->
      <td>
        <input type="text" name='opponentOverride[]' id="opponentOverride1" class="form-control"/>
      </td>

      <!-- Location -->
      <td>
        <select name='location[]' id="location1" class="form-control" required>
          <option value="HOME">Home</option>
          <option value="AWAY">Away</option>
          <!--<option value="NEUTRAL">Neutral</option>-->
        </select>
      </td>

      <!-- Site Name -->
      <td>
        <input type="text" name='site[]' id="site1" class="form-control"/>
      </td>

      <!-- Game Type -->
      <td>
        <select name='gameType[]' id="gameType1" class="form-control" required>
          <option value="REGULAR SEASON">Reg. Season</option>
          <option value="POSTSEASON">Postseason</option>
          <option value="SCRIMMAGE">Scrimmage</option>
        </select>
      </td>

    </tr>
  </tbody>
</table>

<table class="table tabls-sm table-borderless">
  <tr>
    <td class="text-left" width="30%">
      <a id='add_row' onclick="add_row()" class="btn btn-sm btn-warning">Add Row</a>
    </td>
    <td class="text-center" width="40%">
      <button type="submit" class="btn btn-primary">Create Games</button>
    </td>
    <td class="text-right" width="30%">
      <a id='delete_row' onclick="deleteLastRow()" class="btn btn-sm btn-danger">Delete Last Row</a>
    </td>
  </tr>
</table>

Function (bottom of Body): Function(机身底部):

<script>
  var cloned = $("#gameTable tbody tr:first").clone() //keep clone for later use..
  $("select[name*=opponent]").selectpicker() //intialize your slectpicker
  function add_row() {
    $(cloned).find("input").val("") //empty any input..
    $("<tr>" + $(cloned).html() + "</tr>").appendTo($("#gameTable tbody")) //append to your tbody..
    $("#gameTable tbody tr:last select").selectpicker() //intialize newly added selct...
  }
</script>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM