Динамическое добавление строк с помощью SelectPicker

#javascript #php #jquery #laravel #bootstrap-select

Вопрос:

Утро,

У меня есть таблица с выбором в первом столбце. и я хотел бы динамически добавлять строки. На самом деле после добавления первого столбца строки все в порядке, но я не могу выбрать второй столбец. Спасибо за вашу помощь.

Мой столик :

 <tbody>
    <tr>
        <td>
            <Select class="selectpicker" name="item_desc[]" id="item_desc" type="integer" onchange="select_fields(this)">
                <option> </option>
                @foreach ($articles as $article)
                    <option>{{$article->id}}</option>
                @endforeach
            </Select>
        </td>
        <td class="writefields" name="item_fields[]"></td>
        <td><i class="btn far fa-trash-alt" onclick="remove_row(this)"></i></td>
    </tr>
</tbody>
 

`

Моя функция для добавления строки :

 function add_row(){
     var root = document.getElementById('add_table').getElementsByTagName('tbody')[0];
     var rows = root.getElementsByTagName('tr');
     var clone = cloneEl(rows[rows.length -1]);
     cleanUpInputs(clone);
     root.appendChild(clone);
 }

 function cloneEl(el){
     var clo = el.cloneNode(true);
     return clo;
 }

 function cleanUpInputs(obj){
     for (var i = 0; n = obj.childNodes[i];   i){
         if(n.childNodes amp;amp; n.tagName != 'INPUT'){
             cleanUpInputs(n);
         }else if (n.tagName == 'INPUT' amp;amp; n.type == 'text') {
             n.value = '';
         }
     }
 }
 

Моя функция select_fields:

 function select_familyfields(e)
{
    ...
    var selectionfamille = e.value;

  $.ajax({
            type: "POST",
            url: "/achats/selection",
            data: {_token: CSRF_TOKEN, code_item : selection },
            dataType: "JSON",
            success: function (data) {       $(e).parents('tr').find('.item_fields[]').text(data.natureachat.LibNatureAchat); 
          ...
        }
    });
}
 

Комментарии:

1. не могли бы вы, пожалуйста, быть более конкретными? Является ли меню выбора во вновь созданной строке не запускающим событие onchange? И где находится функция select_fields ()?

2. Спасибо за ваши отзывы. Смотрите ниже мою функцию select_fields ().

3. Я думаю, что моя проблема заключается в удалении начальной загрузки-выберите после добавления новой строки путем клонирования в функцию добавления строки. Я могу с успехом выбрать первый ряд. Но я не могу сделать новый выбор после добавления новой строки. у моего нового клона лигна все еще выбран элемент первой строки.

4. Вы решили эту проблему ?

5. ещё нет… ищем решение !

Ответ №1:

Вы используете selectpicker в своем коде, поэтому этот плагин создает свои собственные динамические htmls и назначает ids ,data-attribute их, поэтому, когда вы клонируете свой tr, они также копируются, поэтому вы не видите опцию внутри недавно добавленного выпадающего списка, и они не могут быть выбраны.

Вместо этого один из способов сделать эту работу-сохранить клонированный tr в некоторой переменной , где selectpicker еще не инициализирован . Затем , всякий add_row() раз, когда вызывается функция, просто используйте этот клонированный tr для добавления в свой tbody , а затем инициализируйте свой selectpicker с помощью $("#add_table tbody tr:last select").selectpicker() .

Демонстрационный код :

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

function select_fields(e) {
  var selectionfamille = e.value;
  console.log(selectionfamille)

  /* $.ajax({
     type: "POST",
     url: "/achats/selection",
     data: {
       _token: CSRF_TOKEN,
       code_item: selection
     },
     dataType: "JSON",
     success: function(data) {*/
  //just for demo...
  $(e).parents('tr').find('[name="item_fields[]"]').text("abcxyz") //data.natureachat.LibNatureAchat;

  /*}
  });*/
} 
 <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-select@1.13.14/dist/css/bootstrap-select.min.css">
<script src="https://cdn.jsdelivr.net/npm/bootstrap-select@1.13.14/dist/js/bootstrap-select.min.js"></script>

<table id="add_table">
  <tbody>
    <tr>
      <td>
        <!--remove selectpicker class and id..-->
        <select name="item_desc[]" onchange="select_fields(this)">
          <option> </option>

          <option>1</option>
          <option>2</option>
        </select>
      </td>
      <td class="writefields" name="item_fields[]">Smethings...</td>
      <td><i class="btn far fa-trash-alt" onclick="remove_row(this)">Delete</i></td>
    </tr>
  </tbody>
</table>
<button onclick="add_row()">Add</button> 

Комментарии:

1. Спасибо Свати за вашу помощь. это успешно !

Ответ №2:

Может быть, это потому, что у вашего <Select элемента есть идентификатор, и вам нужно сделать его уникальным? Попробуйте это дополнение к вашей cleanUpInputs функции

 function cleanUpInputs(obj){
     let cloneCounter = document.getElementById('add_table').getElementsByTagName('tbody').length   1
     obj.getElementsByClassName('.selectpicker')[0].id = "item_desc"   cloneCounter;
     for (var i = 0; n = obj.childNodes[i];   i){
 

Комментарии:

1. После тестов у меня появилась эта ошибка :»obj.querySelector не является функцией»

2. Я обновил свой ответ, вы можете это попробовать? Спасибо

3. Ошибка после теста : «obj.getElementsByClassName(…)[0] не определено»