Кнопки на нажатии функционируют с тем же идентификатором разных и разных атрибутов

У меня есть веб -страница HTML с образцом кнопок, как показано часть приложения Django, которое заполняет имя и город после вставки значений:

{% 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>

тогда у меня есть JS, который выполняет следующее:

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));
        });

в моем приложении Django у меня есть следующее:

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"})

Прямо сейчас, когда я нажимаю на веб -страницу, только одна кнопка работает и отправляет ответ JSON на веб -страницу, она не работает, если я нажимаю другую кнопку после нажатия первой кнопки. Есть ли способ нажать каждую кнопку при необходимости и отобразить ответ JSON для каждой кнопки?

Способ, которым вы настроили таргетинг на свои HTML-элементы, близок, но неверен. Вы не должны присваивать нескольким элементам одинаковые значения id ( прочитайте другой ответ здесь и смотрите эту статью, чтобы узнать больше о том, почему).

При наличии более чем 1 элемента с одинаковым id будет возвращен только первый элемент, поэтому работает только 1 кнопка.

Чтобы решить эту проблему, замените id на class и измените свой код, чтобы он выглядел следующим образом:

Кнопки

<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));
    });
}

Это позволяет выбрать все элементы с помощью class и вернуть их в виде array элементов. Затем for выполните цикл для каждого элемента в array и подключите прослушиватель событий к каждому из них.

Вернуться на верх