Невозможно динамически добавить строку в Jquery datatable

#javascript #jquery #ajax #datatables

#javascript #jquery #ajax #таблицы данных

Вопрос:

Я выполняю 2 функции в jquery datatable.

  1. Для поиска и фильтрации таблицы, зависящей от выбранных тегов.
  2. Динамическое добавление строк в datatable через ajax.

При добавлении строки строка добавляется в таблицу, а количество строк увеличивается при разбивке на страницы, но в таблице отображаются нулевые строки из-за функции поиска. Как только я обновляю таблицу, я могу видеть все строки. Я выяснил, что основная проблема заключается в функции $.fn.DataTable.ext.search.push(), из-за которой table.rows.add($trHTML).draw(); не работает. Из-за функции поиска создается некоторая зависимость, которую я не могу разрешить. Пожалуйста, предоставьте несколько предложений по ее устранению.

HTML

 <div class="container">
    <form class="form-inline  d-inline-flex mt-2 ml-2 align-items-start">
        <div class="form-group">
          <select id="cato"  class="form-control input-sm shadow-none" >
            <option disabled selected="true">-Category-</option>
            {% for i in ch %}
            <option value ="{{i.name}}">{{i.name}}</option>
            {% endfor %}
        </select>
        </div>      
        <div class="form-group">
           <select id="subo" class="form-control shadow-none">
            <option disabled selected="true">-Subcategory-</option>   
            </select>
        </div>  
          <!--Reset Button-->
          <button type="submit" onclick="resettable()" class="btn btn-success"><i class="fa fa-arrow-circle-o-up" aria-hidden="true"></i> Reset</button>    
    </form>
        
<button type="submit" id="bt" class="btn btn-success align-top m-2" data-toggle="modal" data-target="#modaledit" style="float:right !important"><i class="fa fa-plus" aria-hidden="true"></i> Add</button>  

        <div class="modal" tabindex="-1" role="dialog" id="modaledit" >
            <div class="modal-dialog">
                <div class="modal-content">
                    <div class="modal-header">
                        <h5 class="modal-title"><b>Add Product</b></h5>
                        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                            <span aria-hidden="true">amp;times;</span>
                            </button>
                    </div>
   
                <div class="modal-body" style="background-color: #fffdd0;">
                    <!--Popup Form-->
                    <form id="form_post">
                        {% csrf_token %}
                        <div class="form-group">
                            <label>Name</label>
                            <input type="text" id="name" class="form-control" placeholder="Enter Product Name" name="name" spellcheck="false" required autocomplete="off">
                        </div>
                        <div class="form-group">
                            <label>Description</label>
                            <input type="text" id="desc" class="form-control" placeholder="Enter Description" name="desc" spellcheck="false" autocomplete="off">
                        </div>
                        <div class="form-group">
                            <label>Category</label>
                            <select id="catoo" class="form-control" name="category" required>
                                <option disabled selected="true">-Select Category-</option>
                                {% for i in ch %}
                                <option value ="{{i.name}}">{{i.name}}</option>
                                {% endfor %}
                            </select>
                        </div>
                        <div class="form-group">
                            <label>Subcategory</label>
                            <select id="suboo" class="form-control" name="subcategory" required>
                                <option disabled selected="true">-Select Subcategory-</option>
                    
                            </select><br/>
                            <input type="submit" class="btn btn-success" value="Submit">
                        </div>
                    </form>
                </div>
            </div>
        </div>
     </div>

    <div class="table-responsive" id="resp">
        <table class="table table-bordered" id="example>
            <thead>
                <tr>
                    <th></th>
                    <th>Product</th>
                    <th>Subcategory</th>
                    <th>Category</th>
                </tr>
            </thead>
            <tbody id="r">
                {% for i in pd %}
                <tr>
                    <td>{{i.id}}</td>
                    <td>{{i.name}}</td>
                    <td>{{i.subcategory}}</td>
                    <td>{{i.category}}</td>
                </tr>
                {% endfor %}
            </tbody>
        </table>
    </div>
</div>
  

Jquery

 <script>

 var table = $('#example').DataTable({
  "bLengthChange": false,
  //searching: false,
  pageLength: 5,
  "order": [[ 0, "desc" ]],
  dom: 'tip',
  language : {
        "zeroRecords": " "             
    },
    "columnDefs": [{
    "defaultContent": "-",
    "targets": "_all"
  }]
});

table.column(0).visible(false);

