Reputation: 55
I have a page that displays social media posts from users and all posts have an Edit button. When the Edit button is clicked on, a form with a textarea pre-filled with the current content and a submit input is displayed.
The problem is that regardless of which post's Edit button I click, always the first post is changing. I guess I should add an "id" somewhere to track which post is being edited but I couldn't figure out how to do that. Or is there another solution?
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);
};
});
Upvotes: 0
Views: 356
Reputation: 1106
Just remove the absolute id-selectors because with an absolute id-selector you just get always the first element with that id. So change it for a relative class-selector instead. Also, I recommend you to use addEventListener
instead of on<event>
.
Change the .html
to the following:
{% 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 %}
Change the .js
to the following:
document.addEventListener("DOMContentLoaded", () => {
const content = localStorage.getItem("content")
if (content) document.querySelector(".content").textContent = JSON.parse(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')
const new_content = frame.querySelector('.new_content')
content.textContent = new_content.value
localStorage.setItem('content', JSON.stringify(new_content.value))
content.style.display = 'block'
const edit_post = frame.querySelector('.edit_post').style.display = 'none'
event.preventDefault()
})
});
});
Upvotes: 1