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.
Related
i can't search when it comes to searching NUMBERS on row int (price), but when searching like String number on row string (name) it's working fine
like this in my table row here is my Product table
category_id
"56"
user_id
"1"
name
"555"
description
"fruit"
price
555
when i am searching the name row "555" it's working fine beacuse its a string. but when it comes to price i can't search it because it's int
here is my code for controller searching
public function index(Request $request){
$user = Auth::user()->id;
if($request->search){
$search = $request->search;
$products = Products::with('category')
->where('name','like',"%$search%")
->orWhere('price','like',"%$search%")
->where('user_id',$user)->paginate(10);
}else{
$products = Products::with('category')->where('user_id',$user)->paginate(10);
}
return view('client.product.index',['products'=>$products]);
}
here is my blade
<form class="w-full" action="{{ route('client.product.index') }}">
<i class="fa fa-search"></i>
<input placeholder="Search" type="search" name="search">
<button type="submit">Search</button>
</form>
#foreach ($products as $product)
<p>{{ $product->name }}</p>
<p>{{ $product->price }}</p>
#endforeach
{{ $products->withQueryString()->links('pagination::bootstrap-4') }}
You need to group the where and orWhere so the user_id will be correctly filtered:
$products = Products::with('category')
->where( function($q) use ($search) {
$q->where('name','like',"%$search%");
$q->orWhere('price','like',"%$search%");
})
->where('user_id',$user)->paginate(10);
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/');
}
I am working with Scope Search and cannot figure out why my ternary operator is working like it is.
I have the following in my view:
<form action='/search-results' method='GET'>
{{ csrf_field() }}
<div style="background-color:white">
<div class="container py-5">
<div class="input-group custom-search-form md-form mt-0">
<input type="text" class="form-control" name="city" placeholder="City...">
<input type="text" class="form-control" name="search" placeholder="Search...">
<span class="input-group-btn">
<button class="btn btn-default-sm" type="submit">
Submit
</button>
</div>
</div>
</div>
</form>
I have the following in my Controller:
public function index()
{
{
//The search() function is accessed using 'scopeSearch' within NPIData Model
$providers = NPIData::lookup()->orderBy('NPI')->paginate(20);
return view('inc.searchresults', compact('providers'));
}
I have the following in my NPIData model:
public function scopeLookup($query)
{
//this says if the request is NOT empty, return $query (which would be an empty query), otherwise return $query with all the conditions listed
return empty(request()) ? $query : $query->where('NPI', 'like', '%'.request()->search.'%')
->where('Entity Type Code', '=', '1')
->where('Provider Business Mailing Address City Name', '=', request()->zip)
->orWhere('Provider First Name', 'like', '%'.request()->search.'%')
->orWhere('Provider Last Name (Legal Name)', 'like', '%'.request()->search.'%');
}
}
When a search term is entered in both the 'city' and 'search' text inputs, the $query executes correctly. However, if one or both inputs are left blank, the $query returns everything from my NPIData table. If one or both inputs are left blank, I want my $query to return nothing so the search results are blank. I assume I have to change something in the second part of my ternary operator but cannot figure out what that should be.
You can use where 1 < 0 which is pretty standard way to get empty result
public function scopeLookup($query)
{
//this says if the request is NOT empty, return $query (which would be an empty query), otherwise return $query with all the conditions listed
return empty(request()) ? $query->whereRaw('1 < 0') : $query->where('NPI', 'like', '%'.request()->search.'%')
->where('Entity Type Code', '=', '1')
->where('Provider Business Mailing Address City Name', '=', request()->zip)
->orWhere('Provider First Name', 'like', '%'.request()->search.'%')
->orWhere('Provider Last Name (Legal Name)', 'like', '%'.request()->search.'%');
}
I am trying to run a search query on all of my comments. I am encountering a number of problems. I would to have two search queries one that runs a search on the comment ID and another that runs a search on the username that is connected to the comment through the user_id FK.
Currently im getting the problem:
Too few arguments to function Illuminate\Support\Collection::get(), 0 passed in
Tables:
Comment- id, comment, user_id, timestamps
User - id, name, username
Models:
class Comment extends Model
{
public function author()
{
return $this->belongsTo('App\User','user_id');
}
}
Controller:
public function index(Request $request)
{
$comment =Comment::paginate(10);
$id=$request->input('id');
$name=$request->input('username');
if(!empty($id)){
$comment->where('id', $request->input('id') )->get();
}
if(!empty($name)){
$comment->where($comment->author->username, 'LIKE', '%'.$name.'%')->get();
}
return view('comments.index')->withComment($comment);
}
View:
<div class="panel-body">
{!! Form::open(['route' => 'comments.index', 'method' => 'GET']) !!}
<div class="col-md-5">
{!! Form::label('id', 'Search By ID:') !!}
{!! Form::text('id', null, array('class' => 'form-control')) !!}
</div>
<div class="col-md-5">
{!! Form::label('username', 'Search By Username:') !!}
{!! Form::text('username', null, array('class' => 'form-control')) !!}
</div>
<div class="col-md-2">
{!! Form::submit('Find Comments', array('class' => 'btn btn-send ')) !!}
</div>
{!!Form::close()!!}
</div>
#foreach($comment as $comments)
//data
#endforeach
The paginate function immediately executes the query for you, so you are using Collection functions after that. The get function on collections expects a key as a parameter, this is the problem.
To fix this, you can either remove the ->get() or use the paginate function at the end of your query as shown below.
$comment = Comment::query();
$id = $request->input('id');
$name = $request->input('username');
if (!empty($id)) {
$comment = $comment->where('id', $request->input('id'));
}
$result = $comment->paginate(10);
Since You have Paginated already
public function index(Request $request)
{
$comment = new Comment();
$id=$request->input('id');
$name=$request->input('username');
if(!empty($id)){
$comment->where('id', $request->input('id') )->get();
}
if(!empty($name)){
$comment->where($comment->author->username, 'LIKE', '%'.$name.'%');
}
return view('comments.index')->withComment($comment->paginate(10));
}
You cannot paginate and get it again, its like using SELECT statement twice on same object.
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).