$.fn.dataTable.ext.search.push(
function( settings, data, dataIndex ) {
    var filterCategory= $("#cato option:selected").text().toUpperCase();
    let filterSubCategory= $("#subo option:selected").text().toUpperCase();
    var subCategory = String(data[2]).toUpperCase();
    var category = String(data[3]).toUpperCase();
    if((filterSubCategory != "-SUBCATEGORY-")amp;amp;(filterSubCategory != "")) {
        console.log("2",filterSubCategory);
        if ( filterCategory == category amp;amp; filterSubCategory == subCategory)
            {
            return true;
            }
        }
    else if(filterCategory != "-CATEGORY-") {
        console.log("1",filterCategory);
        if ( filterCategory == category)
            {
            return true;
            }
        }
    return false;
    }
);

$('#cato').on('change', function() {
    $('#subo').val("");
  table.draw();
});

$('#subo').on('change', function() {
  table.draw();
});
       
$(document).on("submit","#form_post",function(e){
        e.preventDefault();
             $.ajax({
                type:'POST',
                url: "{% url 'getdetails1' %}",
                data:{
                    name:$('#name').val(),
                    desc:$('#desc').val(),
                    category:$("#catoo option:selected").text(),
                    subcategory:$("#suboo option:selected").text(),
                    'csrfmiddlewaretoken': '{{ csrf_token }}'
                },
                dataType: "json",
                success:function(data) {
                    var trHTML='';
                    $("#form_post")[0].reset();
                    $('#modaledit').modal('hide');                
                    trHTML  = '<tr><td>'   data[0].i   '</td><td>'  data[0].n   '</td><td>'   data[0].s   '</td><td>'  data[0].c   '</td></tr>';                  
                    table.rows.add($(trHTML)).draw();
                    console.log(data);
                    table.rows.add([data[0].i,data[0].n,data[0].s,data[0].c]);
                    table.draw();
                }
            });
        });
</script>
  

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

1. Если вы создадите фрагмент вашей проблемы, это действительно поможет нам помочь вам.

2. @IslamElshobokshy Snipped не будет работать, поскольку я извлекаю данные из базы данных, которая также включает часть django

3. Вы можете легко имитировать ответ ajax

Ответ №1:

Я создал небольшой пример с моим небольшим репозиторием, надеясь, что это поможет вам решить вашу проблему:

 var table = $('#example').DataTable({
  "bLengthChange": false,
  //searching: false,
  pageLength: 3,
  dom: 'tip'
});
  
$.fn.dataTable.ext.search.push(function( settings, data, dataIndex ) {
    
    var filterCategory= $("#cato option:selected").text().toUpperCase();
    var filterSubCategory= $("#subo option:selected").text().toUpperCase();
    var subCategory = String(data[2]).toUpperCase();
    var category = String(data[3]).toUpperCase();
    
    //console.log(filterSubCategory);
    
    if(filterSubCategory != "-SELECT SUBCATEGORY-") {
        if ( filterCategory == category amp;amp; filterSubCategory == subCategory)
             return true;
        }
        else if(filterCategory != "-SELECT CATEGORY-") {
            if ( filterCategory == category)
             return true;
        }
        
        return false;
    }
);

$('#cato').on('change', function() {
  $('#subo').val("");
  table.draw();
});

$('#subo').on('change', function() {
  table.draw();
});

function getInfo() {

        var $subCategory = $("#subo option:selected").text()

        $.ajax({
      type:'GET',
      url: "https://my-json-server.typicode.com/SagnalracSO/repo/items?subcategory="   $subCategory,
      /*data:{
        name:$('#name').val(),
        desc:$('#desc').val(),
        category:$("#catoo option:selected").text(),
        ,
        'csrfmiddlewaretoken': '{{ csrf_token }}'
      },*/
      dataType: "json",
      beforeSend: function(jqXHR, settings) {
      
          if($subCategory.toUpperCase() == '-SELECT SUBCATEGORY-') {
              alert('Select a SubCategory');
                jqXHR.abort();
          }
      },
      success: function(data) {
        
        var item = data[0];
        var jRow = $("<tr>").append("<td>"   item.id   "</td><td>"   item.product   "</td><td>"   item.subcategory   "</td><td>"   item.category   "</td>").append("</tr>");
        table.row.add(jRow).draw();

      }
   });
}  
 <link href="https://cdn.datatables.net/1.10.21/css/jquery.dataTables.min.css" rel="stylesheet"/>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="https://cdn.datatables.net/1.10.21/js/jquery.dataTables.min.js"></script>

