laravel pagination with search wrong links - laravel

I am trying to apply laravel pagination with search functionality.
So far I have tried both live search with laravel pagination and that keeps failing and normal search with pagination where I got better results but still not working.
Here is what I last tried for normal search with pagination:
ProjectController:
public function index()
{
$projects = Project::paginate(6);
return view('dashboard.projects.index',['projects' => $projects]);
}
public function search(Request $request)
{
$q = $request->input('q');
if(!empty($q)){
//dd("search");
$projects = Project::where('name', 'LIKE', '%' . $q . "%")->orderBy('created_at','desc')->paginate(6)->setPath('');
$projects->appends(['q' => $request->input('q')]);
return view ( 'dashboard.projects.index')->with('projects',$projects);
}
return redirect('/dashboard/projects/');
}
dashboard.projects.index
<div class="container-fluid">
<div class="row section-primary">
#foreach($projects as $project)
<div class="col-12 col-md-4 mb-2">
<div class="card project h-100">
<div class="card-header">
<h4>{{$project->name}}</h4>
</div>
<div class="card-body">
<p><strong>Project Manager:</strong> {{$project->manager_name}}</p>
<p class="description">{{ substr($project->description, 0, 110) }}...</p>
<div class="display-flex">
<div>View</div>
<div>Edit</div>
<div>Members</div>
<div>
{!!Form::open(['action' => ['ProjectController#destroy', $project->id], 'method' => 'POST','class' => 'form-link'])!!}
{{Form::hidden('_method', 'DELETE')}}
{{Form::submit('Delete', ['class' => 'button-link'])}}
{!!Form::close()!!}
</div>
</div>
</div>
</div>
</div>
#endforeach
</div>
</div>
<div>
{!! $projects->links()!!}
</div>
The code works fine when I go to dashboard/projects and pagination works.
The search works but pagination fails.
When I press the search button it first goes to dashboard/projects/search
Then when I press page 2 button on pagination it goes to dashboard/projects/search?q=project&page=2, here it is requesting the show function which is unrelated.
PS: Any extra help for live search with pagination would be amazing.

I have managed to fix the problem, for anyone who is facing the same issue, I used in my routes:
Route::resource('/dashboard/projects', 'ProjectController');
Route::any('/dashboard/projects/search', 'ProjectController#search');
For some reasons, /dashboard/projects/search was not a good idea as it was going to the show defined by resource, all I had to do is change:
Route::any('/dashboard/projects/search', 'ProjectController#search');
to
Route::any('/dashboard/project/search', 'ProjectController#search');
so they look like different routes until I find/learn a better solution.
The other solutions is putting the search route first such as:
Route::any('/dashboard/projects/search', 'ProjectController#search');
Route::resource('/dashboard/projects', 'ProjectController');

In larvel => 6 Version:
Input no longer exists In larvel 6,7,8 Version. Use Request instead of Input.
Change $q = $request->input('q'); to $q = $request->q;
Your ProjectController:
use Illuminate\Support\Facades\Request;
..
..
public function search(Request $request)
{
$q = $request->q;
if(!empty($q)){
//dd("search");
$projects = Project::where('name', 'LIKE', '%' . $q . "%")->orderBy('created_at','desc')->paginate(6)->setPath('');
$projects->appends(['q' => $request->input('q')]);
return view ( 'dashboard.projects.index')->with('projects',$projects);
}
return redirect('/dashboard/projects/');
}

Related

Laravel 5.7 | Pagination - eloquent query (relationship table)

