How to update a Datatable via Ajax call - javascript

I have a table that displays the content from a model whenever someone accesses the URL /project_page.
On that page, the user can add files and I would like the table to be updated in real-time without having to constantly refresh.
For that purpose, I have tried to implement an Ajax function that updates the table content every few seconds. Since it is something that was suggested a few years ago here
I think the function is implemented and I receive the data properly in the Ajax success function but I don't know how to 'inject it' to the table.
I would also like to know if there is a more optimal or pythonic way to achieve this result.
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 PART)
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 PART)
<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>

this question is more related to javascript.but here is my idea how you can solve this with partial_html.This is just an idea how you can do it but maybe a javascript guy will come with a beautifull answer ))).
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(just a simple html do not put any body or head tag just this create that file with only this)
<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
}
});
}

The solution largely depends on what the JSON response is.
HTML
If your response is the actual HTML chunk to be displayed, looking somewhat like this:
<tr><!-- Some tds --></tr>
<tr><!-- Some tds --></tr>
<tr><!-- Some tds --></tr>
<!-- ... -->
<tr><!-- Some tds --></tr>
Then you can do it like this:
document.querySelector("#ittFileUploadTable tbody").innerHTML = yourTemplate;
JSON
If your data is JSON, then it would be great to create a template function, like this one:
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>
`;
}
And hydrate your tbody like this:
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()">

I found a solution!
As #mark_b sugested, I used the datatables Ajax instead of jQuery AJAX
Now it works, here is my code:
$('#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 = ''+data+'';
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'
});

Related

Button working on second click instead of first in Reactjs

I am i working on Reactjs/nextjs and right now in my page video with audio button,i want two things
1) I want "by default" there should be "bi bi-volume-mute" class in button instead of "bi bi-volume-down"
2) whenever i click on unmute ( after mute) then its not working with one click but if i click on second time then its working , in other words should be "mute or unmute" with single click
Here is my current code
function handleAudio() {
if (ref.current.paused) {
setMuted(false);
ref.current.play();
} else {
setMuted(true);
ref.current.pause();
}
}
<buton onClick={handleAudio} className="customAudioPlayerButton">
{!muted ? (
<svg
xmlns="http://www.w3.org/2000/svg"
width="30"
height="30"
fill="currentColor"
className="bi bi-volume-down"
viewBox="0 0 16 16"
>
<path d="M9 4a.5.5 0 0 0-.812-.39L5.825 5.5H3.5A.5.5 0 0 0 3 6v4a.5.5 0 0 0 .5.5h2.325l2.363 1.89A.5.5 0 0 0 9 12V4zM6.312 6.39 8 5.04v5.92L6.312 9.61A.5.5 0 0 0 6 9.5H4v-3h2a.5.5 0 0 0 .312-.11zM12.025 8a4.486 4.486 0 0 1-1.318 3.182L10 10.475A3.489 3.489 0 0 0 11.025 8 3.49 3.49 0 0 0 10 5.525l.707-.707A4.486 4.486 0 0 1 12.025 8z" />
</svg>
) : (
<svg
xmlns="http://www.w3.org/2000/svg"
width="30"
height="30"
fill="currentColor"
className="bi bi-volume-mute"
viewBox="0 0 16 16"
>
<path d="M6.717 3.55A.5.5 0 0 1 7 4v8a.5.5 0 0 1-.812.39L3.825 10.5H1.5A.5.5 0 0 1 1 10V6a.5.5 0 0 1 .5-.5h2.325l2.363-1.89a.5.5 0 0 1 .529-.06zM6 5.04 4.312 6.39A.5.5 0 0 1 4 6.5H2v3h2a.5.5 0 0 1 .312.11L6 10.96V5.04zm7.854.606a.5.5 0 0 1 0 .708L12.207 8l1.647 1.646a.5.5 0 0 1-.708.708L11.5 8.707l-1.646 1.647a.5.5 0 0 1-.708-.708L10.793 8 9.146 6.354a.5.5 0 1 1 .708-.708L11.5 7.293l1.646-1.647a.5.5 0 0 1 .708 0z" />
</svg>
)}
</buton>
can you please try this function.
function handleAudio() {
if (muted) {
setMuted(false);
ref.current.play();
} else {
setMuted(true);
ref.current.pause();
}
}

How to print a div that has a canvas using JavaScript and html?

Hi I wanted to print a specific div that has a canvas consisting of a chart. I had written a script to print the specific div in my HTML body tag but it returns everything except the graph.
This is what I want:
This is what I get:
How can I achieve the results shown in image 1? Thanks in advance.
This is my code for the script:
<script>
//Print specific div
function printFunc() {
var tagname = $('#div-report').prop("tagName").toLowerCase();
var attributes = "";
var attrs = document.getElementById("div-report").attributes;
$.each(attrs, function(i, elem) {
attributes += " " + elem.name + " ='" + elem.value + "' ";
})
var divToPrint = $('#div-report').html();
var head = "<html><head>" + $("head").html() + "</head>";
var allcontent = head + "<body onload='window.print()' >" + "<" + tagname + attributes + ">" + divToPrint + "</" + tagname + ">" + "</body></html>";
var newWin = window.open('', 'Print-Window');
newWin.document.open();
newWin.document.write(allcontent);
newWin.document.close();
};
</script>
This is my code for the front-end HTML(in case you need it):
<body class="d-flex flex-column">
<div class="container p-2 pb-0 mt-5 pt-3" id="admin-dashboard">
<h2 class="pt-3 pb-5 display-6">Report Summary</h2>
<div class="row g-2 mb-5 justify-content-md-end">
<div class="col-auto">
<button type="button" onclick="printFunc()" class="btn btn-outline-primary" style="--bs-btn-padding-y: .5rem; --bs-btn-padding-x: 1rem; --bs-btn-font-size: .75rem;">Print</button>
</div>
</div>
</div>
<div class="container pb-0" id="div-report">
<div ALIGN=CENTER>
<b>
<h6>Report Summary Generated on DD/MM/YYYY
</b>
</div>
<br />
<div ALIGN=CENTER>
<p>
Demo
</p>
</div>
<a class=" nav nav-item text-decoration-none text-muted" href="cstaff-report-generation.php">
<i class="bi bi-arrow-left-square me-2"></i>Go back</a>
<div class="row row-cols-2 row-cols-md-3 g-3 py-3">
<div class="col">
<div class="card border-info">
<div class="card-body">
<h6 class="card-title">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" class="bi bi-cash" viewBox="0 0 16 16">
<path d="M8 10a2 2 0 1 0 0-4 2 2 0 0 0 0 4z" />
<path d="M0 4a1 1 0 0 1 1-1h14a1 1 0 0 1 1 1v8a1 1 0 0 1-1 1H1a1 1 0 0 1-1-1V4zm3 0a2 2 0 0 1-2 2v4a2 2 0 0 1 2 2h10a2 2 0 0 1 2-2V6a2 2 0 0 1-2-2H3z" />
</svg>
Total Sales Revenue
</h6>
<p class="card-text my-2">
Demo
</p>
</div>
</div>
</div>
<div class="col">
<div class="card border-info">
<div class="card-body">
<h6 class="card-title">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" class="bi bi-receipt" viewBox="0 0 16 16">
<path d="M1.92.506a.5.5 0 0 1 .434.14L3 1.293l.646-.647a.5.5 0 0 1 .708 0L5 1.293l.646-.647a.5.5 0 0 1 .708 0L7 1.293l.646-.647a.5.5 0 0 1 .708 0L9 1.293l.646-.647a.5.5 0 0 1 .708 0l.646.647.646-.647a.5.5 0 0 1 .708 0l.646.647.646-.647a.5.5 0 0 1 .801.13l.5 1A.5.5 0 0 1 15 2v12a.5.5 0 0 1-.053.224l-.5 1a.5.5 0 0 1-.8.13L13 14.707l-.646.647a.5.5 0 0 1-.708 0L11 14.707l-.646.647a.5.5 0 0 1-.708 0L9 14.707l-.646.647a.5.5 0 0 1-.708 0L7 14.707l-.646.647a.5.5 0 0 1-.708 0L5 14.707l-.646.647a.5.5 0 0 1-.708 0L3 14.707l-.646.647a.5.5 0 0 1-.801-.13l-.5-1A.5.5 0 0 1 1 14V2a.5.5 0 0 1 .053-.224l.5-1a.5.5 0 0 1 .367-.27zm.217 1.338L2 2.118v11.764l.137.274.51-.51a.5.5 0 0 1 .707 0l.646.647.646-.646a.5.5 0 0 1 .708 0l.646.646.646-.646a.5.5 0 0 1 .708 0l.646.646.646-.646a.5.5 0 0 1 .708 0l.646.646.646-.646a.5.5 0 0 1 .708 0l.646.646.646-.646a.5.5 0 0 1 .708 0l.509.509.137-.274V2.118l-.137-.274-.51.51a.5.5 0 0 1-.707 0L12 1.707l-.646.647a.5.5 0 0 1-.708 0L10 1.707l-.646.647a.5.5 0 0 1-.708 0L8 1.707l-.646.647a.5.5 0 0 1-.708 0L6 1.707l-.646.647a.5.5 0 0 1-.708 0L4 1.707l-.646.647a.5.5 0 0 1-.708 0l-.509-.51z" />
<path d="M3 4.5a.5.5 0 0 1 .5-.5h6a.5.5 0 1 1 0 1h-6a.5.5 0 0 1-.5-.5zm0 2a.5.5 0 0 1 .5-.5h6a.5.5 0 1 1 0 1h-6a.5.5 0 0 1-.5-.5zm0 2a.5.5 0 0 1 .5-.5h6a.5.5 0 1 1 0 1h-6a.5.5 0 0 1-.5-.5zm0 2a.5.5 0 0 1 .5-.5h6a.5.5 0 0 1 0 1h-6a.5.5 0 0 1-.5-.5zm8-6a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 0 1h-1a.5.5 0 0 1-.5-.5zm0 2a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 0 1h-1a.5.5 0 0 1-.5-.5zm0 2a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 0 1h-1a.5.5 0 0 1-.5-.5zm0 2a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 0 1h-1a.5.5 0 0 1-.5-.5z" />
</svg>
Total Number of Order Placed
</h6>
<p class="card-text my-2">
Demo
</p>
</div>
</div>
</div>
<div class="col">
<div class="card border-info">
<div class="card-body">
<h6 class="card-title">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" class="bi bi-person-check" viewBox="0 0 16 16">
<path d="M6 8a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm2-3a2 2 0 1 1-4 0 2 2 0 0 1 4 0zm4 8c0 1-1 1-1 1H1s-1 0-1-1 1-4 6-4 6 3 6 4zm-1-.004c-.001-.246-.154-.986-.832-1.664C9.516 10.68 8.289 10 6 10c-2.29 0-3.516.68-4.168 1.332-.678.678-.83 1.418-.832 1.664h10z" />
<path fill-rule="evenodd" d="M15.854 5.146a.5.5 0 0 1 0 .708l-3 3a.5.5 0 0 1-.708 0l-1.5-1.5a.5.5 0 0 1 .708-.708L12.5 7.793l2.646-2.647a.5.5 0 0 1 .708 0z" />
</svg>
Total Number of Customer Visited
</h6>
<p class="card-text my-2">
Demo
</p>
</div>
</div>
</div>
<div class="col">
<div class="card border-info">
<div class="card-body">
<h6 class="card-title">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" class="bi bi-diagram-2" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M6 3.5A1.5 1.5 0 0 1 7.5 2h1A1.5 1.5 0 0 1 10 3.5v1A1.5 1.5 0 0 1 8.5 6v1H11a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-1 0V8h-5v.5a.5.5 0 0 1-1 0v-1A.5.5 0 0 1 5 7h2.5V6A1.5 1.5 0 0 1 6 4.5v-1zM8.5 5a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1zM3 11.5A1.5 1.5 0 0 1 4.5 10h1A1.5 1.5 0 0 1 7 11.5v1A1.5 1.5 0 0 1 5.5 14h-1A1.5 1.5 0 0 1 3 12.5v-1zm1.5-.5a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1zm4.5.5a1.5 1.5 0 0 1 1.5-1.5h1a1.5 1.5 0 0 1 1.5 1.5v1a1.5 1.5 0 0 1-1.5 1.5h-1A1.5 1.5 0 0 1 9 12.5v-1zm1.5-.5a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1z" />
</svg>
Best-Selling Menu Item
</h6>
<p class="card-text my-2">
Demo
</p>
</div>
</div>
</div>
<div class="col">
<div class="card border-info">
<div class="card-body">
<h6 class="card-title">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" class="bi bi-hourglass-split" viewBox="0 0 16 16">
<path d="M2.5 15a.5.5 0 1 1 0-1h1v-1a4.5 4.5 0 0 1 2.557-4.06c.29-.139.443-.377.443-.59v-.7c0-.213-.154-.451-.443-.59A4.5 4.5 0 0 1 3.5 3V2h-1a.5.5 0 0 1 0-1h11a.5.5 0 0 1 0 1h-1v1a4.5 4.5 0 0 1-2.557 4.06c-.29.139-.443.377-.443.59v.7c0 .213.154.451.443.59A4.5 4.5 0 0 1 12.5 13v1h1a.5.5 0 0 1 0 1h-11zm2-13v1c0 .537.12 1.045.337 1.5h6.326c.216-.455.337-.963.337-1.5V2h-7zm3 6.35c0 .701-.478 1.236-1.011 1.492A3.5 3.5 0 0 0 4.5 13s.866-1.299 3-1.48V8.35zm1 0v3.17c2.134.181 3 1.48 3 1.48a3.5 3.5 0 0 0-1.989-3.158C8.978 9.586 8.5 9.052 8.5 8.351z" />
</svg>
Peak Hour
</h6>
<p class="card-text my-2">
Demo
</p>
</div>
</div>
</div>
</div>
<br />
<h4 class="border-top fw-light pt-3 mt-2">Menu Performance</h4>
<div class="container p-2 pb-0 mt-2 mb-5 pt-3" style="text-align: center;">
<canvas id="mpChart"></canvas>
</div>
</div>

Filter table rows with vuejs

Hi i want to filter and sor a table in vue js. I do this but when i text in the textbox the letter that i want to search the table is empty. I want to filter the rows and display the ones that matches whatever is in this input.
I hope I am making sense. I do not know how to proceed from here. Cookies and a big thank you to anyone who helps!
<script>
import axios from 'axios'
export default {
name: 'Utenti',
data() {
return {
utenti: [],
modalTitle: '',
UtenteTessera: 0,
UtenteNome: '',
UtenteCognome: '',
UtenteEmail: '',
UtenteTelefono: '',
UtenteNomeFilter: '',
UtenteTesseraFilter: '',
utentiWithoutFilter: [],
}
},
methods: {
refreshData() {
axios.post('https://localhost:7285/Utenti/GetDati').then((response) => {
this.utenti = response.data.prova
this.utentiWithoutFilter = response.data.prova
})
},
FilterFn() {
const UtenteTesseraFilter = this.UtenteTesseraFilter
const UtenteNomeFilter = this.UtenteNomeFilter
this.utenti = this.utentiWithoutFilter.filter(function (el) {
return (
el.UtenteTessera.toString()
.toLowerCase()
.includes(UtenteTesseraFilter.toString().trim().toLowerCase()) &&
el.UtenteNome.toString()
.toLowerCase()
.includes(UtenteNomeFilter.toString().trim().toLowerCase())
)
})
},
sortResult(prop, asc) {
this.utenti = this.utentiWithoutFilter.sort(function (a, b) {
if (asc) {
return a[prop] > b[prop] ? 1 : a[prop] < b[prop] ? -1 : 0
} else {
return b[prop] > a[prop] ? 1 : b[prop] < a[prop] ? -1 : 0
}
})
},
},
}
</script>
<template>
<div>
<table class="table table-striped">
<thead>
<tr>
<th>
<div class="d-flex flex-row">
<input
v-model="UtenteTesseraFilter"
class="form-control m-2"
placeholder="Filter"
#keyup="FilterFn()"
/>
<button
type="button"
class="btn btn-light"
#click="sortResult('UtenteTessera', true)"
>
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
fill="currentColor"
class="bi bi-arrow-down-square-fill"
viewBox="0 0 16 16"
>
<path
d="M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2zm6.5 4.5v5.793l2.146-2.147a.5.5 0 0 1 .708.708l-3 3a.5.5 0 0 1-.708 0l-3-3a.5.5 0 1 1 .708-.708L7.5 10.293V4.5a.5.5 0 0 1 1 0z"
/>
</svg>
</button>
<button
type="button"
class="btn btn-light"
#click="sortResult('UtenteTessera', false)"
>
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
fill="currentColor"
class="bi bi-arrow-up-square-fill"
viewBox="0 0 16 16"
>
<path
d="M2 16a2 2 0 0 1-2-2V2a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2zm6.5-4.5V5.707l2.146 2.147a.5.5 0 0 0 .708-.708l-3-3a.5.5 0 0 0-.708 0l-3 3a.5.5 0 1 0 .708.708L7.5 5.707V11.5a.5.5 0 0 0 1 0z"
/>
</svg>
</button>
</div>
Tessera
</th>
<th>
<div class="d-flex flex-row">
<input
v-model="UtenteNomeFilter"
class="form-control m-2"
placeholder="Filter"
#keyup="FilterFn()"
/>
<button
type="button"
class="btn btn-light"
#click="sortResult('UtenteNome', true)"
>
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
fill="currentColor"
class="bi bi-arrow-down-square-fill"
viewBox="0 0 16 16"
>
<path
d="M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2zm6.5 4.5v5.793l2.146-2.147a.5.5 0 0 1 .708.708l-3 3a.5.5 0 0 1-.708 0l-3-3a.5.5 0 1 1 .708-.708L7.5 10.293V4.5a.5.5 0 0 1 1 0z"
/>
</svg>
</button>
<button
type="button"
class="btn btn-light"
#click="sortResult('UtenteNome', false)"
>
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
fill="currentColor"
class="bi bi-arrow-up-square-fill"
viewBox="0 0 16 16"
>
<path
d="M2 16a2 2 0 0 1-2-2V2a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2zm6.5-4.5V5.707l2.146 2.147a.5.5 0 0 0 .708-.708l-3-3a.5.5 0 0 0-.708 0l-3 3a.5.5 0 1 0 .708.708L7.5 5.707V11.5a.5.5 0 0 0 1 0z"
/>
</svg>
</button>
</div>
UtenteNome
</th>
<th>Options</th>
</tr>
</thead>
</table>
<table class="table table-striped" style="z-index: 1">
<thead>
<tr>
<th>Tessera</th>
<th>Nome</th>
<th>Cognome</th>
<th>Email</th>
<th>Telefono</th>
</tr>
</thead>
<tbody>
<!--<tr v-for="info in info" :key="index">-->
<tr v-for="utente in utenti" :key="title">
<td>{{ utente.tessera }}</td>
<td>{{ utente.nome }}</td>
<td>{{ utente.cognome }}</td>
<td>{{ utente.email }}</td>
<td>{{ utente.telefono }}</td>
</tr>
</tbody>
</table>
</div>
</template>
You treat "filter" and "sort" as two different operations but those are two operations that need to be applied at the same time (so that sorting does not overwrite filtering result and vice versa). Also you are not using Vue reactivity at all. This is perfect use case for computed
This computed has 3 inputs:
unfiltered and no sorted original array
active filter
active sort
<script>
import axios from 'axios'
export default {
name: 'Utenti',
data() {
return {
utenti: [],
modalTitle: '',
UtenteTessera: 0,
UtenteNome: '',
UtenteCognome: '',
UtenteEmail: '',
UtenteTelefono: '',
UtenteNomeFilter: '',
UtenteTesseraFilter: '',
// NEW
sort: {
prop: undefined,
asc: true
}
}
},
computed: {
utentiToDisplay() {
// filter first - this creates new array
const result = this.utenti.filter(el =>
el.UtenteTessera.toString()
.toLowerCase()
.includes(
this.UtenteTesseraFilter.toString().trim().toLowerCase()
)
&&
el.UtenteNome.toString()
.toLowerCase()
.includes(
this.UtenteNomeFilter.toString().trim().toLowerCase()
)
)
// now sort the results in-place if needed
if(this.sort.prop) {
result.sort((a, b) => {
if (this.sort.asc) {
return a[prop] > b[prop] ? 1 : a[prop] < b[prop] ? -1 : 0
} else {
return b[prop] > a[prop] ? 1 : b[prop] < a[prop] ? -1 : 0
}
})
}
return result
}
},
methods: {
refreshData() {
axios.post('https://localhost:7285/Utenti/GetDati').then((response) => { this.utenti = response.data.prova })
},
setSort(prop, asc) {
this.sort.prop = prop
this.sort.asc = asc
}
},
}
</script>
<div>
<table class="table table-striped">
<thead>
<tr>
<th>
<div class="d-flex flex-row">
<input
v-model="UtenteTesseraFilter"
class="form-control m-2"
placeholder="Filter"
/>
<button
type="button"
class="btn btn-light"
#click="setSort('UtenteTessera', true)"
>
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
fill="currentColor"
class="bi bi-arrow-down-square-fill"
viewBox="0 0 16 16"
>
<path
d="M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2zm6.5 4.5v5.793l2.146-2.147a.5.5 0 0 1 .708.708l-3 3a.5.5 0 0 1-.708 0l-3-3a.5.5 0 1 1 .708-.708L7.5 10.293V4.5a.5.5 0 0 1 1 0z"
/>
</svg>
</button>
<button
type="button"
class="btn btn-light"
#click="setSort('UtenteTessera', false)"
>
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
fill="currentColor"
class="bi bi-arrow-up-square-fill"
viewBox="0 0 16 16"
>
<path
d="M2 16a2 2 0 0 1-2-2V2a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2zm6.5-4.5V5.707l2.146 2.147a.5.5 0 0 0 .708-.708l-3-3a.5.5 0 0 0-.708 0l-3 3a.5.5 0 1 0 .708.708L7.5 5.707V11.5a.5.5 0 0 0 1 0z"
/>
</svg>
</button>
</div>
Tessera
</th>
<th>
<div class="d-flex flex-row">
<input
v-model="UtenteNomeFilter"
class="form-control m-2"
placeholder="Filter"
/>
<button
type="button"
class="btn btn-light"
#click="setSort('UtenteNome', true)"
>
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
fill="currentColor"
class="bi bi-arrow-down-square-fill"
viewBox="0 0 16 16"
>
<path
d="M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2zm6.5 4.5v5.793l2.146-2.147a.5.5 0 0 1 .708.708l-3 3a.5.5 0 0 1-.708 0l-3-3a.5.5 0 1 1 .708-.708L7.5 10.293V4.5a.5.5 0 0 1 1 0z"
/>
</svg>
</button>
<button
type="button"
class="btn btn-light"
#click="setSort('UtenteNome', false)"
>
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
fill="currentColor"
class="bi bi-arrow-up-square-fill"
viewBox="0 0 16 16"
>
<path
d="M2 16a2 2 0 0 1-2-2V2a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2zm6.5-4.5V5.707l2.146 2.147a.5.5 0 0 0 .708-.708l-3-3a.5.5 0 0 0-.708 0l-3 3a.5.5 0 1 0 .708.708L7.5 5.707V11.5a.5.5 0 0 0 1 0z"
/>
</svg>
</button>
</div>
UtenteNome
</th>
<th>Options</th>
</tr>
</thead>
</table>
<table class="table table-striped" style="z-index: 1">
<thead>
<tr>
<th>Tessera</th>
<th>Nome</th>
<th>Cognome</th>
<th>Email</th>
<th>Telefono</th>
</tr>
</thead>
<tbody>
<!--<tr v-for="info in info" :key="index">-->
<tr v-for="utente in utentiToDisplay" :key="title">
<td>{{ utente.tessera }}</td>
<td>{{ utente.nome }}</td>
<td>{{ utente.cognome }}</td>
<td>{{ utente.email }}</td>
<td>{{ utente.telefono }}</td>
</tr>
</tbody>
</table>
</div>
</template>
I've solved it.
<script>
import axios from "axios"
export default {
name: "Utenti",
data() {
return {
utenti: [],
modalTitle: "",
UtenteTessera: 0,
UtenteNome: "",
UtenteCognome: "",
UtenteEmail: "",
UtenteTelefono: "",
UtenteNomeFilter: "",
UtenteTesseraFilter: "",
sortKey: 'nome',
reverse:false
}
},
computed: {
utentiToDisplay() {
return this.utenti.filter(this.filterByName)
.filter(this.filterByTessera)
.sort(this.orderBy);
}
},
methods: {
filterByName: function (utente) {
if (this.UtenteNomeFilter.length === 0) {
return true;
}
return (utente.nome.toLowerCase().indexOf(this.UtenteNomeFilter.toLowerCase()) > -1);
},
filterByTessera: function (utente) {
if (this.UtenteTesseraFilter.length === 0) {
return true;
}
return (utente.tessera.toLowerCase().indexOf(this.UtenteTesseraFilter.toLowerCase()) > -1);
},
orderBy: function (utenteA, utenteB) {
let condition = (utenteA[this.sortKey] > utenteB[this.sortKey]);
if (this.reverse) {
return !condition;
}
else {
return condition;
}
}
}
And the template
<div>
<table class="table table-striped">
<thead>
<tr>
<th>
<div class="d-flex flex-row">
<input
v-model="UtenteTesseraFilter"
class="form-control m-2"
placeholder="Filter"
/>
<button
type="button"
class="btn btn-light"
#click="setSort('UtenteTessera', true)"
>
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
fill="currentColor"
class="bi bi-arrow-down-square-fill"
viewBox="0 0 16 16"
>
<path
d="M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2zm6.5 4.5v5.793l2.146-2.147a.5.5 0 0 1 .708.708l-3 3a.5.5 0 0 1-.708 0l-3-3a.5.5 0 1 1 .708-.708L7.5 10.293V4.5a.5.5 0 0 1 1 0z"
/>
</svg>
</button>
<button
type="button"
class="btn btn-light"
#click="setSort('UtenteTessera', false)"
>
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
fill="currentColor"
class="bi bi-arrow-up-square-fill"
viewBox="0 0 16 16"
>
<path
d="M2 16a2 2 0 0 1-2-2V2a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2zm6.5-4.5V5.707l2.146 2.147a.5.5 0 0 0 .708-.708l-3-3a.5.5 0 0 0-.708 0l-3 3a.5.5 0 1 0 .708.708L7.5 5.707V11.5a.5.5 0 0 0 1 0z"
/>
</svg>
</button>
</div>
Tessera
</th>
<th>
<div class="d-flex flex-row">
<input
v-model="UtenteNomeFilter"
class="form-control m-2"
placeholder="Filter"
/>
<button
type="button"
class="btn btn-light"
#click="setSort('UtenteNome', true)"
>
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
fill="currentColor"
class="bi bi-arrow-down-square-fill"
viewBox="0 0 16 16"
>
<path
d="M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2zm6.5 4.5v5.793l2.146-2.147a.5.5 0 0 1 .708.708l-3 3a.5.5 0 0 1-.708 0l-3-3a.5.5 0 1 1 .708-.708L7.5 10.293V4.5a.5.5 0 0 1 1 0z"
/>
</svg>
</button>
<button
type="button"
class="btn btn-light"
#click="setSort('UtenteNome', false)"
>
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
fill="currentColor"
class="bi bi-arrow-up-square-fill"
viewBox="0 0 16 16"
>
<path
d="M2 16a2 2 0 0 1-2-2V2a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2zm6.5-4.5V5.707l2.146 2.147a.5.5 0 0 0 .708-.708l-3-3a.5.5 0 0 0-.708 0l-3 3a.5.5 0 1 0 .708.708L7.5 5.707V11.5a.5.5 0 0 0 1 0z"
/>
</svg>
</button>
</div>
UtenteNome
</th>
<th>Options</th>
</tr>
</thead>
</table>
<table class="table table-striped" style="z-index: 1">
<thead>
<tr>
<th>Tessera</th>
<th>Nome</th>
<th>Cognome</th>
<th>Email</th>
<th>Telefono</th>
</tr>
</thead>
<tbody>
<!--<tr v-for="info in info" :key="index">-->
<tr v-for="utente in utentiToDisplay" :key="title">
<td>{{ utente.tessera }}</td>
<td>{{ utente.nome }}</td>
<td>{{ utente.cognome }}</td>
<td>{{ utente.email }}</td>
<td>{{ utente.telefono }}</td>
</tr>
</tbody>
</table>
</div>
</template>

Data not showing from web api to React in front-end

I'm trying to fetch data from webapi to display in react js tables, everything seems to work fine only text is not being displayed in these table the look empty[!
What might be the problem here, because I can't figure it out for days.
Image of Table
this is the error Im getting in console
This is my Department.js file
import React,{Component} from 'react';
import { Table } from 'react-bootstrap';
import { ModalBody, ModalTitle } from 'react-bootstrap';
import { variables } from './variables';
export class Department extends Component{
constructor(props){
super(props);
this.state={
departments:[],
modalTitle:"",
DepartmentName:"",
DepartmentId:0,
DepartmentIdFilter:"",
DepartmentNameFilter:"",
departmentsWithoutFilter:[]
}
}
FilterFn(){
var DepartmentIdFilter=this.state.DepartmentIdFilter;
var DepartmentNameFilter = this.state.DepartmentNameFilter;
var filteredData=this.state.departmentsWithoutFilter.filter(
function(el){
return el.DepartmentId.toString().toLowerCase().includes(
DepartmentIdFilter.toString().trim().toLowerCase()
)&&
el.DepartmentName.toString().toLowerCase().includes(
DepartmentNameFilter.toString().trim().toLowerCase()
)
}
);
this.setState({departments:filteredData});
}
sortResult(prop,asc){
var sortedData=this.state.departmentsWithoutFilter.sort(function(a,b){
if(asc){
return (a[prop]>b[prop])?1:((a[prop]<b[prop])?-1:0);
}
else{
return (b[prop]>a[prop])?1:((b[prop]<a[prop])?-1:0);
}
});
this.setState({departments:sortedData});
}
changeDepartmentIdFilter = (e)=>{
this.state.DepartmentIdFilter=e.target.value;
this.FilterFn();
}
changeDepartmentNameFilter = (e)=>{
this.state.DepartmentNameFilter=e.target.value;
this.FilterFn();
}
refreshList(){
fetch(variables.API_URL+'departments')
.then(response=>response.json())
.then(data=>{
this.setState({departments:data,departmentsWithoutFilter:data});
});
}
componentDidMount(){
this.refreshList();
}
changeDepartmentName =(e)=>{
this.setState({DepartmentName:e.target.value});
}
addClick(){
this.setState({
modalTitle:"Add Department",
DepartmentId:0,
DepartmentName:""
});
}
editClick(dep){
this.setState({
modalTitle:"Edit Department",
DepartmentId:dep.DepartmentId,
DepartmentName:dep.DepartmentName
});
}
createClick(){
fetch(variables.API_URL+'departments',{
method:'POST',
headers:{
'Accept':'application/json',
'Content-Type':'application/json'
},
body:JSON.stringify({
DepartmentName:this.state.DepartmentName
})
})
.then(res=>res.json())
.then((result)=>{
alert(result);
this.refreshList();
},(error)=>{
alert('Failed');
})
}
updateClick(){
fetch(variables.API_URL+'departments',{
method:'PUT',
headers:{
'Accept':'application/json',
'Content-Type':'application/json'
},
body:JSON.stringify({
DepartmentId:this.state.DepartmentId,
DepartmentName:this.state.DepartmentName
})
})
.then(res=>res.json())
.then((result)=>{
alert(result);
this.refreshList();
},(error)=>{
alert('Failed');
})
}
deleteClick(id){
if(window.confirm('Are you sure?')){
fetch(variables.API_URL+'departments/'+ id,{
mode:'no-cors',
method:'DELETE',
headers:{
'Accept':'application/json',
'Content-Type':'application/json'
}
})
.then(res=>res.json())
.then((result)=>{
alert(result);
this.refreshList();
},(error)=>{
alert('Failed');
})
}
}
render(){
const {
departments,
modalTitle,
DepartmentId,
DepartmentName
}=this.state;
return(
<div>
<button type="button"
className="btn btn-primary m-2 float-end"
data-bs-toggle="modal"
data-bs-target="#exampleModal"
onClick={()=>this.addClick()}>
Add Department
</button>
<table className="table table-striped">
<thead>
<tr key={Department.id}>
<th>
<div className="d-flex flex-row">
<input className="form-control m-2"
onChange={this.changeDepartmentIdFilter}
placeholder="Filter"/>
<button type="button" className="btn btn-light"
onClick={()=>this.sortResult('DepartmentId',true)}>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" className="bi bi-arrow-down-square-fill" viewBox="0 0 16 16">
<path d="M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2zm6.5 4.5v5.793l2.146-2.147a.5.5 0 0 1 .708.708l-3 3a.5.5 0 0 1-.708 0l-3-3a.5.5 0 1 1 .708-.708L7.5 10.293V4.5a.5.5 0 0 1 1 0z"/>
</svg>
</button>
<button type="button" className="btn btn-light"
onClick={()=>this.sortResult('DepartmentId',false)}>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" className="bi bi-arrow-up-square-fill" viewBox="0 0 16 16">
<path d="M2 16a2 2 0 0 1-2-2V2a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2zm6.5-4.5V5.707l2.146 2.147a.5.5 0 0 0 .708-.708l-3-3a.5.5 0 0 0-.708 0l-3 3a.5.5 0 1 0 .708.708L7.5 5.707V11.5a.5.5 0 0 0 1 0z"/>
</svg>
</button>
</div>
DepartmentId
</th>
<th>
<div className="d-flex flex-row">
<input className="form-control m-2"
onChange={this.changeDepartmentNameFilter}
placeholder="Filter"/>
<button type="button" className="btn btn-light"
onClick={()=>this.sortResult('DepartmentName',true)}>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" className="bi bi-arrow-down-square-fill" viewBox="0 0 16 16">
<path d="M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2zm6.5 4.5v5.793l2.146-2.147a.5.5 0 0 1 .708.708l-3 3a.5.5 0 0 1-.708 0l-3-3a.5.5 0 1 1 .708-.708L7.5 10.293V4.5a.5.5 0 0 1 1 0z"/>
</svg>
</button>
<button type="button" className="btn btn-light"
onClick={()=>this.sortResult('DepartmentName',false)}>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" className="bi bi-arrow-up-square-fill" viewBox="0 0 16 16">
<path d="M2 16a2 2 0 0 1-2-2V2a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2zm6.5-4.5V5.707l2.146 2.147a.5.5 0 0 0 .708-.708l-3-3a.5.5 0 0 0-.708 0l-3 3a.5.5 0 1 0 .708.708L7.5 5.707V11.5a.5.5 0 0 0 1 0z"/>
</svg>
</button>
</div>
DepartmentName
</th>
<th>
Options
</th>
</tr>
</thead>
<tbody>
{departments.map(dep=>
<tr key={dep.DepartmentId}>
<td>{dep.DepartmentId}</td>
<td>{dep.DepartmentName}</td>
<td>
<button type="button"
className="btn btn-light mr-1"
data-bs-toggle="modal"
data-bs-target="#exampleModal"
onClick={()=>this.editClick(dep)}>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" className="bi bi-pencil-square" viewBox="0 0 16 16">
<path d="M15.502 1.94a.5.5 0 0 1 0 .706L14.459 3.69l-2-2L13.502.646a.5.5 0 0 1 .707 0l1.293 1.293zm-1.75 2.456-2-2L4.939 9.21a.5.5 0 0 0-.121.196l-.805 2.414a.25.25 0 0 0 .316.316l2.414-.805a.5.5 0 0 0 .196-.12l6.813-6.814z"/>
<path fillRule="evenodd" d="M1 13.5A1.5 1.5 0 0 0 2.5 15h11a1.5 1.5 0 0 0 1.5-1.5v-6a.5.5 0 0 0-1 0v6a.5.5 0 0 1-.5.5h-11a.5.5 0 0 1-.5-.5v-11a.5.5 0 0 1 .5-.5H9a.5.5 0 0 0 0-1H2.5A1.5 1.5 0 0 0 1 2.5v11z"/>
</svg>
</button>
<button type="button"
className="btn btn-light mr-1"
onClick={()=>this.deleteClick(dep.DepartmentId)}>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" className="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>
</td>
</tr>
)}
</tbody>
</table>
<div className="modal fade" id="exampleModal" tabIndex="-1" aria-hidden="true">
<div className="modal-dialog modal-lg modal-dialog-centered">
<div className="modal-content">
<div className="modal-header">
<h5 className="modal-title">{modalTitle}</h5>
<button type="button" className="btn-close" data-bs-dismiss="modal" aria-label="Close"
></button>
</div>
<div className="modal-body">
<div className="input-group mb-3">
<span className="input-group-text">DepartmentName</span>
<input type="text" className="form-control"
value={DepartmentName}
onChange={this.changeDepartmentName}/>
</div>
{DepartmentId===0?
<button type="button"
className="btn btn-primary float-start"
onClick={()=>this.createClick()}
>Create</button>
:null}
{DepartmentId!==0?
<button type="button"
className="btn btn-primary float-start"
onClick={()=>this.updateClick()}
>Update</button>
:null}
</div>
</div>
</div>
</div>
</div>
)
}
}```
This is my Program.cs
using Microsoft.EntityFrameworkCore;
using WebApp.Data;
var myAllowSpecificOrigins = "_myAllowSpecificOrigins";
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddDbContext<DataContext>(options =>
{
options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection"));
});
//Enable CORS
builder.Services.AddCors(options =>
{
options.AddPolicy(name: myAllowSpecificOrigins,
builder =>
{
builder.WithOrigins("http://localhost:3000")
.AllowAnyMethod()
.AllowAnyHeader();
});
});
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseCors(myAllowSpecificOrigins);
app.UseAuthorization();
app.MapControllers();
app.Run();
What might be the problem here, because I can't figure it out for days.
Does anyone had the same issue?
It looks like I have done something wrong in react js file

