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 на сервер. При этом он ничего не ждет и перезагружает страницу.
Я не эксперт и прохожу тот же курс, что и вы, поэтому если есть ошибка или что-то неясно, я прошу прощения и не стесняйтесь спрашивать.