I am trying to create a button that hides and displays only the specific HTML
elements that are in the same div with it through JavaScript
. All the divs are within a Django
template for loop and display different information. Right now, I am using a querySelector
to select the id, but that is not correct because it selects the first element it finds with that id.
html
:
<div>
{% for post in page_obj.object_list %}
<div class = "individual_posts">
<a href="{% url 'username' post.user %}"><h5 id="p_user" class = "post_user">{{ post.user }}</h5></a>
<h6 id = "post_itself">{{ post.post }}</h6>
<h6 id="date_and_time" class = "post_elements">{{ post.date_and_time }}</h6>
<h6 id="likes" class = "post_elements">{{ post.likes }}👍</h6>
{% if post.user == request.user %}
<button value="{{ post.id }}">Edit</button>
{% endif %}
<textarea id="edit_area"></textarea>
<button id="save">Save</button>
</div>
{% endfor %}
</div>
javascript
:
document.addEventListener('DOMContentLoaded', function(){
//hide the textarea
const editingTextareas = document.querySelectorAll(".textarea");
for (const textarea of editingTextareas){
textarea.style.display = 'none';
}
//hide the save buttons for the textarea
const saveButtons = document.querySelectorAll(".edit_save");
for (const s_button of saveButtons){
s_button.style.display = 'none';
}
//adds the click to the edit buttons
const editButtons = document.querySelectorAll('.edit_button');
for (const button of editButtons) {
id = button.value;
button.addEventListener('click', () => edit_email(id));
}
});
function edit_email(id){
document.querySelector('#post_itself').style.display = 'none';
document.querySelector('#date_and_time').style.display = 'none';
document.querySelector('#likes').style.display = 'none';
const edit_area = document.querySelector('#edit_area');
edit_area.style.display = 'block';
const save = document.querySelector('#save');
save.style.display = 'block';
//get post
fetch(`/edit/${id}`)
.then(response => response.json())
.then(post => {
edit_area.innerHTML = `${post.post}`;
})
//save the post
fetch(`/edit/${id}`,{
method: 'POST',
post: JSON.stringify({
post: edit_area.value
})
})
}
Will I have to run each HTML
element through a for loop like I do when the DOM
is first loaded to hide the buttons?
CodePudding user response:
You're sharing the same id for multiple elements. According to MDN,
The Document method querySelector() returns the first Element within the document that matches the specified selector, or group of selectors
To fix this for your case, append the post ID to the element ID so each ID is unique and can be queried individually. E.g <h6 id = "post_itself-{{post.id}}">{{ post.post }}</h6>
, then the JS side should be:
document.querySelector(`#post_itself-${id}`).style.display = 'none';
Do that for all repeated IDs. I'll advise you to store the element in a variable so you don't have to repeatedly query the same element
const postItselfEl = document.querySelector(`#post_itself-${id}`)