user6073700 user6073700 - 2 months ago 12
HTML Question

Quote a users comment in a thread

I'm trying to build a reply function on an comment in a forum thread so when the user clicks reply it auto populates the reply box with the replied comment so they can add there reply underneath.

I have written a function in javascript to trigger on click to fill out the field.

<script>
function reply() {
document.getElementById("reply").innerHTML = "{{ $comment->body }}";
}
</script>


This works but it only works first time and it fills out the reply form with the last comment made, not the one I clicked on, I am having trouble how to determine which comment it is as it is in a for each loop.

@foreach ($post->comments as $comment)
<div id="main">
<!-- Comments -->
<div class="post-box">
<article class="post">
<header>
<div class="title">
<p>Posted {{ $comment->created_at->diffForHumans() }}</p>
</div>
<div class="meta">
<a href="../profile/{{ $comment->user->id }}-{{$comment->user->name}}" class="author"><span class="name">{{ $comment->user->name }}</span><img src="{{ url('images/avatar.jpg') }}" alt="User Avatar" /></a>
</div>
</header>
<p id="comment">{{ $comment->body }}</p>
<footer>
<ul class="stats">
<li><a href="#" class="icon fa-heart">28</a></li>
</ul>
<div class="reply-button">
<a href="#" onclick="reply()" class="button icon fa fa-reply">Reply</a>
</div>
</footer>
</article>
</div>
</div>
@endforeach


Ideally I would also like the page to scroll to the buttom after the 'reply' is clicked and the cursor focus on the field (if someone could help with that, that would be great) but cross every bridge as I come to it.

Thanks a lot :)

Answer

As Goose said, you really need to try out something yourself before posting a question on Stack Overflow. Nonetheless, since I see that you don't understand why your code is producing these results, I will be providing some help.


The reason your reply() javascript function always fills the reply text-area to be equal to the last comment in the page is simple. In your blade file you are looping through all the comments in a foreach loop. You keep each comment in the post's comments in your $comment variable. When your loop is finished, the $comment variable is equal to the last comment in your post. In a nutshell, the last value set to the $comment variable is the last comment in the post.

Now, at the bottom of your blade file you have your scripts. This is after your foreach loop. Thus, when you instruct blade to echo the body of the $comment variable with {{ $comment->body }} you are in fact telling it to echo out the body of the last comment, since that is the value of your $comment variable. Thus, whenever you run the Javascript reply() function, all you are doing is changing the innerHTML of reply to be equal to the body of the last comment in the post.

This is why you are getting these results.


To fix this (using plain Javascript) you will need to do something like this:

@foreach ($post->comments as $comment)
    ...
    <p class="comment-body" id="comment-{{ $comment->id }}">{{ $comment->body }}</p>
    ....
    <div class="reply-button">
        <a href="#" onclick="reply({{ $comment->id }})" class="button icon fa fa-reply">Reply</a>
    </div>
    ...
@endforeach

<script>
    function reply(id) {
        document.getElementById("reply").value= document.getElementById("comment-"+id).innerHTML;
    }
</script>

Edit: make sure you use value like this => document.getElementById("reply").value= document.getElementById("comment-"+id).innerHTML; and not like this => document.getElementById("reply").innerHTML= document.getElementById("comment-"+id).innerHTML;


This, of course, is not the best solution. The best way would be to use vue.js or some other MVVM instead of this, well, hackery...