Buttons On Click Functioning with same ID different and different attributes
I have an HTML webpage with a sample of buttons as shown part of a Django Application that fills in the name and town after inserting the values:
{% for person in page_obj %}
<button id="NotifyBtn" name="person.FName" town="person.LName">Press Me</button>
{% endfor %}
<button id="NotifyBtn" name="Billy" town="Bob">Press Me</button>
<button id="NotifyBtn" name="Timmy" town="Tawin">Press Me</button>
<button id="NotifyBtn" name="Milly" town="House">Press Me</button>
Then I have a JS that does the following:
document.getElementById("NotifyBtn").addEventListener("click", function(){
var name = this.getAttribute("name");
var town = this.getAttribute("town");
fetch("{% url 'alert_via_JSON_Response' %}", {
method: "POST",
headers: {
"X-CSRFToken": "{{ csrf_token }}",
"Content-Type": "application/json"
},
body: JSON.stringify({ message: "Hi there: " + `${name} born in ${town}`
})
}).then(response => response.json())
.then(data => alert(data.status));
});
In my Django application I have the following:
def alert_via_JSON_Response(request):
if request.method == 'POST':
data = json.loads(request.body)
message = data.get('message', "Error in sending email")
return JsonResponse({"status": f"{message}"})
return JsonResponse({"status": f"No Message"})
Right now, when I click on the webpage, only one button works and sends a JSON response to the webpage, it doesn't work if I press another button after pressing the first button. Is there a way to press each button when needed and display the JSON response for each button?
The way you have targeted your HTML elements is close, but incorrect. You should not be giving multiple elements the same id
(read another answer here and see this article to find out more about why).
Having more than 1 element with same id
will only return the first element, which is why only 1 button works.
To solve this issue, replace the id
with class
and modify your code to look like this:
Buttons
<button class="NotifyBtn" name="Billy" town="Bob">Press Me</button>
<button class="NotifyBtn" name="Timmy" town="Tawin">Press Me</button>
<button class="NotifyBtn" name="Milly" town="House">Press Me</button>
JavaScript:
let buttons = document.getElementsByClassName("NotifyBtn")
for(let i = 0; i < buttons.length; i++){
let button = buttons[i]
button.addEventListener("click", function(){
var name = button.getAttribute("name");
var town = button.getAttribute("town");
fetch("{% url 'alert_via_JSON_Response' %}", {
method: "POST",
headers: {
"X-CSRFToken": "{{ csrf_token }}",
"Content-Type": "application/json"
},
body: JSON.stringify({ message: "Hi there: " + `${name} born in ${town}`
})
}).then(response => response.json())
.then(data => alert(data.status));
});
}
What this does is select all elements with class
and return them as an array
of elements. Then for
loop each item in the array
and attach the event listener to each of them.