Как добавить слушателя события для нескольких кнопок, которые отображаются с помощью цикла for?

У меня есть страница, на которой отображаются посты пользователей в социальных сетях, и все посты имеют кнопку Edit. При нажатии на кнопку Edit отображается форма с текстовой областью, предварительно заполненной текущим содержимым, и входом для отправки.

Проблема в том, что независимо от того, на какую кнопку редактирования сообщения я нажимаю, всегда изменяется первое сообщение. Я предполагаю, что мне нужно добавить где-то "id", чтобы отслеживать, какой пост редактируется, но я не смог понять, как это сделать. Или есть другое решение?

views.py:

def index(request):
    post_list = AllPost.objects.all().order_by("date").reverse()
    paginator = Paginator(post_list, 10) # Show 10 posts per page.
    page_number = request.GET.get('page')
    page_obj = paginator.get_page(page_number)
    return render(request, "network/index.html", {
        "posts": post_list,
        "page_obj": page_obj
    })
def edit(request, id):
    if request.method == "POST":
        new_content = request.POST["new_content"]
        updated_post = AllPost.objects.filter(id = id)
        updated_post.update(content = new_content)
        return JsonResponse({}, status = 201)
    return JsonResponse({"error": "Bad Request"}, status = 400)

index.html:

{% for post in page_obj %}
    {{ post.full_name|upper }}<br>
    
        <div class="frame">
            <h4><a href="{% url 'profile' post.user.username %}" style="color: black;">{{post.user.username}}</a></h4>
            {% if post.user == user %}
                <button class="btn btn-sm btn-outline-primary" id="edit">Edit</button>
            {% endif %}
            <div id="content">{{post.content}}</div>
            <form action="{% url 'edit' post.id %}" method="post" id="edit_post" style="display: none;">
                {% csrf_token %}
                <div class="form-group"><textarea id="new_content" name="new_content" cols="30"></textarea></div>
                <input class="btn btn-sm btn-primary" id="save" type="submit" value="Save">
            </form>
            
            <div class="grey" id="timestamp">{{post.date}}</div>
            <div class="grey">{{post.likes}}</div>
            <a href="#" style="color: grey;">Comment</a>
        </div>
{% endfor %}

network.js

document.addEventListener("DOMContentLoaded",  () => {
    document.querySelector("#content").innerHTML = localStorage.getItem("content");
    document.querySelectorAll("#edit").forEach(button => {
        button.onclick = () => {
            const content = document.querySelector("#content").innerHTML;
            document.querySelector("#content").style.display = "none";
            document.querySelector("#edit_post").style.display = "block";
            document.querySelector("#new_content").value = content;
        }
    });
    document.querySelector("#edit_post").onsubmit = (event) => {
        let content = document.querySelector("#new_content").value;
        document.querySelector("#content").innerHTML = content;
        document.querySelector("#content").style.display = "block";
        document.querySelector("#edit_post").style.display = "none";
        event.preventDefault();
        localStorage.setItem("content", content);
    };
});

Просто удалите абсолютные id-селекторы, потому что с абсолютным id-селектором вы просто получите всегда первый элемент с этим id. Поэтому замените его на относительный class-селектор. Также я рекомендую вам использовать addEventListener вместо on<event>.

Измените .html на следующее:

{% for post in page_obj %}
    {{ post.full_name|upper }}<br>
    
        <div class="frame">
            <h4><a href="{% url 'profile' post.user.username %}" style="color: black;">{{post.user.username}}</a></h4>
            {% if post.user == user %}
                <button class="btn btn-sm btn-outline-primary edit">Edit</button>
            {% endif %}
            <div class="content">{{post.content}}</div>
            <form action="{% url 'edit' post.id %}" method="post" class="edit_post" style="display: none;">
                {% csrf_token %}
                <div class="form-group"><textarea class="new_content" name="new_content" cols="30"></textarea></div>
                <input class="btn btn-sm btn-primary" id="save" type="submit" value="Save">
            </form>
            
            <div class="grey" id="timestamp">{{post.date}}</div>
            <div class="grey">{{post.likes}}</div>
            <a href="#" style="color: grey;">Comment</a>
        </div>
{% endfor %}

Измените .js на следующее:

document.addEventListener("DOMContentLoaded", () => {
  document.querySelector(".content").innerHTML = localStorage.getItem("content");
  Array.from(document.querySelectorAll(".edit")).forEach(button => {
    button.addEventListener('click', event => {
      const target = event.target
      const frame = target.closest('.frame')
      const content = frame.querySelector('.content')
      const edit_post = frame.querySelector('.edit_post')
      edit_post.style.display = 'block'
      const new_content = frame.querySelector('.new_content')
      new_content.value = content.textContent
      content.style.display = 'none'
    })
    const form = button.closest('.frame').querySelector('.edit_post')
    form.addEventListener('submit', event => {
      const target = event.target
      const frame = target.closest('.frame')
      const content = frame.querySelector('.content')
      content.innerHTML = content
      content.style.display = 'block'
      const edit_post = frame.querySelector('.edit_post').style.display = 'none'
      localStorage.setItem('content', content)
      event.preventDefault()
    })
  });
});
Вернуться на верх