fetching data from findAll and pass it to ejs file

I'm trying to fetch data from mysql and pass the data to ejs file. I want to display the passed data as a html datatable. but it seems to not work.
I'm using sequelize and node js and ejs.
Here is how i implemented findAll() method
router.get('/list', function (req,res, next) {
player.findAll()
.then( players => {
console.log(data);
var data = res.json(players);
res.render("list", {data:data})
});
});
And here is where i want the data to be displayed.
<table>
<thead>
<tr>
<th scope="col"></th>
<th scope="col">Name</th>
<th scope="col">Last follow up date</th>
<th scope="col"></th>
<th scope="col"></th>
<th scope="col"></th>
</tr>
</thead>
<tbody id="Table-data">
<%if (typeof data != 'undefined'){ %>
<% data.forEach(function(row){ %>
<tr>
<td> 1 </td>
<td> <%= row.name %> </td>
<td> 15 </td>
<td>
<a href="./chart">
<span class="title">
<svg
width="1em"
height="1em"
viewBox="0 0 16 16"
class="bi bi-bar-chart-line"
fill="currentColor"
xmlns="http://www.w3.org/2000/svg"
>
<path
fill-rule="evenodd"
d="M11 2a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1v12h.5a.5.5 0 0 1 0 1H.5a.5.5 0 0 1 0-1H1v-3a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1v3h1V7a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1v7h1V2zm1 12h2V2h-2v12zm-3 0V7H7v7h2zm-5 0v-3H2v3h2z"
/>
</svg>
view
</span>
</a>
</td>
<td>
<a href="./edit">
<span class="title">
<svg
width="1em"
height="1em"
viewBox="0 0 16 16"
class="bi bi-pencil-square"
fill="currentColor"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M15.502 1.94a.5.5 0 0 1 0 .706L14.459 3.69l-2-2L13.502.646a.5.5 0 0 1 .707 0l1.293 1.293zm-1.75 2.456l-2-2L4.939 9.21a.5.5 0 0 0-.121.196l-.805 2.414a.25.25 0 0 0 .316.316l2.414-.805a.5.5 0 0 0 .196-.12l6.813-6.814z"
/>
<path
fill-rule="evenodd"
d="M1 13.5A1.5 1.5 0 0 0 2.5 15h11a1.5 1.5 0 0 0 1.5-1.5v-6a.5.5 0 0 0-1 0v6a.5.5 0 0 1-.5.5h-11a.5.5 0 0 1-.5-.5v-11a.5.5 0 0 1 .5-.5H9a.5.5 0 0 0 0-1H2.5A1.5 1.5 0 0 0 1 2.5v11z"
/>
</svg>
edit
</span>
</a>
</td>
<td>
<a href="./addEnv">
<span class="title">
<svg
width="1em"
height="1em"
viewBox="0 0 16 16"
class="bi bi-plus-square"
fill="currentColor"
xmlns="http://www.w3.org/2000/svg"
>
<path
fill-rule="evenodd"
d="M14 1H2a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1zM2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2z"
/>
<path
fill-rule="evenodd"
d="M8 4a.5.5 0 0 1 .5.5v3h3a.5.5 0 0 1 0 1h-3v3a.5.5 0 0 1-1 0v-3h-3a.5.5 0 0 1 0-1h3v-3A.5.5 0 0 1 8 4z"
/>
</svg>
add enviroment
</span>
</a>
</td>
</tr>
<% })} else{ %>
<tr>
<td colspan="6">No Record Found</td>
</tr>
<% } %>
</tbody>
</table>
The output always like this
output
Thank you for helping in advance
Try passing players directly to the template
router.get('/list', function (req,res, next) {
player.findAll()
.then(players => {
res.render("list", {data: players})
});

Categories

Resources