Функция onclick выполняется только один раз
Я использую кнопку редактирования для редактирования сообщений, но когда я нажимаю на кнопку, функция onclick выполняется, и она прекрасно работает, как будто редактирует сообщение и обновляет содержимое сообщения (не из бэкенда). Но проблема в том, что когда я снова нажимаю на кнопку редактирования, функция onclick не запускается. Мой HTML код :-
<div class="post">
<b><a href="{% url 'profile' post.author.id %}">{{post.author}}</a></b>
<input type="hidden" name="postid" value={{post.id}}>
<!-- <br><br> -->
<p>{{post.content}}</p>
{% csrf_token %}
<textarea name="edit_content" id="edit_content" cols="50" rows="5"></textarea>
{% if user.is_authenticated %}
{% if post.author == user %}
<button class="edit" onclick="edit(this)">Edit</button>
{% endif %}
{% endif %}
<p><small class="text-muted">{{post.created_on}}</small></p>
Здесь отображение текстовой области установлено на 'none'.
Мой код javascript :-
function edit(ele){
var parent = ele.parentNode;
console.log(ele.parentNode);
var post = parent.querySelector('p');
var textarea = parent.querySelector('textarea');
var id = parent.querySelector('input');
post.style.display = 'none';
textarea.style.display = 'block';
ele.innerHTML = "Save";
ele.id = "save";
ele.disabled = true;
const csrftoken = document.querySelector('[name=csrfmiddlewaretoken]').value;
textarea.onkeyup = () => {
if( textarea.value.length > 0){
ele.disabled = false;
}
else{
ele.disabled = true;
}
}
var save = document.getElementById('save');
save.onclick = () => {
fetch("http://127.0.0.1:8000/edit", {
method : "PUT",
headers: {'X-CSRFToken': csrftoken},
body : JSON.stringify({
"postdata" : textarea.value,
"id" : id.value
})
}).then(() => {
post.innerHTML = textarea.value;
// textarea.value = '';
post.style.display = "block";
textarea.style.display = "none";
ele.innerHTML = "Edit";
save.removeAttribute('id');
});
}
}
Я предлагаю разделить две кнопки, редактировать и сохранить, и скрывать/показывать одну из них в зависимости от текущего состояния.
В этом демо я немного переписал ваш код так, чтобы начальное состояние было только для чтения, показывая <p>
с текстовым содержимым. Когда вы нажмете кнопку редактирования, абзац будет скрыт, а текстовая область с его содержимым появится, давая вам возможность редактировать текст. В то же время кнопки редактирования/сохранения поменяют свою видимость так, что в этот момент при нажатии кнопки сохранения будет выполнено обратное действие сразу после успешного вызова web api.
Таким образом, у вас есть два разделенных элемента, которые вы можете стилизовать независимо друг от друга, и две разные функции для соответствующих событий щелчка (сохранение и редактирование).
В качестве дополнительного бонуса этот код не имеет дело с идентификаторами, так что он может масштабироваться с несколькими постами на одной странице. Скрытое поле csrf будет единственным исключением.
function save(target){
const parent = target.parentNode;
const post = parent.querySelector('p');
const textarea = parent.querySelector('textarea');
const id = parent.querySelector('input');
const edit = parent.querySelector('button.edit');
const url = "http://127.0.0.1:8000/edit";
const csrftoken = "";
fetch(url, {
method: "PUT",
headers: {
'X-CSRFToken': csrftoken
},
body: JSON.stringify({
"postdata": textarea.value,
"id": id.value
})
})
//I used finally instead of then to deal with the fact that the api url will fail
.finally(() => {
post.innerText = textarea.value;
post.style.display = "block";
textarea.style.display = "none";
target.style.display = 'none';
edit.style.display = 'block';
});
}
function edit(target) {
const parent = target.parentNode;
const post = parent.querySelector('p');
const textarea = parent.querySelector('textarea');
const id = parent.querySelector('input');
const save = parent.querySelector('button.save');
post.style.display = 'none';
textarea.style.display = 'block';
textarea.value = post.innerText;
target.style.display = 'none';
save.style.display = 'block';
}
button.save{
display: none;
cursor: pointer;
}
button.edit{
display: block;
cursor: pointer;
}
textarea.edit_content{
display: none;
}
<div class="post">
<b><a href="http://bogus">{{post.author}}</a></b>
<input type="hidden" name="postid" value={{post.id}}>
<p>{{post.content}}</p>
<textarea name="edit_content" class="edit_content" cols="50" rows="5"></textarea>
<button class="edit" onclick="edit(this);">Edit</button>
<button class="save" onclick="save(this);">Save</button>
<p><small class="text-muted">{{post.created_on}}</small></p>
<input type="hidden" name="csrfmiddlewaretoken" value="bogus">
</div>