1

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 }}&#x1F44D;</h6> {% if post.user == request.user %} <button class="edit_button" value="{{ post.id }}">Edit</button> {% endif %} <textarea class="textarea" id="edit_area"></textarea> <button class="edit_save" 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?

1 Answer 1

3

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}`) 
Sign up to request clarification or add additional context in comments.

6 Comments

this sort of works. The user gets the choice of which button to press, and each button is within a different div (and all the other elements I'm trying to get access to are different), but no matter which button the user presses, the display and none work for the bottommost div, not the one that goes with the button the user pressed. Do you know how to fix this problem?
You'll also need to update id="likes" to id="likes-{{post.id}}". Then update the JS side to query based on the id too e.g document.querySelector(#likes-${id}). Same for date_and_time
I did that, and I am still receiving the problem that I explained above. I also added a console.log that will log the id when the button is pressed, and the number in the console is the same no matter which button is clicked (for a particular user). I think whatever is causing that is also causing this problem. Do you know what the issue could be?
Inspect the values of the edit buttons if they indeed have the right post ids.
I was able to fix the problem by passing in the id to the event listener, but if I use edit_button = document.querySelector(`#${id}`); to get access to the edit button to hide it, I receive this error: Uncaught DOMException: Failed to execute 'querySelector' on 'Document': '#3' is not a valid selector. Do you know how to fix this?
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.