how can I use pagination, where my eloquent query looks:
PageController - method show:
$page = Page::where('slug', $slug)->with(['subpages'=>function($q) {
$q->where('visible', 1)->orderBy('order', 'asc')->paginate(9);
}])->first();
I would like to paginate subpages on page's View blade (Page - one to many - Subpage relationship)
Here is part of my show.blade.php view:
{{ $page->subpages->links() }}
Error:
Method Illuminate\Database\Eloquent\Collection::links does not exist.
EDIT:
FULL FUNCTION SHOW:
public function show(PageRepository $pageRepo, $slug){
$page = Page::where('slug', $slug)->with(['subpages'=>function($q) {
$q->where('visible', 1)->orderBy('order', 'asc');
}])->first();
$subpages = $page->subpages()->paginate(2);
$sidebar = Navbar::where('type','sidebar')->orderBy('order')->with(['pages'])->get();
return view('pages.page.show', [
"page" => $page,
"subpages" => $subpages,
"sidebar" => $sidebar,
]);
}
VIEW:
<div class="row display-flex">
#foreach($page->subpages as $subpage)
<div class="col-sm-4">
<div class="card mb20">
<div class="card-block">
<h4 class="card-title font400">{{ $subpage->title }}</h4>
</div>
</div>
</div>
#endforeach
</div>
{{ $subpages->links() }}
If your goal is to paginate the relation from what I see, but you're querying the parent model. That's what's wrong. You have to completely change your logic since the subquery doesn't map the relation inside the Laravel Model. It's just used as a condition to retrieve that model.
You query should look like this:
$page = Page::where('slug', $slug)->with(['subpages'=>function($q) {
$q->where('visible', 1)->orderBy('order', 'asc') // ->paginate(9); This is not necessary
}])->first();
Now that you have the parent model, you can execute a new query for the relation, and there you have to call the paginate method:
I don't think that would be a good practice to do something like this in your blade view:
{{ $page->subpages()->paginate(9)->links() }}
But it's better to implement a new variable:
// Previous code that retrieves the page
$subpages = $page->subpages()->paginate(9);
return response()->view('your.blade.view', compact('page', 'subpages');
now you can use the subpages variable, that contains the paginated results, in your view

Foreach doesnt work in my View in laravel 5.6

public function getValues(Request $request){
$typ=$request->get('typ');
$stellentyp=$request->get('stellentyp');
$bereich=$request->get('bereich');
$abschluss=$request->get('abschluss');
$user = DB::table('users')->get();
$angebots = DB::table('angebots') ->orderBy('stellenname', 'asc');
if(!empty($request->get('stellentyp'))){
$angebots->where('stellentyp', $stellentyp);
}
$angebots->get();
$row = $angebots->count();
return view('user/angebots', compact('typ', 'stellentyp', 'bereich', 'abschluss', 'row', 'angebots', 'user'));
}
this is my controller
{{$row}} Angebote insgesamt
<div class="row">
#foreach ($angebots as $angebot)
<div class="col-12 col-md-6 col-lg-4 pt-4">
<div class="card offer-card">
<div class="card-image">
<img class="img-fluid" src="{{ asset('uploads/avatars/' . $user[$angebot->firma -1]->avatar) }}">
</div>
<div class="card-body">
<h4 class="text-j4y-dark praktikumstitel">{{ $angebot->stellenname }}</h4>
Jetzt mehr anzeigen ยป
</div>
</div>
</div>
#endforeach
</div>
and this is my view
but i got this error message:
Undefined property: Illuminate\Database\MySqlConnection::$firma (View: C:\wamp\sites\j4ylara\resources\views\user\angebots.blade.php)
if I put the get behind my first statement so like this
$angebots = DB::table('angebots') ->orderBy('stellenname', 'asc')->get();
but then the filter doesn't work
I don't know how I can view my results
I only know this way
{{$angebot[1]->stellenname}}
but I want all my results so I use a foreach but it doesn't work
does anyone know why?
In the following snippet
$angebots = DB::table('angebots') ->orderBy('stellenname', 'asc');
if(!empty($request->get('stellentyp'))){
$angebots->where('stellentyp', $stellentyp);
}
$angebots->get();
You're doing $angebots->get() which returns the results of your query. You need to assign the results of your query to a variable and pass that into your view. You could do something like this:
$angebots = $angebots->get();
Which would assign the result of the query to $angebots and then you could use it in your view.
Personally, I would consider renaming $angebots to $angebotsQuery or something similar and then do this:
$angebotsQuery = DB::table('angebots') ->orderBy('stellenname', 'asc');
if(! empty($request->get('stellentyp'))){
$angebotsQuery->where('stellentyp', $stellentyp);
}
$angebots = $angebotsQuery->get();
You are sending the Builder in $angebot. Try putting the results in a variable.
public function getValues(Request $request){
$typ=$request->get('typ');
$stellentyp=$request->get('stellentyp');
$bereich=$request->get('bereich');
$abschluss=$request->get('abschluss');
$user = DB::table('users')->get();
$angebots = DB::table('angebots') ->orderBy('stellenname', 'asc');
if(!empty($request->get('stellentyp'))){
$angebots->where('stellentyp', $stellentyp);
}
$angebots = $angebots->get();
$row = $angebots->count(); //this will not cause an issue since the Collection has a count method
return view('user/angebots', compact('typ', 'stellentyp', 'bereich', 'abschluss', 'row', 'angebots', 'user'));
}

Laravel 5.0: Route with query string

I am using laravel 5.0, I am sending a query string on A tag with an id.
I am getting id but not the query string data
Below is the code:
View
<div class="col-xs-12 col-sm-4 col-md-4 col-lg-4">
<div class="img-decor">
<a href="{{url('buycarddetail/'.$retailer->id)}}" class="">
<img src="{{ assetnew('uploads/client_image/'.$retailer->image) }}" alt="..." class="img-rounded" width="200">
</a>
<div class="deals-title">
{{ $retailer->name }}
<div class="sub-details">Save up to {{ $retailer->discount }}%</div>
</div>
</div>
</div>
Controller
public function buycarddetail($id = null, Request $request)
{
echo $id;
echo '<pre>'; $data = $request->all(); exit;
return view('buycarddetail');
}
Route
Route::get('buycarddetail/{id}', ['as' => 'buycarddetail', 'uses' => 'HomeController#buycarddetail']);
I want to use the query string data for further process on controller
Please help
Based on your code you're not actually appending any query string when generating the link {{url('buycarddetail/'.$retailer->id)}}.
As per your comments you can do this to generate a link to your route with the query string.
{{ route('buycarddetail', ['id' => $retailer->id, '_token' => csrf_token(), 'brand' => 'test', 'buybrand' => 'example']) }}
This example would generate a link like
http://example.com/buycarddetail/17?_token=QHE8va7stXUOPabwTjKmXyJxdsuPSZ9VbH3uThwx&brand=test&buybrand=example

Laravel Pagination Appends Not Keeping Search Data

I've been able to implement the pagination and appends() on my form and it does show the proper values in the url on page 2, though it doesn't actually bring the values back into the form/query, it simply resets the actual data being searched for and displays all.
Here is my form code and the appends.
{{ Form::open(array('class' => 'stdform', 'method' => 'post', 'name' => 'all')) }}
<input type="text" name="srch_lname" class="input-large"
value="{{ Input::old('srch_lname', Session::get('srch_lname')) }}" />
<input type="text" name="srch_fname" class="input-large"
value="{{ Input::old('srch_fname', Session::get('srch_fname')) }}" />
.
.
.
<?php echo $employees->appends(array("srch_lname" => Session::get('srch_lname'),
"srch_fname" => Session::get('srch_fname') ))->links(); ?>
And my Controller
public function getIndex() {
$srch_lname = Session::get('srch_lname');
$srch_fname = Session::get('srch_fname');
$employees = vEmployees::co()->restrictions()
->where('lastname', 'LIKE', $srch_lname . '%')
->where('firstname', 'LIKE', $srch_fname . '%')
->paginate(10);
return View::make('employees.index')
->with('employees', $employees)
->with('title', 'Users');
}
public function postIndex() {
if (Input::has('btnSearch')) {
return Redirect::to('/employees')->with('search', 1)
->with('srch_lname', Input::get('srch_lname'))
->with('srch_fname', Input::get('srch_fname'));
else {
return Redirect::to('/employees');
}
}
Full Form
{{ Form::open(array('class' => 'stdform', 'method' => 'post', 'name' => 'all')) }}
<div class="stepContainer">
<div class="formwiz content">
<h4 class="widgettitle">Search for an Employee</h4>
<p>
<label>Lastname</label>
<span class="field">
<input type="text" name="srch_lname" class="input-large"
value="{{ Input::old('srch_lname', Session::get('srch_lname')) }}" />
</span>
</p>
<p>
<label>Firstname</label>
<span class="field">
<input type="text" name="srch_fname" class="input-large"
value="{{ Input::old('srch_fname', Session::get('srch_fname')) }}" />
</span>
</p>
</div>
</div>
<div class="actionBar" style="text-align: right;">
<button class="btn btn-primary" name="btnSearch" value="1">
Search for Employee(s)
</button>
</div>
{{ Form::close() }}
You need to pass your inputs to the view so that Input::old() has values to work with after the redirect from postIndex to getIndex.
in getIndex(), add to View::make()
->with('input', [ 'srch_lname'=> $srch_lname, 'srch_fname' => $srch_fname ]);
It looks like you do not have the pageSearch value in your pagination query string. Try this.
<?php echo $employees->appends(
array("btnSearch" => "1",
"srch_lname" => Session::get('srch_lname'),
"srch_fname" => Session::get('srch_fname') )
)->links(); ?>
I made a small sample but since I don't have your employees I just used the User model and commented out the filtering, just used as a test to pass and get input values.
Note the change to Input:: from Session, in getIndex() and in the form for $employees->appends(). Use Input instead of Session, I did not see anywhere in your code where you save the filter values in session variables.
I also changed the Redirect::to() to pass the parameters in the URL since it is a get method.
I tested and the filter values are passed to getIndex() and the form fields, also the inputs get properly passed by pagination links.
class EmployeeController extends BaseController
{
public
function getIndex()
{
$srch_lname = Input::get('srch_lname');
$srch_fname = Input::get('srch_fname');
$employees = User::query()
//->where('lastname', 'LIKE', $srch_lname . '%')
//->where('firstname', 'LIKE', $srch_fname . '%')
->paginate(10);
// make input available for page's form fields as old input
Session::flash('_old_input', Input::all());
return View::make('employees')
->with('employees', $employees)
->with('title', 'Users');
}
public
function postIndex()
{
if (Input::has('btnSearch'))
{
return Redirect::to('/employees?search=1&srch_lname=' . urlencode(Input::get('srch_lname')) . '&srch_fname=' . urlencode(Input::get('srch_fname')));
//return Redirect::to('/employees')->with('search', 1)
// ->with('srch_lname', Input::get('srch_lname'))
// ->with('srch_fname', Input::get('srch_fname'));
}
else
{
return Redirect::to('/employees');
}
}
}
Form and ->appends():
{{ Form::open(array('class' => 'stdform', 'method' => 'post', 'name' => 'all')) }}
<div class="stepContainer">
<div class="formwiz content">
<h4 class="widgettitle">Search for an Employee</h4>
<p>
<label>Lastname</label>
<span class="field">
<input type="text" name="srch_lname" class="input-large"
value="{{ Input::old('srch_lname', Session::get('srch_lname')) }}" />
</span>
</p>
<p>
<label>Firstname</label>
<span class="field">
<input type="text" name="srch_fname" class="input-large"
value="{{ Input::old('srch_fname', Session::get('srch_fname')) }}" />
</span>
</p>
</div>
</div>
<div class="actionBar" style="text-align: right;">
<button class="btn btn-primary" name="btnSearch" value="1">
Search for Employee(s)
</button>
</div>
{{ Form::close() }}
<?php echo $employees->appends(array("srch_lname" => Input::get('srch_lname'),
"srch_fname" => Input::get('srch_fname') ))->links(); ?>
I got it working! I continued to do some research and running the search through POST was really a major issue in adding that gap between the search itself and holding the data into the GET method of pagination.
I'll run through everything I did below for anyone in the future having the same issue.
I first created a Route that would direct to a new function in my EmployeesController
Route::get('emp_srch', 'EmployeesController#search');
And created the new function in the Controller
public function search() {
$srch_lname = Input::get('srch_lname');
$srch_fname = Input::get('srch_fname');
$employees = vEmployees::co()->restrictions()
->where('lastname', 'LIKE', $srch_lname . '%')
->where('firstname', 'LIKE', $srch_fname . '%')
->orderBy('lastname')
->orderBy('firstname')
->paginate(10);
Session::flash('_old_input', Input::all());
return View::make('employees.index')
->with('employees', $employees)
->with('title', 'Users')
->with('pagetitle', 'Employees')
}
It's essentially the function I had in the getIndex though rearranging the way the search was functioning I believe was the defining factor in actually getting this to work in my case.
I also changed the url on the form, which directed to my new Route. As well as changing the form so it uses the GET Method and no longer POST.
{{ Form::open(array('url' => 'emp_srch', 'class' => 'stdform', 'method' => 'get')) }}
I do want to thank vladsch and whoacowboy for helping push me in the right direction(s).

Laravel 4 search - in view, show value submitted in form

Below is the beginnings of filter form I have built. It works ok but what I'd like to do is retrieve in my view, the values entered for. So, in this example I'd like to display "you searched by 'the keyword user entered'", and also display this within the keyword text field. This will be the same principle when I add select lists.
If the user wishes to change filter settings, or paginate through the results, the values are always stored.
My question is how to do this. I'm quite sure it's possible in laravel but only know how to do this in PHP
FORM
<div class="row">
{{ Form::open(array('url'=>'events/search', 'class'=>'form-search', 'role'=>'form')) }}
<div class="col-lg-6">
<div class="input-group">
{{ Form::text('search', '', array('class'=>'form-control', 'placeholder'=>'Search by keyword.'))}}
<span class="input-group-btn">
{{ Form::submit('Search', array('class'=>'btn btn-default'))}}
</span>
</div>
</div>
{{ Form::close() }}
</div>
SEARCH CONTROLLER
public function postSearch() {
$search = Input::get('search');
$events = DB::table('events')
->where(function($query) use ($search)
{
$query->where('title', 'LIKE', '%' . $search . '%')
->where('date','>=', DB::raw('CURDATE()'));
})
->orderBy('date', 'DESC')
->get();
$this->layout->content = View::make('events.results',
array(
'events' => $events
)
);
}
VIEW
#foreach($events as $event)
<div class="col-md-9">You search for ''</div>
{{-- filter form will again display here --}}
<h2>{{ HTML::link("events/$event->id/", "$event->title") }}</h2>
#endforeach
Controller:
public function postSearch() {
$search = Input::get('search');
$events = DB::table('events')
->where(function($query) use ($search)
{
$query->where('title', 'LIKE', '%' . $search . '%')
->where('date','>=', DB::raw('CURDATE()'));
})
->orderBy('date', 'DESC')
->get();
$this->layout->content = View::make('events.results',
array(
'events' => $events,
'search' => $search <-------- pass the search parameter to view
)
);
}
View:
#if(!empty($search))
<div class="col-md-9">You search for {{$search}}</div>
#endif
#foreach($events as $event)
{{-- filter form will again display here --}}
<h2>{{ HTML::link("events/$event->id/", "$event->title") }}</h2>
#endforeach
Two issues:
Generally search forms are GET and not POST. (easier to bookmark, give the links elsewhere)
put the search term outside the loop.

Resources