简体   繁体   中英

Update DataTable with JsonResponse from Django not working properly

I have a Django application and a page where data is written to a table that I am styling using DataTables. I have a very simple problem that has proven remarkably complicated to figure out. I have a dropdown filter where users can select an option, click filter, and then an ajax request updates the html of the table without reloading the page. Problem is, this does not update the DataTable.

My html:

<table class="table" id="results-table">
    <thead>
        <tr>
            <th scope="col">COL 1</th>
            <th scope="col">COL 2</th>
            <th scope="col">COL 3</th>
            <th scope="col">COL 4</th>
            <th scope="col">COL 5</th>
        </tr>
    </thead>
    <tbody class="table_body">
        {% include 'results/results_table.html' %}
    </tbody>
</table>

results_table.html:

{% for result in result_set %}
<tr class="result-row">
  <td>{{ result.col1 }}</td>
  <td>{{ result.col2 }}</td>
  <td>{{ result.col3 }}</td>
  <td>{{ result.col4 }}</td>
  <td>{{ result.col5 }}</td>
</tr>
{% endfor %}

javascript:

function filter_results() {
    var IDs = [];
    var IDSet = $('.id-select');
    for (var i = 0; i < IDSet.length; i++) {
      var ID = getID($(IDSet[i]));
      IDs.push(ID);
    }
    // var data = [];
    // data = $.ajax({
    //   url:"filter_results/" + IDs + "/",
    //   dataType: "json",
    //   async: false,
    //   cache: false,
    //   data: {},
    //   success: function(response) {
    //     $('#results-table').html(response);
    //     // console.log(response.length);
    //     // console.log(typeof response);
    //     //
    //   }
    // }).responseJSON;
    var dataTable = $('#results-table').DataTable();
    dataTable.clear();
    $('.table_body').html('').load("filter_results/" + IDs + "/", function() {
      alert("Done");
    });
    dataTable.draw();
  }

And views:

def filter_results(request, ids):
    ids = [int(id) for id in ids.split(',')]
    account_set = Account.objects.filter(id__in=ids)
    form = ResultsFilterForm()
    result_set = Result.objects.filter(account__in=account_set)
    context = {
        'form': form,
        'result_set': result_set
    }
    return render(request, 'results/results_table.html', context)

What is happening is that the Ajax is correctly updating what I see on the HTML page, but it is not updating the actual data table. So I can filter for a particular ID, for instance, which has 2 results and this will work and show me the two results on the HTML page without reloading it. However, the DataTable still contains the rest of the results so there is still like a "next" page which makes no sense when there are only 2 results.

I also tried changing the view to return a JSON response with the code that is commented out of the JS and when I did that I got "Warning: DataTable encountered unexpected parameter '0' at row 0 column 0" even though the data coming from Django was the correct data in JSON form.

Really stuck here, appreciate the help.

I figured out a way to make it work. Though maybe not the "best" way to do this, it is simple so I hope this helps someone else. Change JavaScript as follows:

function filter_results() {
$('#results-table').DataTable().destroy();
    var IDs = [];
    var IDSet = $('.id-select');
    for (var i = 0; i < IDSet.length; i++) {
      var ID = getID($(IDSet[i]));
      IDs.push(ID);
    }
    $('.table_body').html('').load("filter_results/" + IDs + "/", function() {
      $('#results-table').DataTable();
    });
  }

That was it. All I needed to do was destroy the old DataTable at the beginning of the filter_results function and then re-create it. Note however that the recreation is the function to execute after the call to .load() . If you don't write it like this you will have an issue with JS recreating the DataTable before the the html is finished loading, which is a problem I encountered. Nesting that function inside the .load() call is an easy workaround though.

I know there is probably a better way to do this, one that involves updating rather than destroying and recreating the DataTable. If somebody knows of it feel free to post it as an answer but for now this workaround is good for me!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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