There are a couple of ways to go about this.
You get get all the songs and pass them through the context in your Django view. You then add them to a data-attribute on the HTML and then access them via JavaScript. This will allow you to do all the logic in JavaScript.
Another option and more ideal (especially are there could be thousands of songs) would be to use the Django Rest Framework and setup a view with pagination where you can get a specific number of songs at a time. You would access this view through an AJAX call in JavaScript. The Django Rest Framework view would return a JSON response of the next X amount of songs.
https://www.django-rest-framework.org/api-guide/pagination/
I have a HTML table which is populated using Django variables:
<h3>Recommended Playlist</h3>
<table class="table table-dark" id="playlist_table">
<thead>
<tr>
<th scope="col">
<h4>Artist</h4></th>
<th scope="col">
<h4>Track</h4></th>
<th scope="col" style="display:none;">
<h4>Track ID</h4></th>
<th scope="col">
<h4>Album</h4></th>
<th scope="col" colspan="2">
<h4>Accept/Reject</h4></th>
</tr>
</thead>
<tbody>
{% for song in playlist %}
<tr>
<td>{{song.artist_name}}</td>
<td>{{song.track_name}}</td>
<td style="display:none;" class="song_id">{{song.track_id}}</td>
<td>{{song.album_name}}</td>
<td class="approve"><i class="fas fa-check-circle fa-2x" onclick="approveRow(this)"></i></td>
<td class="reject"><i class="fas fa-times-circle fa-2x" onclick="deleteRow(this)"></i></td>
</tr>
{% endfor %}
</tbody>
</table>
Users can ‘Accept’ or ‘Reject’ rows using the tick/X icons:
Table Screenshot
The following Javascript functions are called if users ‘Accept’/’Reject’ a song:
//if a user accepts a row
function approveRow(r) {
var i = r.parentNode.parentNode.rowIndex;
var row = document.getElementById("playlist_table").rows[i];
row.deleteCell(5);
row.deleteCell(4);
var blank1 = row.insertCell(4); //green tick once song approved
blank1.innerHTML = '<center><i class="fas fa-check-circle fa-2x" style="color:#00ee21;"></i></center>';
//order of above is important as once a cell is deleted, the other's index is index-1
approve_counter++;
console.log(approve_counter);
song_selection.push('Accept');
}
//if a user rejects a row
function deleteRow(r) {
var i = r.parentNode.parentNode.rowIndex;
document.getElementById("playlist_table").deleteRow(i);//delete existing row
var table = document.getElementById("playlist_table");
var row = table.insertRow(i); //insert new blank row
var artist = row.insertCell(0);
var track = row.insertCell(1);
var album = row.insertCell(2);
var approve = row.insertCell(3);
var reject = row.insertCell(4);
artist.innerHTML = "New Artist";
track.innerHTML = "New Track";
album.innerHTML = "New Album";
approve.className = 'approve';
reject.className = 'reject';
approve.innerHTML='<i class="fas fa-check-circle fa-2x" onclick="approveRow(this)"></i>';
reject.innerHTML='<i class="fas fa-times-circle fa-2x" onclick="deleteRow(this)"></i>';
reject_counter++;
console.log(reject_counter);
song_selection.push('Reject');
}
If a User ‘Rejects’ a song at the moment, the row is just populated with placeholder variables (see below).
rejecting a song
I’m wondering if there is a way to dynamically populate the rows? The Django queryset ({{playlist}}) currently has 10 items and populates the table with the 10 songs. I want to be able to have for example 50 items in the queryset and populate the table with 10 at a time. If the user ‘Rejects’ the song, the next item from the queryset (item 11) would become the new row in the table and so on.
Any help would be very much appreciated, thanks! 🙂