brentxscholl's avatar

Adding a "Show more" link above a loop and looping backwards. Livewire

I have a livewire component that allows a user to post comments. Above the new comment form I have a foreach loop showing the comments. The most recent comment is at the end of the loop, so it is at the bottom of the list. My problem is i need to paginate/chunk the comments to only show the 10 most recent. then allow the user to load 10 more at a time above the previous comments.

Lets say I have 100 comments (comment 100 being most recently posted). my layout needs to look like this

(SEE MORE BUTTON) 
[comment 91]
[comment 92]
[comment 93]
[comment 94]
[comment 95]
[comment 96]
[comment 97]
[comment 98]
[comment 99]
[comment 100]
-------------------------------------------------------------
[Textarea for entering new comment (101)]    |   (Submit Button)
-------------------------------------------------------------

When the (SEE MORE BUTTON) is clicked, comments 81-90 should load in ascending order above comment 91.

How would you go about this in livewire? do you use pagination or chunk for something likes this? and how do you handle the loop? im guessing you need to use groupBy? and somehow loop through the comment groups, then loop through the comments?

My Livewire Component: CommentComponent.php

public $comments;

public function mount(){
    $this->comments = Comments::get();
}

....

public function render(){
    return view('livewire.comment-component');
}

comment-component.blade.php

<div>
    <div class="comments">
        <button ... type="button">Show more</button>
        @foreach($comments as $comment)
            <div>....</div>
        @endforeach
    </div>
	<form wire:submit.prevent="createComment" class="comment-form">
		<textarea ...></textarea>
		<button type="submit">Submit</button>
    </form>
</div>
0 likes
1 reply
brentxscholl's avatar
brentxscholl
OP
Best Answer
Level 17

It's easier than I thought. the key is to use the reverse() method on the collection in the foreach loop CommentComponent.php

    use WithPagination;

    public $perPage = 5;

    public function loadMore() {
        $this->perPage = $this->perPage + 5;
    }
    
    public function render() {
        $comments = Comment::latest()->paginate($this->perPage);
        return view('livewire.comment-component', ['comments' => $comments]);
    }

comment-component.blade.php

<div>
    <div class="comments">
        @if($comments->hasMorePages())
        <button wire:click="loadMore()" type="button">Show more</button>
        @endif
        @foreach($comments->reverse() as $comment)
            <div>....</div>
        @endforeach
    </div>
	<form ..... class="comment-form">
		<textarea ...></textarea>
		<button type="submit">Submit</button>
    </form>
</div>
1 like

Please or to participate in this conversation.