Reputation: 568
i have multiple user comments wrapped in <article>
with the same content structure and the same class. the main part that i need to playaround with js is to get text and attribute value from each user comment when the reply button clicked then add those thing to form input value.
this is the html structure
<div class="comments">
<article id="comment-1" class="comment parent">
<span class='comment-author'>John Doe</span>
<p class="body">Lorem ipsum af farm-to-table brunch XOXO portland small batch edison bulb yr hella 3 wolf moon</p>
<a id="de255ea0-ddde-11e9-84d7-5d6e5fd4ffd6" class="reply-btn" title="de255ea0-ddde-11e9-84d7-5d6e5fd4ffd6">reply</a>
</article>
<!-- this one is reply for the first comment -->
<article id="comment-1r1" class="comment reply">
<span class='comment-author'>Jane</span>
<p class="body">Lorem ipsum af farm-to-table brunch XOXO portland small batch edison bulb yr hella 3 wolf moon</p>
<a id="de255ea0-ddde-11e9-84d7-5d6e5fdjkl4m5" class="reply-btn" title="de255ea0-ddde-11e9-84d7-5d6e5fd4ffd6">reply</a>
</article>
<article id="comment-2" class="comment reply">
<span class='comment-author'>Foo</span>
<p class="body">Lorem ipsum af farm-to-table brunch XOXO portland small batch edison bulb yr hella 3 wolf moon</p>
<a id="de255ea0-ddde-11e9-84d7-5d6e5fdj409d4" class="reply-btn" title="de255ea0-ddde-11e9-84d7-5d6e5fd4ffd6">reply</a>
</article>
</div>
<!-- the form -->
<form>
<input class="replyThread" type="hidden" name="fields[replyThread]" value="">
<input class="replyID" type="hidden" name="fields[replyID]" value="">
<input class="replyName" type="hidden" name="fields[replyName]" value="">
</form
as you can see each user comment have a unique user name also unique attribute value on the reply-btn
but they generaly they have same class.
this is my workaround
const replyButton = document.querySelector('.reply-btn');
const replyThread = document.querySelector('.replyThread');
const replyID = document.querySelector('.replyID');
const replyName = document.querySelector('.replyName');
const threadValue = document.querySelector('.reply-btn').getAttribute("title");
const idValue = document.querySelector('.reply-btn').getAttribute("id");
const nameValue = document.querySelector('.comment-author');
replyButton.addEventListener('click', (evt) => {
replyThread.innerHTML = threadValue;
replyID.innerHTML = idValue;
replyName.setAttribute('value', nameValue.innerHTML );
})
the only problem is the button seems to work only for the first comment, when i click the other nothing happen. i try using querySelectorAll but unfortunately it can work with addEventListener
my question is how to make the reply button working and get the text and attribute value from the right place (each user comment)?
Upvotes: 0
Views: 104
Reputation: 370759
I'd use event delegation on the .comments
container: watch for clicks, and if the clicked target matches .reply-btn
, get its .title
and ID, and get the thread title by accessing the .comment-author
in its container, and then you can put those into the form:
const [replyThread, replyId, replyName] = document.querySelectorAll('form > *');
document.querySelector('.comments').addEventListener('click', ({ target }) => {
if (!target.matches('.reply-btn')) {
return;
}
replyId.value = target.id;
replyThread.value = target.title;
replyName.value = target.parentElement.querySelector('.comment-author').textContent;
});
<div class="comments">
<article id="comment-1" class="comment parent">
<span class='comment-author'>John Doe</span>
<p class="body">Lorem ipsum af farm-to-table brunch XOXO portland small batch edison bulb yr hella 3 wolf moon</p>
<a id="de255ea0-ddde-11e9-84d7-5d6e5fd4ffd6" class="reply-btn" title="de255ea0-ddde-11e9-84d7-5d6e5fd4ffd6">reply</a>
</article>
<!-- this one is reply for the first comment -->
<article id="comment-1r1" class="comment reply">
<span class='comment-author'>Jane</span>
<p class="body">Lorem ipsum af farm-to-table brunch XOXO portland small batch edison bulb yr hella 3 wolf moon</p>
<a id="de255ea0-ddde-11e9-84d7-5d6e5fdjkl4m5" class="reply-btn" title="de255ea0-ddde-11e9-84d7-5d6e5fd4ffd6">reply</a>
</article>
<article id="comment-2" class="comment reply">
<span class='comment-author'>Foo</span>
<p class="body">Lorem ipsum af farm-to-table brunch XOXO portland small batch edison bulb yr hella 3 wolf moon</p>
<a id="de255ea0-ddde-11e9-84d7-5d6e5fdj409d4" class="reply-btn" title="de255ea0-ddde-11e9-84d7-5d6e5fd4ffd6">reply</a>
</article>
</div>
<!-- the form -->
<form>
Form
<input class="replyThread" name="fields[replyThread]" value="">
<input class="replyID" name="fields[replyID]" value="">
<input class="replyName" name="fields[replyName]" value="">
</form>
While querySelectorAll
is possible too, it'd require adding a separate listener to each button, which is overkill. (event delegation also allows for functionality for dynamically added elements too).
Upvotes: 2