I don’t know about django in specific, but usually you would handle this in the frontend, by simply setting the button to disabled immediately after it has been clicked.
This way you have not only covered the technical aspect, but even the UX and accessibility aspect. By setting the button to disabled, the user gets immediate feedback to his click and also knows that he cannot click it again. This counts also for handicapped users (e.g. using screen readers, etc.)
I would not recommend setting pointer-events: none or doing onclick = null, because it does not cover the aspects described above.
joinButton.disabled = true;
Problem :
I’m working in a Django project which has events that can be joined by users (adding the user_id and event_id to a model attend), In my event I have a join button form that when clicked adds the attend, after clicking the button disappears and appears a new button called leave event and the opposite. All this works, when the user joins or leaves the event page reloads.
The problem I’m having is that I’m able to click the button 2 times in a row before the button disappears getting an error because it is trying to add an attend object that already exists or delete an object that does not exist.
So my question is if there is a way to avoid the user clicking two times the button so it is not sending a POST request 2 times, or at least if he clicks it again before it disappears not sending a request, or there could be a way to apply the button onclick function before sending the POST request?
EDIT: I solved the Django part so I’m not getting an error if the user clicks 2 times the join or leave button, but now the user can still keep clicking the button and the page will keep reloading till he/she stops clicking that same button which I think it is not good.
Here the javascript to show the join or leave button which is executed when the page is loaded or either button is clicked (I first looked in the list of attendants if the logged user is attending, because I didn’t find a way to query the attend model in a Django template):
script type="text/javascript">
window.onload = function() {
showJoinLeave();
};
function showJoinLeave() {
var attendants = document.getElementsByClassName("attendant-username");
var username = "{{ user.username }}";
var joinButton = document.getElementById("event-info-join");
var leaveButton = document.getElementById("event-info-leave");
var is_attending = false;
var attendant;
for (attendant of attendants) {
var attendant_name = attendant.innerHTML;
if (attendant_name == username) {
is_attending = true;
}
}
if (is_attending===true){
joinButton.style.display = "none";
leaveButton.style.display = "flex";
}
else {
joinButton.style.display = "flex";
leaveButton.style.display = "none";
}
}
this.onclick = null is not working but you are right, someone could put the URL and the same would happen, thank you. I’ll find another way to handle it
Comment posted by RiesenChicken
now, it is disabling it but not sending the POST request I don’t know why.
Comment posted by RiesenChicken
As you said, would the best option be to leave the buttons as I have them but handle the view so a user can’t leave an event if he/she already left it right? because I will have to do it eitherway
Comment posted by JavaScript
Javascript should be used to enhance the user experience and prevalidate in this case. Yet it can not replace an actual server-sided validation/process. Usually you validate it first on the server-side and once that is done and tested you prevalidate on the client-side. Every validation made with Javascript can be avoided somehow. You could disable the button, show a message, display a waiting symbol.. there are many ways to deal with the cosmetic part and prevent a double request by GUI.
Comment posted by JavaScript
showJoinLeave()
Comment posted by RiesenChicken
yep, it gets triggered on load but either way, I’m being able to click it two times, it’s like I’m clicking it before the function executes.
Comment posted by RiesenChicken
I tried as u said (joinButton.disabled = true; inside the if, leaveButton.disabled = true; in the else) and I keep getting the same error.