Javascript загружает страницу слишком быстро - Django Edit Form

Я пытаюсь отредактировать существующее сообщение (форму) на моем сайте, но когда я нажимаю "редактировать", я получаю следующее в консоли: Fetch finished loading: POST "http://127.0.0.1:8000/edit_post/18". Статус 201, поэтому я думаю, что страница пропускает большую часть javascript и напрямую отправляет его/сохраняет на сервер. Также, когда я нажимаю "редактировать", должно появиться текстовое поле с текстом моего сообщения. Но оно так и не открывается, просто в консоли появляется надпись fetch finished loading appropriate.

Как убедиться, что сначала выполняется весь Javascript? Я пробовал использовать preventDefault и постоянно сталкиваюсь с ошибками типа Uncaught. Я довольно новичок в Javascript, поэтому я все еще учусь этому.

Например, в функции event_handeler я попробовал следующее:

document.querySelectorAll("#textarea").addEventListener("submit", function(event) {
document.querySelector(`#post-edit-${id}`).innerHTML += "Sorry!";
event.preventDefault();
})

Но я получил не пойманные ошибки типа.

function edit_handeler(element) {
  id = element.getAttribute("data-id");

  document.querySelector(`#post-edit-${id}`).style.display = "block";
  document.querySelector(`#post-content-${id}`).style.display = "none";

edit_btn = document.querySelector(`#edit-btn-${id}`);
edit_btn.textContent = "Save";
edit_btn.setAttribute("class", "text-success edit");
if (edit_btn.textContent == "Save") {
edit_post(id, document.querySelector(`#post-edit-${id}`).value); //here

edit_btn.textContent = "Edit";
edit_btn.setAttribute("class", "text-primary edit");
}}


function edit_post(id, post) {
 const body = document.querySelector(`#post-content-${id}`).value; 

fetch(`/edit_post/${id}`, {

method: "POST",
body: JSON.stringify({
body:body
})


 }).then((res) => {
 document.querySelector(`#post-content-${id}`).textContent = post;
 document.querySelector(`#post-content-${id}`).style.display = "block";
 document.querySelector(`#post-edit-${id}`).style.display = "none";
 document.querySelector(`#post-edit-${id}`).value = post.trim(); 
  });
 }

views.py

@csrf_exempt
def edit_post(request, pk): #used to take in pk here also

    post = Post.objects.get(id=pk)  # was id=pk

    form = PostForm(instance=post)
    if request.method == "POST":
        form = PostForm(request.POST, instance=post)
        if form.is_valid():
            form.save()
          
            return JsonResponse({}, status=201) # this works to edit and save to db
    else:
        if request.method == "GET":           
            form = PostForm(instance=post)
            form_for_post = {'form': PostForm()}

            return render(request, "network/make_post.html", {
                "post": post,
                "form_for_post": form,
    })

relevant urls.py

path('edit_post/<str:pk>', views.edit_post, name="edit_post"),

релевантный html - первая часть - это текстовая область, которая должна открываться, когда вы нажимаете "редактировать". Следующая часть - кнопка редактирования.

span id="post-content-{{i.id}}" class="post">{{i.text}}</span> <br> 
                <textarea data-id="{{i.id}}" id="post-edit-{{i.id}}" 
style="display:none;" class="form-control textarea" row="3">{{i.text}}</textarea>

<button class="btn-btn primary" data-id="{{i.id}}" id="edit-btn-{{i.id}}" 
onclick="edit_handeler(this)" >Edit</button>

во-первых, формат кода беспорядочен и очень трудно читается, попробуйте отформатировать его лучше, используя Prettier или что-либо еще, прежде чем загружать в следующий раз.

Насколько мне известно, слушатель onsubmit может быть привязан только к элементу <form>, и это логично, ведь вы отправляете не textarea, а форму, в которую она включена. Поэтому вы должны нацеливаться на элементы <form> с помощью addEventListener.

Также при вызове слушателя браузер вставляет в него en event object в качестве первого аргумента.

Слушатели событий принимают только один аргумент - объект события, который автоматически передается слушателю, а возвращаемое значение игнорируется. Документация MDN

и если вы хотите получить доступ к атрибутам элемента, вы можете сделать это, обратившись к event.target

Один из возможных способов сделать то, что вам нужно: JS:

function onsubmitHandler(event, url, ...others) {
  // prevents form from submitting and reloading the page
  event.preventDefault();
  // accessing element which caused firing this eventListener
  // in our case that is the form element
  let form = event.target;
  // now we need the textarea and its value
  let textarea = form.querySelector("textarea");
  let content = textarea.value;

  // other steps
  fetch(url, ...).then(res => ..)
}

HTML:

<form onsubmit='onsubmitHandler(event, url, ...others)'> 
  <textarea>..</textarea>
  <button type="submit">..</button>
</form>

Таким образом, кнопка вызывает событие onsubmit, которое перехватывается элементом формы, в котором находится кнопка.

и, конечно, вы можете передавать значения из шаблона Django как:

<form onsubmit='onsubmitHandler(event, {{ url }})'>

Ключевые моменты:

  • onsubmit или addEventListener("submit") срабатывает на самой форме, поэтому она является целью события и перезагружает страницу - это ее родное поведение, которое вы можете остановить программно event.preventDefault() внутри функции обратного вызова слушателя (onsubmitHandler в нашем случае)
  • .

Обратите внимание, что событие submit срабатывает на самом элементе, а не на каком-либо элементе или внутри него.

  • Если вы используете <form action="https://example.com" method="POST"> и не прикрепляете к нему слушателя событий, он будет собирать именованные входы внутри формы ` и добавлять их к url действия как параметры запроса => "https://example.com?car=car" и отправлять POST запрос с этим url на сервер. При этом он ничего не ждет и перезагружает страницу.

Я не эксперт и прохожу тот же курс, что и вы, поэтому если есть ошибка или что-то неясно, я прошу прощения и не стесняйтесь спрашивать.

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