I'm using Laravel 5.5.* and jQuery (jquery-3.3.1.min.js).
I commercially develop mostly (like 95% of the time) in PHP, so using jQuery is really different for me, so I need help.
I am developing a blog's landing page and I must show just 3 posts in it. In it's bottom, I have a button <a>
that is supposed to load 3 more posts and show it to the user. Everytime the user hits this button, 3 more posts must load in the page.
I have the following codes so far.
Posts controller
public function index() {
// this loads the landing page with 3 initial posts
// Working like a charm
$posts = Posts::with('categories', 'user', 'media')
->where('status', 1)
->orderBy('published', 'desc')
->limit(3)
->get();
$rank = self::blogPanel();
return view('portal.pages.blog',
compact(
'rank',
'posts'
)
);
}
I call this action from the route
Route::get('/', 'User\PostsController@index')->name('landingPage');
For the logic in which I load more posts, I have the following:
Posts Controller
public function loadMore() {
$posts = Post::with('categories', 'user', 'media')
->where('status', 1)
->orderBy('publicacao', 'desc')
// ->limit(3) I took this out because I was trying to set the limit in front-end
->get();
return json_decode($posts);
}
Which returns the following:
array:48 [▼
0 => {#257 ▼
+"id": 48
+"title": "Lorem ipsum"
+"summary": "Perferendis labore veritatis voluptas et vero libero fuga qui sapiente maiores animi laborum similique sunt magni voluptate et."
+"content": """
Really long text here, with line-breaks and all
"""
+"seo_id": null
+"url": "Sunt rerum nisi non dolores."
+"link_title": "dolor"
+"published": "2018-03-01 10:35:12"
+"scheduled": "2018-03-01 10:25:12"
+"user_id": 1
+"media_id": null
+"status": 1
+"created_at": "2018-03-01 10:25:12"
+"updated_at": "2018-03-01 10:25:12"
+"category_id": 3
+"slug": "cum-aut-officia-consequatur-dolor"
+"categories": []
+"user": {#313 ▼
+"id": 1
+"name": "Jonessy"
+"email": "jonessy@email.com"
+"status": 1
+"grupo_id": 1
+"created_at": null
+"updated_at": null
}
+"media": null
}
1 => {#341 ▶}
2 => {#254 ▶}
]
Please, note I'm using json_decode()
because it looks easier to work with in front-end.
This is my blade file, where I should print my results
blogPost.blade.php
@foreach($posts as $post)
@php
$date = date_create($post->published);
@endphp
<div class="blog-post" id="blog-post">
<div class="blog-post__title" >
<h3 id="artTitle">
{{ $post->title }}
</h3>
@foreach($post->categories as $cat)
<span class="blog-post__category"> {{ $cat->name }} </span>
@endforeach
<span class="blog-post__date" id="artDate">
{{ date_format($date,"d/m/y - H") }}H
</span>
</div>
<div class="blog-post__image" id="artImage">
@if(isset($post->media_id))
<img src="{{ asset('img/post-img/' . $post->media->file) }}">
@else
<img src="{{asset('img/post-img/default-img-post.jpg')}}">
@endif
</div>
<div class="blog-post__resume">
<p id="artSumma">
{{ $post->summary }}
</p>
</div>
<div class="blog-post__link">
<a href="{{ route('blogPost', $post->slug) }}">
Read More
</a>
</div>
<div class="blog-post__social">
// Some social media links for sharing
</div>
</div>
@endforeach
I am calling the loadMore()
method from PostsController
using a GET
route:
Route::get('/', 'User\PostsController@loadMore')->name('loadMore');
For jQuery, here is the code I got so far:
<script type="text/javascript">
// after importing jquery file...
$(document).on('click', '#loadingPosts', function(e) {
e.preventDefault();
var listing = {!! $posts !!};
console.log("list ", listing);
var lastId = listing[2].id;
console.log("id from pos 2, listing ", lastId);
var parts = $(listing).slice(lastId);
console.log("part ", parts);
// THIS DOESN'T WORK, BY THE WAY
// var lastId = listing[2].id;
// console.log("listing 2 id", lastId);
$('#loadingPosts').html("Loading More Posts");
$.ajax({
url: '{{ route('loadMore') }}',
method: 'GET',
// data: {
// 'id': lastId,
// I was trying to set up an ID here, but it didn't work as well
// },
// contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(data) {
// console.log("checking if data not null", data);
// this returns the expected $posts array
$('#blog-post').html(data);
// using .html() because .append() didn't work, which is weird, I guess
console.log("data depois do apend", data);
// This returns the same $posts array
lastId = data[2].id;
console.log("last id from data", lastId);
// I can retrieve the id from the given position from the array.
// I was trying to set up the id here so I could check, with jQuery, the last post iterated, so I could continue from that point forward
$('#loadingPosts').html("load More");
return data[2].id;
// A last minute despair
}
});
});
</script>
Well, it doesn't work (that's the reason I'm here). I really don't know what I am doing wrong, since the $posts
array is passing...
I need help with this, please.
A few things worth saying:
Laravel comes with a default pagination, but it works "horizontally", and the projects asks for a "vertical" pagination.
The page must have a "load more" button because the footer has some much needed info, so the content can not load automatically
IF there is a way to make it work using vanilla JavaScript OR using Laravel's PHP methods (EXCEPT FOR THE PAGINATION METHOD, AS STATED BEFORE), I would be really happy
Thank you all in advance.