如何通过 Ajax 调用更新数据表
How to update a Datatable via Ajax call
我有一个 table,只要有人访问 URL /project_page
,它就会显示来自模型的内容。
在该页面上,用户可以添加文件,我希望 table 实时更新,而无需不断刷新。
为此,我尝试实现一个 Ajax 函数,每隔几秒更新一次 table 内容。因为这是几年前提出的
我认为该功能已实现并且我在 Ajax 成功功能中正确收到 data
但我不知道如何 'inject it' 到 table .
我也想知道是否有更优化或pythonic的方式来实现这个结果。
urls.py
path('project_page_ajax/', views.project_page_ajax, name='project_page_ajax'),
views.py
@login_required
def project_page(request):
context = {}
context['nbar'] = 'projects'
if request.method == 'POST':
print(request.FILES)
form = UploadFileForm(request.POST, request.FILES)
if form.is_valid():
file_hist = form.save(commit=False)
file_hist.user = request.user
# file is saved
file_hist.save()
file_hist_results = FileHistory.objects.all().filter(user=request.user)
context['file_hist_results'] = file_hist_results
print(type(context['file_hist_results']))
return render(request, 'project_page.html', context)
print (form.errors)
else:
form = UploadFileForm()
file_hist_results = FileHistory.objects.all().filter(user=request.user)
context['file_hist_results'] = file_hist_results
context['form'] = form
return render(request, 'project_page.html', context)
@login_required
def project_page_ajax(request):
response = dict()
if request.method == 'GET':
file_hist_results = FileHistory.objects.all().filter(user=request.user).values()
#response.update({'file_hist_results': file_hist_results})
return JsonResponse({"file_hist_results": list(file_hist_results)})
return HttpResponse('')
project_page.html
(JS部分)
var intervalID = setInterval(updateTable, 10000);
function updateTable()
{
$.ajax({
method: "GET",
url: "/project_page_ajax/",
success: function(data, textStatus, request) {
console.log(data);
}
});
}
project_page.html
(HTML部分)
<table id="ittFileUploadTable" class="display nowrap" width="100%">
<thead>
<tr class="ittLineItemsTh">
<th style="text-align:center;">File Name</th>
<th style="text-align:center;">Submitted</th>
<th style="text-align:center;">Updated</th>
<th style="text-align:center;">User</th>
<th style="text-align:center;">Action</th>
</tr>
</thead>
<tbody>
{% for histfiles in file_hist_results %}
<tr>
<td>{{ histfiles.filename }}</td>
<td>{{ histfiles.uploaded }}</td>
<td>{{ histfiles.updated }}</td>
<td>{{ histfiles.user }}</td>
<td>
<button id="delete-itt-file" type="button" class="btn btn-secondary">
<svg xmlns="http://www.w3.org/2000/svg" width="25" height="25" fill="currentColor" class="bi bi-trash-fill" viewBox="0 0 16 16">
<path d="M2.5 1a1 1 0 0 0-1 1v1a1 1 0 0 0 1 1H3v9a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2V4h.5a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1H10a1 1 0 0 0-1-1H7a1 1 0 0 0-1 1H2.5zm3 4a.5.5 0 0 1 .5.5v7a.5.5 0 0 1-1 0v-7a.5.5 0 0 1 .5-.5zM8 5a.5.5 0 0 1 .5.5v7a.5.5 0 0 1-1 0v-7A.5.5 0 0 1 8 5zm3 .5v7a.5.5 0 0 1-1 0v-7a.5.5 0 0 1 1 0z"></path>
</svg>
</button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
这个问题与 javascript.but 更相关这是我的想法,你可以如何用 partial_html.This 解决这个问题只是一个想法,但也许 javascript 人会附上漂亮的答案 ))).
views.py
from django.shortcuts import redirect
@login_required
def project_page(request):
context = {}
context['nbar'] = 'projects'
if request.method == 'POST':
print(request.FILES)
form = UploadFileForm(request.POST, request.FILES)
if form.is_valid():
file_hist = form.save(commit=False)
file_hist.user = request.user
# file is saved
file_hist.save()
return redirect('project_page')
print (form.errors)
else:
form = UploadFileForm()
file_hist_results = FileHistory.objects.all().filter(user=request.user)
context['file_hist_results'] = file_hist_results
context['form'] = form
return render(request, 'project_page.html', context)
@login_required
def project_page_ajax(request):
response = dict()
if request.method == 'GET':
file_hist_results = FileHistory.objects.all().filter(user=request.user).values()
return render(request, 'partial_page.html', {'file_hist_results':file_hist_results})
project_page.html
<table id="ittFileUploadTable" class="display nowrap" width="100%">
<thead>
<tr class="ittLineItemsTh">
<th style="text-align:center;">File Name</th>
<th style="text-align:center;">Submitted</th>
<th style="text-align:center;">Updated</th>
<th style="text-align:center;">User</th>
<th style="text-align:center;">Action</th>
</tr>
</thead>
<tbody>
{% for histfiles in file_hist_results %}
<tr>
<td>{{ histfiles.filename }}</td>
<td>{{ histfiles.uploaded }}</td>
<td>{{ histfiles.updated }}</td>
<td>{{ histfiles.user }}</td>
<td>
<button id="delete-itt-file" type="button" class="btn btn-secondary">
<svg xmlns="http://www.w3.org/2000/svg" width="25" height="25" fill="currentColor" class="bi bi-trash-fill" viewBox="0 0 16 16">
<path d="M2.5 1a1 1 0 0 0-1 1v1a1 1 0 0 0 1 1H3v9a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2V4h.5a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1H10a1 1 0 0 0-1-1H7a1 1 0 0 0-1 1H2.5zm3 4a.5.5 0 0 1 .5.5v7a.5.5 0 0 1-1 0v-7a.5.5 0 0 1 .5-.5zM8 5a.5.5 0 0 1 .5.5v7a.5.5 0 0 1-1 0v-7A.5.5 0 0 1 8 5zm3 .5v7a.5.5 0 0 1-1 0v-7a.5.5 0 0 1 1 0z"></path>
</svg>
</button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
partial_page.html(只是一个简单的 html 不要放置任何 body 或 head 标签,仅此创建该文件)
<table id="ittFileUploadTable" class="display nowrap" width="100%">
<thead>
<tr class="ittLineItemsTh">
<th style="text-align:center;">File Name</th>
<th style="text-align:center;">Submitted</th>
<th style="text-align:center;">Updated</th>
<th style="text-align:center;">User</th>
<th style="text-align:center;">Action</th>
</tr>
</thead>
<tbody>
{% for histfiles in file_hist_results %}
<tr>
<td>{{ histfiles.filename }}</td>
<td>{{ histfiles.uploaded }}</td>
<td>{{ histfiles.updated }}</td>
<td>{{ histfiles.user }}</td>
<td>
<button id="delete-itt-file" type="button" class="btn btn-secondary">
<svg xmlns="http://www.w3.org/2000/svg" width="25" height="25" fill="currentColor" class="bi bi-trash-fill" viewBox="0 0 16 16">
<path d="M2.5 1a1 1 0 0 0-1 1v1a1 1 0 0 0 1 1H3v9a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2V4h.5a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1H10a1 1 0 0 0-1-1H7a1 1 0 0 0-1 1H2.5zm3 4a.5.5 0 0 1 .5.5v7a.5.5 0 0 1-1 0v-7a.5.5 0 0 1 .5-.5zM8 5a.5.5 0 0 1 .5.5v7a.5.5 0 0 1-1 0v-7A.5.5 0 0 1 8 5zm3 .5v7a.5.5 0 0 1-1 0v-7a.5.5 0 0 1 1 0z"></path>
</svg>
</button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
js
var intervalID = setInterval(updateTable, 10000);
function updateTable()
{
$.ajax({
method: "GET",
url: "/project_page_ajax/",
success: function(response) {
$("#ittFileUploadTable").hide(); // first hide the current table
$("#ittFileUploadTable").append(response); // and append the data
}
});
}
解决方案很大程度上取决于 JSON 响应。
HTML
如果您的响应是要显示的实际 HTML 块,看起来有点像这样:
<tr><!-- Some tds --></tr>
<tr><!-- Some tds --></tr>
<tr><!-- Some tds --></tr>
<!-- ... -->
<tr><!-- Some tds --></tr>
那么你可以这样做:
document.querySelector("#ittFileUploadTable tbody").innerHTML = yourTemplate;
JSON
如果您的数据是 JSON,那么创建一个模板函数会很棒,例如:
function fileUploadRecordTemplate(record) {
return `
<td>record.filename</td>
<td>record.uploaded</td>
<td>record.updated</td>
<td>record.user</td>
<td>
<button id="delete-itt-file" type="button" class="btn btn-secondary">
<svg xmlns="http://www.w3.org/2000/svg" width="25" height="25" fill="currentColor" class="bi bi-trash-fill" viewBox="0 0 16 16">
<path d="M2.5 1a1 1 0 0 0-1 1v1a1 1 0 0 0 1 1H3v9a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2V4h.5a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1H10a1 1 0 0 0-1-1H7a1 1 0 0 0-1 1H2.5zm3 4a.5.5 0 0 1 .5.5v7a.5.5 0 0 1-1 0v-7a.5.5 0 0 1 .5-.5zM8 5a.5.5 0 0 1 .5.5v7a.5.5 0 0 1-1 0v-7A.5.5 0 0 1 8 5zm3 .5v7a.5.5 0 0 1-1 0v-7a.5.5 0 0 1 1 0z"></path>
</svg>
</button>
</td>
`;
}
然后像这样为您的 tbody
补水:
let output = [];
for (let record of data) output.push(fileUploadRecordTemplate(record));
document.querySelector("#ittFileUploadTable tbody").innerHTML = yourTemplate;
Fiddle
let index = 1;
//t1
function updateT1() {
//We generate some HTML, but if you get an HTML from server-side, then you can
//skip this part
let template = "";
let rows = parseInt(document.getElementById("t1rows").value);
for (let i = 0; i < rows; i++) {
template += `
<tr>
<td>${index++}</td>
<td>${index++}</td>
<td>${index++}</td>
<td>${index++}</td>
</tr>
`;
}
//This is the actual operation which refreshes the HTML
document.querySelector("#t1 > tbody").innerHTML = template;
}
//t2
function fileUploadRecordTemplate(record) {
return `
<tr>
<td>${record.filename}</td>
<td>${record.uploaded}</td>
<td>${record.updated}</td>
<td>${record.user}</td>
<td>
<button id="delete-itt-file" type="button" class="btn btn-secondary">
<svg xmlns="http://www.w3.org/2000/svg" width="25" height="25" fill="currentColor" class="bi bi-trash-fill" viewBox="0 0 16 16">
<path d="M2.5 1a1 1 0 0 0-1 1v1a1 1 0 0 0 1 1H3v9a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2V4h.5a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1H10a1 1 0 0 0-1-1H7a1 1 0 0 0-1 1H2.5zm3 4a.5.5 0 0 1 .5.5v7a.5.5 0 0 1-1 0v-7a.5.5 0 0 1 .5-.5zM8 5a.5.5 0 0 1 .5.5v7a.5.5 0 0 1-1 0v-7A.5.5 0 0 1 8 5zm3 .5v7a.5.5 0 0 1-1 0v-7a.5.5 0 0 1 1 0z"></path>
</svg>
</button>
</td>
</tr>
`;
}
function updateT2() {
let rows = parseInt(document.getElementById("t2rows").value);
let data = [];
for (let i = 0; i < rows; i++) {
data.push({
filename: index++,
uploaded: index++,
updated: index++,
user: index++
});
}
let output = [];
for (let record of data) output.push(fileUploadRecordTemplate(record));
document.querySelector("#t2 tbody").innerHTML = output.join("");
}
<table id="t1">
<thead>
<th>First</th>
<th>Second</th>
<th>Third</th>
<th>Fourth</th>
</thead>
<tbody>
</tbody>
</table>
Number of rows: <input type="number" value="4" id="t1rows"><input type="button" value="OK" onclick="updateT1()">
<table id="t2">
<thead>
<th>First</th>
<th>Second</th>
<th>Third</th>
<th>Fourth</th>
<th>Fifth</th>
</thead>
<tbody>
</tbody>
</table>
Number of rows: <input type="number" value="4" id="t2rows"><input type="button" value="OK" onclick="updateT2()">
我找到了解决办法!
正如@mark_b 所说,我使用数据表 Ajax 而不是 jQuery AJAX
现在可以了,这是我的代码:
$('#ittFileUploadTable').DataTable( {
responsive: true,
autowidth: false,
destroy: true,
deferRender: true,
ajax: {
url: '/project_page_ajax/',
type: 'GET',
data: {},
dataSrc: ""
},
columns: [
{"data": "fields.filename"},
{"data": "fields.uploaded"},
{"data": "fields.updated"},
{"data": "fields.user"},
{"data": "pk"},
],
columnDefs: [
{ className: 'text-center', targets: [1] },
{
targets: [0],
class: 'text-center',
orderable: false,
render: function (data, type, row) {
var buttons = '<a href="/media/'+data+'" target="_blank">'+data+'</a>';
return buttons;
}
},
{
targets: [-1],
class: 'text-center',
orderable: false,
render: function (data, type, row) {
var buttons = '<form method="post" action="delete_file/'+data+'/"><button type="submit" class="btn btn-danger"><svg xmlns="http://www.w3.org/2000/svg" width="25" height="25" fill="white" class="bi bi-trash-fill" viewBox="0 0 16 16"><path d="M2.5 1a1 1 0 0 0-1 1v1a1 1 0 0 0 1 1H3v9a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2V4h.5a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1H10a1 1 0 0 0-1-1H7a1 1 0 0 0-1 1H2.5zm3 4a.5.5 0 0 1 .5.5v7a.5.5 0 0 1-1 0v-7a.5.5 0 0 1 .5-.5zM8 5a.5.5 0 0 1 .5.5v7a.5.5 0 0 1-1 0v-7A.5.5 0 0 1 8 5zm3 .5v7a.5.5 0 0 1-1 0v-7a.5.5 0 0 1 1 0z"/></svg></button></form>';
return buttons;
}
},
],
order: [
[0, 'asc']
],
"pagingType": "numbers",
dom: 'rt'
});
我有一个 table,只要有人访问 URL /project_page
,它就会显示来自模型的内容。
在该页面上,用户可以添加文件,我希望 table 实时更新,而无需不断刷新。
为此,我尝试实现一个 Ajax 函数,每隔几秒更新一次 table 内容。因为这是几年前提出的
我认为该功能已实现并且我在 Ajax 成功功能中正确收到 data
但我不知道如何 'inject it' 到 table .
我也想知道是否有更优化或pythonic的方式来实现这个结果。
urls.py
path('project_page_ajax/', views.project_page_ajax, name='project_page_ajax'),
views.py
@login_required
def project_page(request):
context = {}
context['nbar'] = 'projects'
if request.method == 'POST':
print(request.FILES)
form = UploadFileForm(request.POST, request.FILES)
if form.is_valid():
file_hist = form.save(commit=False)
file_hist.user = request.user
# file is saved
file_hist.save()
file_hist_results = FileHistory.objects.all().filter(user=request.user)
context['file_hist_results'] = file_hist_results
print(type(context['file_hist_results']))
return render(request, 'project_page.html', context)
print (form.errors)
else:
form = UploadFileForm()
file_hist_results = FileHistory.objects.all().filter(user=request.user)
context['file_hist_results'] = file_hist_results
context['form'] = form
return render(request, 'project_page.html', context)
@login_required
def project_page_ajax(request):
response = dict()
if request.method == 'GET':
file_hist_results = FileHistory.objects.all().filter(user=request.user).values()
#response.update({'file_hist_results': file_hist_results})
return JsonResponse({"file_hist_results": list(file_hist_results)})
return HttpResponse('')
project_page.html
(JS部分)
var intervalID = setInterval(updateTable, 10000);
function updateTable()
{
$.ajax({
method: "GET",
url: "/project_page_ajax/",
success: function(data, textStatus, request) {
console.log(data);
}
});
}
project_page.html
(HTML部分)
<table id="ittFileUploadTable" class="display nowrap" width="100%">
<thead>
<tr class="ittLineItemsTh">
<th style="text-align:center;">File Name</th>
<th style="text-align:center;">Submitted</th>
<th style="text-align:center;">Updated</th>
<th style="text-align:center;">User</th>
<th style="text-align:center;">Action</th>
</tr>
</thead>
<tbody>
{% for histfiles in file_hist_results %}
<tr>
<td>{{ histfiles.filename }}</td>
<td>{{ histfiles.uploaded }}</td>
<td>{{ histfiles.updated }}</td>
<td>{{ histfiles.user }}</td>
<td>
<button id="delete-itt-file" type="button" class="btn btn-secondary">
<svg xmlns="http://www.w3.org/2000/svg" width="25" height="25" fill="currentColor" class="bi bi-trash-fill" viewBox="0 0 16 16">
<path d="M2.5 1a1 1 0 0 0-1 1v1a1 1 0 0 0 1 1H3v9a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2V4h.5a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1H10a1 1 0 0 0-1-1H7a1 1 0 0 0-1 1H2.5zm3 4a.5.5 0 0 1 .5.5v7a.5.5 0 0 1-1 0v-7a.5.5 0 0 1 .5-.5zM8 5a.5.5 0 0 1 .5.5v7a.5.5 0 0 1-1 0v-7A.5.5 0 0 1 8 5zm3 .5v7a.5.5 0 0 1-1 0v-7a.5.5 0 0 1 1 0z"></path>
</svg>
</button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
这个问题与 javascript.but 更相关这是我的想法,你可以如何用 partial_html.This 解决这个问题只是一个想法,但也许 javascript 人会附上漂亮的答案 ))).
views.py
from django.shortcuts import redirect
@login_required
def project_page(request):
context = {}
context['nbar'] = 'projects'
if request.method == 'POST':
print(request.FILES)
form = UploadFileForm(request.POST, request.FILES)
if form.is_valid():
file_hist = form.save(commit=False)
file_hist.user = request.user
# file is saved
file_hist.save()
return redirect('project_page')
print (form.errors)
else:
form = UploadFileForm()
file_hist_results = FileHistory.objects.all().filter(user=request.user)
context['file_hist_results'] = file_hist_results
context['form'] = form
return render(request, 'project_page.html', context)
@login_required
def project_page_ajax(request):
response = dict()
if request.method == 'GET':
file_hist_results = FileHistory.objects.all().filter(user=request.user).values()
return render(request, 'partial_page.html', {'file_hist_results':file_hist_results})
project_page.html
<table id="ittFileUploadTable" class="display nowrap" width="100%">
<thead>
<tr class="ittLineItemsTh">
<th style="text-align:center;">File Name</th>
<th style="text-align:center;">Submitted</th>
<th style="text-align:center;">Updated</th>
<th style="text-align:center;">User</th>
<th style="text-align:center;">Action</th>
</tr>
</thead>
<tbody>
{% for histfiles in file_hist_results %}
<tr>
<td>{{ histfiles.filename }}</td>
<td>{{ histfiles.uploaded }}</td>
<td>{{ histfiles.updated }}</td>
<td>{{ histfiles.user }}</td>
<td>
<button id="delete-itt-file" type="button" class="btn btn-secondary">
<svg xmlns="http://www.w3.org/2000/svg" width="25" height="25" fill="currentColor" class="bi bi-trash-fill" viewBox="0 0 16 16">
<path d="M2.5 1a1 1 0 0 0-1 1v1a1 1 0 0 0 1 1H3v9a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2V4h.5a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1H10a1 1 0 0 0-1-1H7a1 1 0 0 0-1 1H2.5zm3 4a.5.5 0 0 1 .5.5v7a.5.5 0 0 1-1 0v-7a.5.5 0 0 1 .5-.5zM8 5a.5.5 0 0 1 .5.5v7a.5.5 0 0 1-1 0v-7A.5.5 0 0 1 8 5zm3 .5v7a.5.5 0 0 1-1 0v-7a.5.5 0 0 1 1 0z"></path>
</svg>
</button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
partial_page.html(只是一个简单的 html 不要放置任何 body 或 head 标签,仅此创建该文件)
<table id="ittFileUploadTable" class="display nowrap" width="100%">
<thead>
<tr class="ittLineItemsTh">
<th style="text-align:center;">File Name</th>
<th style="text-align:center;">Submitted</th>
<th style="text-align:center;">Updated</th>
<th style="text-align:center;">User</th>
<th style="text-align:center;">Action</th>
</tr>
</thead>
<tbody>
{% for histfiles in file_hist_results %}
<tr>
<td>{{ histfiles.filename }}</td>
<td>{{ histfiles.uploaded }}</td>
<td>{{ histfiles.updated }}</td>
<td>{{ histfiles.user }}</td>
<td>
<button id="delete-itt-file" type="button" class="btn btn-secondary">
<svg xmlns="http://www.w3.org/2000/svg" width="25" height="25" fill="currentColor" class="bi bi-trash-fill" viewBox="0 0 16 16">
<path d="M2.5 1a1 1 0 0 0-1 1v1a1 1 0 0 0 1 1H3v9a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2V4h.5a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1H10a1 1 0 0 0-1-1H7a1 1 0 0 0-1 1H2.5zm3 4a.5.5 0 0 1 .5.5v7a.5.5 0 0 1-1 0v-7a.5.5 0 0 1 .5-.5zM8 5a.5.5 0 0 1 .5.5v7a.5.5 0 0 1-1 0v-7A.5.5 0 0 1 8 5zm3 .5v7a.5.5 0 0 1-1 0v-7a.5.5 0 0 1 1 0z"></path>
</svg>
</button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
js
var intervalID = setInterval(updateTable, 10000);
function updateTable()
{
$.ajax({
method: "GET",
url: "/project_page_ajax/",
success: function(response) {
$("#ittFileUploadTable").hide(); // first hide the current table
$("#ittFileUploadTable").append(response); // and append the data
}
});
}
解决方案很大程度上取决于 JSON 响应。
HTML
如果您的响应是要显示的实际 HTML 块,看起来有点像这样:
<tr><!-- Some tds --></tr>
<tr><!-- Some tds --></tr>
<tr><!-- Some tds --></tr>
<!-- ... -->
<tr><!-- Some tds --></tr>
那么你可以这样做:
document.querySelector("#ittFileUploadTable tbody").innerHTML = yourTemplate;
JSON
如果您的数据是 JSON,那么创建一个模板函数会很棒,例如:
function fileUploadRecordTemplate(record) {
return `
<td>record.filename</td>
<td>record.uploaded</td>
<td>record.updated</td>
<td>record.user</td>
<td>
<button id="delete-itt-file" type="button" class="btn btn-secondary">
<svg xmlns="http://www.w3.org/2000/svg" width="25" height="25" fill="currentColor" class="bi bi-trash-fill" viewBox="0 0 16 16">
<path d="M2.5 1a1 1 0 0 0-1 1v1a1 1 0 0 0 1 1H3v9a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2V4h.5a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1H10a1 1 0 0 0-1-1H7a1 1 0 0 0-1 1H2.5zm3 4a.5.5 0 0 1 .5.5v7a.5.5 0 0 1-1 0v-7a.5.5 0 0 1 .5-.5zM8 5a.5.5 0 0 1 .5.5v7a.5.5 0 0 1-1 0v-7A.5.5 0 0 1 8 5zm3 .5v7a.5.5 0 0 1-1 0v-7a.5.5 0 0 1 1 0z"></path>
</svg>
</button>
</td>
`;
}
然后像这样为您的 tbody
补水:
let output = [];
for (let record of data) output.push(fileUploadRecordTemplate(record));
document.querySelector("#ittFileUploadTable tbody").innerHTML = yourTemplate;
Fiddle
let index = 1;
//t1
function updateT1() {
//We generate some HTML, but if you get an HTML from server-side, then you can
//skip this part
let template = "";
let rows = parseInt(document.getElementById("t1rows").value);
for (let i = 0; i < rows; i++) {
template += `
<tr>
<td>${index++}</td>
<td>${index++}</td>
<td>${index++}</td>
<td>${index++}</td>
</tr>
`;
}
//This is the actual operation which refreshes the HTML
document.querySelector("#t1 > tbody").innerHTML = template;
}
//t2
function fileUploadRecordTemplate(record) {
return `
<tr>
<td>${record.filename}</td>
<td>${record.uploaded}</td>
<td>${record.updated}</td>
<td>${record.user}</td>
<td>
<button id="delete-itt-file" type="button" class="btn btn-secondary">
<svg xmlns="http://www.w3.org/2000/svg" width="25" height="25" fill="currentColor" class="bi bi-trash-fill" viewBox="0 0 16 16">
<path d="M2.5 1a1 1 0 0 0-1 1v1a1 1 0 0 0 1 1H3v9a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2V4h.5a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1H10a1 1 0 0 0-1-1H7a1 1 0 0 0-1 1H2.5zm3 4a.5.5 0 0 1 .5.5v7a.5.5 0 0 1-1 0v-7a.5.5 0 0 1 .5-.5zM8 5a.5.5 0 0 1 .5.5v7a.5.5 0 0 1-1 0v-7A.5.5 0 0 1 8 5zm3 .5v7a.5.5 0 0 1-1 0v-7a.5.5 0 0 1 1 0z"></path>
</svg>
</button>
</td>
</tr>
`;
}
function updateT2() {
let rows = parseInt(document.getElementById("t2rows").value);
let data = [];
for (let i = 0; i < rows; i++) {
data.push({
filename: index++,
uploaded: index++,
updated: index++,
user: index++
});
}
let output = [];
for (let record of data) output.push(fileUploadRecordTemplate(record));
document.querySelector("#t2 tbody").innerHTML = output.join("");
}
<table id="t1">
<thead>
<th>First</th>
<th>Second</th>
<th>Third</th>
<th>Fourth</th>
</thead>
<tbody>
</tbody>
</table>
Number of rows: <input type="number" value="4" id="t1rows"><input type="button" value="OK" onclick="updateT1()">
<table id="t2">
<thead>
<th>First</th>
<th>Second</th>
<th>Third</th>
<th>Fourth</th>
<th>Fifth</th>
</thead>
<tbody>
</tbody>
</table>
Number of rows: <input type="number" value="4" id="t2rows"><input type="button" value="OK" onclick="updateT2()">
我找到了解决办法!
正如@mark_b 所说,我使用数据表 Ajax 而不是 jQuery AJAX
现在可以了,这是我的代码:
$('#ittFileUploadTable').DataTable( {
responsive: true,
autowidth: false,
destroy: true,
deferRender: true,
ajax: {
url: '/project_page_ajax/',
type: 'GET',
data: {},
dataSrc: ""
},
columns: [
{"data": "fields.filename"},
{"data": "fields.uploaded"},
{"data": "fields.updated"},
{"data": "fields.user"},
{"data": "pk"},
],
columnDefs: [
{ className: 'text-center', targets: [1] },
{
targets: [0],
class: 'text-center',
orderable: false,
render: function (data, type, row) {
var buttons = '<a href="/media/'+data+'" target="_blank">'+data+'</a>';
return buttons;
}
},
{
targets: [-1],
class: 'text-center',
orderable: false,
render: function (data, type, row) {
var buttons = '<form method="post" action="delete_file/'+data+'/"><button type="submit" class="btn btn-danger"><svg xmlns="http://www.w3.org/2000/svg" width="25" height="25" fill="white" class="bi bi-trash-fill" viewBox="0 0 16 16"><path d="M2.5 1a1 1 0 0 0-1 1v1a1 1 0 0 0 1 1H3v9a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2V4h.5a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1H10a1 1 0 0 0-1-1H7a1 1 0 0 0-1 1H2.5zm3 4a.5.5 0 0 1 .5.5v7a.5.5 0 0 1-1 0v-7a.5.5 0 0 1 .5-.5zM8 5a.5.5 0 0 1 .5.5v7a.5.5 0 0 1-1 0v-7A.5.5 0 0 1 8 5zm3 .5v7a.5.5 0 0 1-1 0v-7a.5.5 0 0 1 1 0z"/></svg></button></form>';
return buttons;
}
},
],
order: [
[0, 'asc']
],
"pagingType": "numbers",
dom: 'rt'
});