<select id="cato" class="form-control" >
  <option value="" disabled selected="true">-Select Category-</option>
  <option>Electronics</option>
  <option>Sports</option>
</select>

<select id="subo" class="form-control">
   <option value="" disabled selected="true">-Select Subcategory-</option>
   <option>Laptop</option>
   <option>Mobile</option>
</select>

<table id="example" class="table display">
  <thead>
    <tr>
      <th>Id</th>
      <th>Product</th>
      <th>Subcategory</th>
      <th>Category</th>
    </tr>
  </thead>
  <tbody id="r">
    <tr>
      <td>1</td>
      <td>Samsung</td>
      <td>Mobile</td>
      <td>Electronics</td>
    </tr>
    <tr>
      <td>2</td>
      <td>Racket</td>
      <td>Tennis</td>
      <td>Sports</td>
    </tr>
    <tr>
      <td>3</td>
      <td>Bat</td>
      <td>Cricket</td>
      <td>Sports</td>
    </tr>
    <tr>
      <td>4</td>
      <td>Dell</td>
      <td>Laptop</td>
      <td>Electronics</td>
    </tr>
    <tr>
      <td>5</td>
      <td>Iphone</td>
      <td>Mobile</td>
      <td>Electronics</td>
    </tr>
    <tr>
      <td>6</td>
      <td>Soccer Ball</td>
      <td>Soccer</td>
      <td>Sports</td>
    </tr>
  </tbody>
</table>
<br><br>
<input type="button" value="ADD ROWS" onClick="getInfo()" />  

Если ваш Ajax-запрос возвращает более одной записи, вы можете заменить это:

 var item = data[0];
    var jRow = $("<tr>").append("<td>"   item.id   "</td><td>"   item.product   "</td><td>"   item.subcategory   "</td><td>"   item.category   "</td>").append("</tr>");
    table.row.add(jRow).draw();
  

с помощью этого:

 for (var item in data) {
    
        var item = data[item];
        
        var jRow = $("<tr>").append("<td>"   item.id   "</td><td>"   item.product   "</td><td>"   item.subcategory   "</td><td>"   item.category   "</td>").append("</tr>");
        table.row.add(jRow).draw();
    }
  

Кстати, если в будущем вы захотите создавать примеры, включающие вызов API (через Ajax-запрос), как я сделал в этом примере, я хотел бы порекомендовать вам этот веб-сайт JSONPlaceholder

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

1. Еще раз спасибо за ваш ответ. Ваш код идеален, но функция отправки, в которой вы использовали функцию getinfo(), фактически извлекает данные формы, которые вы прокомментировали / * data * / part.. Я отправляю данные на сервер и получаю значение через ajax. Вы видите, в моем примере я использовал form_post, который публикует значение формы при отправке в html, и в jquery я извлекаю все поля. Теперь значения моей формы не принимаются, и страница перезагружается как e.функция preventdefault() удалена

2. @Karthik: Да, я знаю. Мне пришлось прокомментировать часть вашего Ajax-запроса с данными , потому что на веб-сайте, который я использую для получения данных онлайн для подобных примеров, я все еще не знаю, как выполнить запрос POST , только GET . Кстати, у меня есть один вопрос. Необходимо ли выполнять действие отправки, чтобы получить ваши данные? Потому что, если вы используете Ajax, вы можете извлечь ее другими способами, как я сделал в своем примере.

3. Я извлекаю данные, используя только ajax, как вы использовали. Дело в том, что и форма, и таблица находятся на одной странице, поэтому создается такой беспорядок. Но дело в том, что, как вы предложили, это работало только с GET, я пытался отправить данные формы в django view через POST, но из-за нескольких действий это не работает, поэтому GET рекомендуется только в этом случае. Просто сомневаюсь, что целая страница перезагружается при нажатии кнопки. Как избежать этого здесь, в моем приведенном выше примере я избежал этого, используя preventdefault()

4. @Karthik: В этой строке <button type="submit" onclick="resettable()" class="btn btn-success"><i class="fa fa-arrow-circle-o-up" aria-hidden="true"></i> Reset</button> замените type="submit" на type="button" . Что касается типа запроса, я уверен, что можно выполнить запрос POST.

5. Большое вам спасибо, мистер спасатель. Теперь все сработало так, как ожидалось. Единственное, что страница перезагружается вместо таблицы при нажатии кнопки. Скоро разберемся. Спасибо за JSONPlaceholder, с этого момента я буду ссылаться на это