Laravel 5 Search and pagination url's together - laravel

I have a search button and pagination system. They are working perfectly. But when i searched something and page was paginated with numbers. After clicking next page. Search query is gone. After that all values are coming into page2. Not searched values.
My search button changing url like this /en/news?q=foo
My pagination is changing url like this(default btw) /en/news?page=2
How can i add this side by side. Or how can i solve the problem. I am open any solution.
I am using scope for search.
public function scopeSearch($query, $search) {
return $query->where('title', 'LIKE', '%' .$search. '%')
->orWhere('sub_body', 'like', '%' .$search. '%')
->orWhere('body', 'like', '%' .$search. '%');
}
Also this is my controller:
public function index (Request $request){
$localeCode = LaravelLocalization::getCurrentLocale();
$updates = Update::latest()->take(3)->get();
$query = $request->get('q');
if ($query){
$new = $query ? News::search($query)->orderBy('id', 'desc')->paginate(10):News::all();
return view('frontend.news', compact('localeCode', 'updates', 'new', 'query'));
}
else
{
$new = News::orderBy('id', 'desc')->paginate(10);
return view('frontend.news', compact('localeCode', 'updates', 'new', 'query'));
}
}
I hope i can express my own.

{{ $users->appends($_GET)->links() }}
that append all your filter value in one line

It is explained in the documentation for displaying pagination results:
Appending To Pagination Links
You may append to the query string of pagination links using the appends method. For example, to append sort=votes to each pagination link, you should make the following call to appends:
{{ $users->appends(['sort' => 'votes'])->links() }}
I find your current code quite confusing. I think you can rewrite it like this
public function index (Request $request){
$localeCode = LaravelLocalization::getCurrentLocale();
$updates = Update::latest()->take(3)->get();
$query = $request->get('q');
$new = $request->filled('q') ? News::search($query) : News::query();
$new = $new->orderBy('id', 'desc')->paginate(10);
return view('frontend.news', compact('localeCode', 'updates', 'new', 'query'));
}
and in the view you'll have to use
{{ $new->appends(['q' => $query])->links() }}

Try to use {{ $collection->appends(request()->all())->links() }}

Related

How to return paging cache in laravel?

I would like to know if there is any way to page this query that I do in Laravel and store it in the cache.
I've already put ->paginate() but it seems that the cache doesn't return in Eloquent but as an object. I checked the variable's type with gettype().
this is my role. Can anyone help me?
public function getProductsRecommendations($keywords)
{
$expiration = 10;
$keyName = 'productsRecommended';
$list = Cache::remember($keyName, $expiration, function () use ($keywords) {
return Product::query()->where(function ($productsAll) use ($keywords) {
if ($keywords) {
foreach ($keywords as $keyword)
$productsAll->orWhere('title', 'LIKE', '%' . $keyword . '%')->orWhere('description', 'LIKE', '%' . $keyword . '%')->orWhere('code', 'LIKE', '%' . $keyword . '%');
}
})->where('status', 'active')->get();
});
return $list;
}
You should cache your results per page, with a key that is the current page. Something like:
$currentPage = request()->get('page',1);
$category = Cache::remember('sellcategory-' . $currentPage, 10, function(){
return DB::table('elans')->orderBy('updated_at', 'desc')->where(['derc' => 1,'elaninnovu' => 'Satılır'])->paginate(10);
});
I managed to do what I needed. I'll leave it here in case someone goes through the same problem and finds this question.
Sometimes you might want to create an instance of paging manually, passing in an array of items. You can do this by creating an Illuminate\Pagination\Paginator or Illuminate\Pagination\LengthAwarePaginator instance, depending on your needs.
To exemplify:
use Illuminate\Pagination\Paginator;
$paginator = new Paginator($array, $rowPerPage, $currentPage = null);

Do not display duplicated posts on 2nd loop if 1st loop already displays the same posts in laravel

I'm building a dictionary website with laravel6.
And when a visitor search a keyword, 2 queries will run to find posts.
Controller.php
public function index(Request $request)
{
$keyword = $request->input('keyword');
$query = Post::query();
$query2 = Post::query();
if(!empty($keyword)){
$query->where('word','like','%'.$keyword.'%');
$data = $query->orderby('word', 'DESC')->paginate(4);
$query2->where('definition','like','%'.$keyword.'%');
$data2 = $query2->orderby('definition', 'DESC')->paginate(4);
return view('index')->with(['keyword' => $keyword])->with(['data' => $data])->with(['data2' => $data2]);
}
}
Then, show 1st query & 2nd query result.
index.blade.php
#foreach($data as $val)
<div class="post">
<h2>{{$val->word}}</h2>
<p>{{$val->definition}}</p>
</div>
#endforeach
#foreach($data2 as $val2)
<div class="post">
<h2>{{$val2->word}}</h2>
<p>{{$val2->definition}}</p>
</div>
#endforeach
The problem is, 2nd loop ($data2) shows duplicate posts of $data.
So how can I not display duplicate posts on $data2 loop?
I tried like:
#foreach($data2 as $val2)
#if($val2->id !== $val->id)
<div class="post">
<h2>{{$val2->word}}</h2>
<p>{{$val2->definition}}</p>
</div>
#endif
#endforeach
But didn't work. Appreciate any suggestion.
If you use the pagination for queries the only solution is to implement code in the controller. In the second foreach of the view it is not possible to know all the values of the first foreach.
If I understand your question correctly, you can change your approach and use a single query.
In the controller you can write a query more or less like this:
$data = Post::select('word', 'definition')
->where(function ($query) use ($keyword) {
$query->where('word', 'like', '%' . str_replace(' ', '%', $keyword) . '%')
->orWhere('definition', 'like', '%' . str_replace(' ', '%', $keyword);
})
->paginate(4);
You have no duplicate posts and you can also search with multiple words separated by a space (for multiple search the order of words must be that of the text).
EDIT:
This the solution with two query. The first query rest the same, the second query is filtered by the id list of the first query:
$listDataId = Post::where('word','like','%'.$keyword.'%')>orderby('word', 'DESC')->get()->pluck('id');
$query2->where('definition','like','%'.$keyword.'%');
$data2 = $query2->whereNotIn('id', listDataId)->orderby('definition', 'DESC')->paginate(4); // whereNotIn exclude the first query value
You can also do that with laravel's collection. As you might have noticed each query in laravel is a collection, so you can play with collections like you can search here https://laravel.com/docs/7.x/collections#method-merge
public function index(Request $request)
{
$keyword = $request->input('keyword');
$query = Post::query();
$query2 = Post::query();
if(!empty($keyword)){
$query->where('word','like','%'.$keyword.'%');
$data = $query->orderby('word', 'DESC')->paginate(4);
$query2->where('definition','like','%'.$keyword.'%');
$data2 = $query2->orderby('definition', 'DESC')->paginate(4);
//collection starts here.
//It will replace duplicate keys and will give you one collection
$merged = $data->merge($data2);
//Now you will have only one foreach loop in the view.
return view('index')->with(['keyword' => $keyword])->with(['data' => $merged]);
}
}
You can use the following query
$query2->where('definition','like','%'.$keyword.'%')->where('word','not like','%'.$keyword.'%')

Laravel search with localization

I have a scope about searcing. Also using localization from mcamara
Right now, when i am search something, results are coming with different languages. But i can just search with my main language. After results are came translation happening. This is related with my blade.
{!! $news->translate($localeCode)->title !!}
But main question is before the search. How can i search something with selected language. I can switch language easily. This is my search scope.
public function scopeSearch($query, $search) {
$localeCode = LaravelLocalization::getCurrentLocale();
return $query->translate($localeCode)->where('title', 'LIKE', '%' .$search. '%')
->orWhere('sub_body', 'like', '%' .$search. '%')
->orWhere('body', 'like', '%' .$search. '%');
}
Also this is my controller
public function index (Request $request){
$localeCode = LaravelLocalization::getCurrentLocale();
$updates = Update::latest()->take(3)->get();
$query = $request->get('q');
$new = $request->filled('q') ? News::search($query) : News::query();
$new = $new->orderBy('id', 'desc')->paginate(10);
return view('frontend.news', compact('localeCode', 'updates', 'new', 'query'));
}
I'll be glad if anyone help. Thanks advance.

Paginate search result laravel

After some help in a previous post Laravel - Search Facility on site using Eloquent I now need to some help on paginating the result using the built in laravel pagination class.
public function search() //no parameter now
{
$q = Input::get('term');
if($q && $q != ''){
$searchTerms = explode(' ', $q);
$query = DB::table('wc_program'); // it's DB::table(), not DB::tables
if(!empty($searchTerms)){
foreach($searchTerms as $term) {
$query->where('JobRef', 'LIKE', '%'. $term .'%');
}
}
$results = $query->get();
dd($results); // for debugging purpose. Use a View here
}
}
Simply change get to paginate and provide number of items per page.
$results = $query->paginate(10);

Paginate / Search Laravel issue

After a couple of conversations on here i'm finally getting somewhere but after the pagintion now works when i got to search?page=2 i get a json array of the logged in user and not page 2 of the results.
Here's my controller:
public function search()
{
$q = Input::get('term');
if($q && $q != ''){
$searchTerms = explode(' ', $q);
$query = DB::table('wc_program');
if(!empty($searchTerms)){
foreach($searchTerms as $term) {
$query->where('JobRef', 'LIKE', '%'. $term .'%');
$query->orwhere('Road', 'LIKE', '%'. $term .'%');
}
}
$results = $query->paginate(10);
return View::make('layouts.results', compact('results'));
}
}
Route:
Route::get('/search', 'HomeController#search');
So how can i work around this?
You need to append query string to the pagination.
in your controller, pass the query string to the view.
return View::make('layouts.results', compact('results', 'q'));
In your view (results.blade.php):
append the query string to the pagination otherwise in page 2 you will not get any result.
<?php echo $results->appends(array('term' => $q))->links(); ?>

Resources