I'm building a project with Laravel 8. I need to handle request parameter which contains page, limit, searchColumn, searchText, orderColumn and orderDirection. Sometimes I need to search in relations. I've built this system below but it doesn't work on relationships.
$query = (new Log())->newQuery();
$query->with('customer', 'domain', 'type');
if ($request->searchColumn != "" && $request->searchColumn != NULL) {
$query->where($request->searchColumn, 'LIKE', '%' . $request->searchText . '%');
}
if ($request->orderColumn != "" && $request->orderColumn != NULL) {
$query->orderBy($request->orderColumn, $request->orderDirection);;
}
$logs = $query->paginate($request->limit, ['*'], '', $request->page);
For example if $request->searchColumn is 'customer.name', how should I search? I've tried few ways but they don't work.
You may use whereHas method which allow to define additional query constraints on your relation. E.g:
$searchText = $request->searchText;
if ( explode( '.', $request->searchColumn )[0] == 'customer' ) {
$query->whereHas( 'customer', function( $query ) use ( $searchText ) {
$query->where( 'name', 'LIKE', '%' . $searchText . '%' )
});
}
Related
Im working on product filtering using AJAX. Is there any possible way to produce same output as picture shown below using query builder?
I have tried union but it’s not working.
I hope this example gives idea , Try this one
use multiple if statement and get data into DB using joins .
function datatables($request) {
$data = $this->leftJoin('blog_category', 'blog_category.blog_category_uuid', '=', 'blog_detail.blog_category_uuid')
->where('blog_detail.blog_detail_is_deleted', 'NO');
if ($request->search['value'] != null && $request->search['value'] != '') {
$keyword = $request->search['value'];
$data = $data->where(function($query) use ($keyword) {
// $query->orWhere('activity_type.activity_type_name', 'LIKE', '%' . $keyword . '%');
$query->orWhere('blog_detail.blog_detail_title', 'LIKE', '%' . $keyword . '%');
});
}
if (isset($request->order[0]['dir'])) {
$data = $data->orderBy('blog_detail.blog_detail_id', $request->order[0]['dir']);
} else {
$data = $data->orderBy('blog_detail.blog_detail_created_date');
}
$datacount = $data->count();
$dataArray = $data->select('blog_detail.*', 'blog_category.blog_category_name' , DB::raw('DATE_FORMAT(blog_detail.blog_detail_created_date,"%Y-%m-%d") as blog_detail_date'));
if ($request->length == -1) {
$dataArray = $dataArray->get();
} else {
$dataArray = $dataArray->skip($request->start)->take($request->length)->get();
}
return [$datacount, $dataArray];
}
In laravel you can create a model for product say Product. Then the query will be like
$products = Product::where('product_status', '1');
if ($request->input('minimum_price') && $request->input('maximum_prize')) {
$products = $products->whereBetween('product_prize', array($request->input('minimum_price'), $request->input('maximum_prize')));
}
if ($request->input('brand')){
$brand_filter = implode("','", $request->input('brand'));
$products = $products->whereIn('product_brand', $brand_filter);
}
$products = $products->get();
after the execution $products contains the products after query.
I have a GET form with three filters.
make
Year
country
I need to get all posts from db. But filter the results based on these three filters.
If a country is selected, get posts for that country only or all countries.
if a make is selected, get posts for that make only or all makes
if a year is selected, get posts for that year only or all years
how to write one query that filters all these three options. What I have done is used if and else statements and written different queries for each scenario. That's 9 queries to get one information. Can we make it dynamic and just have one query?
My Example query:
public function search(Request $request)
{
$search=$request->input('search');
if($request->input('country') == "all")
{
$posts = Post::where('status','Published')->orderBy('status_change','DESC')
->where('status','Published')
->where(function($query) use ($search){
$query->where('title','LIKE','%'.$search.'%');
$query->orWhere('model','LIKE','%'.$search.'%');
$query->orWhere('notes','LIKE','%'.$search.'%');
$query->orWhere('description','LIKE','%'.$search.'%');
})
->paginate(25);
}
else
{
$posts = Country::where('country_name', $request->input('country'))->first()->posts()->orderBy('status_change','DESC')
->where('status','Published')
->where(function($query) use ($search){
$query->where('title','LIKE','%'.$search.'%');
$query->orWhere('model','LIKE','%'.$search.'%');
$query->orWhere('notes','LIKE','%'.$search.'%');
$query->orWhere('description','LIKE','%'.$search.'%');
})
->paginate(25);
}
return view('welcome')
->with('published_posts',$posts)
;
}
I think something like this would work:
/**
* #param Request $request
*/
function search(Request $request)
{
$postsQuery = Post::where('status', 'Published');
if ($request->has('country')) {
$country = $request->country;
// assuming relationships are setup correclty
$postsQuery->whereHas('country', function ($query) use ($country) {
$query->where('country_name', 'LIKE', $country);
});
}
if ($request->has('search')) {
$postsQuery->where(function ($query) use ($search) {
$query->where('title', 'LIKE', '%' . $request->search . '%');
$query->orWhere('model', 'LIKE', '%' . $request->search . '%');
$query->orWhere('notes', 'LIKE', '%' . $request->search . '%');
$query->orWhere('description', 'LIKE', '%' . $request->search . '%');
});
}
$postsQuery->orderBy('status_change', 'DESC')->paginate(25);
return view('welcome')->with('published_posts', $result);
}
I used 'when' method.
$make = null;
$year = null;
$country = null;
if($request->filled('make')){
$make = $request->query('make');
}
if($request->filled('year')){
$year = $request->query('year');
}
if($request->filled('country')){
$country = $request->query('country');
}
$posts = DB::table('posts')
->when($make, function($query, $make){
return $query->where("make", "=", $make);
})
->when($year, function($query, $year){
return $query->whereYear("year", "=", $year);
})
->when($country, function($query, $country){
return $query->where('country', "like", $country);
})
->get();
Check out the Laravel Docs:
Check out an article here
$search = Workforce::whereHas('task_schedule', function($q) use($request){
if($request->search_schedule_day != null){
foreach($request->search_schedule_day as $day){
/*$q->whereIn('schedule_day', 'like', '%'. $day .'%');*/
var_dump($day);
}
}
if($request->search_time_in != null){
$q->where('schedule_time_in', 'like', '%' . $request->search_time_in . '%');
}
if($request->search_time_out != null){
$q->where('schedule_time_out', 'like', '%' . $request->search_time_out . '%');
}
})
I am currently making an advanced search feature, and I have encountered this problem wherein I have an array of search_schedule[] . Then in the database, it is saved one day per row. How do I set a query for searching the days in that array ?
Edit
if($request->search_schedule_day != null){
foreach($request->search_schedule_day as $day){
/*$q->whereIn('schedule_day', 'like', '%'. $day .'%');*/
var_dump($day);
}
}
How can I set a query in the above block of code wherein it checks rows in database where column = $request->search_schedule_day
If you are trying to check whether the model's schedule_day is present in $request->search_schedule_day, you can try this:
if($request->search_schedule_day != null) {
$q->where(function($query)use($request) { // group orWheres
for ($request->search_schedule_date as $day) {
$query->orWhere('schedule_day', $day);
}
}
}
Whats the best way to build an Product Search Filter with an <select>?
My Route:
Route::any ( '/search', function () {
$q = Input::get ( 'q' );
if($q != ""){
$products = Product::where ( 'name', 'LIKE', '%' . $q . '%' )->orWhere ( 'description', 'LIKE', '%' . $q . '%' )->paginate (200)->setPath ( '' );
$pagination = $products->appends ( array (
'q' => Input::get ( 'q' )
) );
if (count ( $products ) > 0)
return view ( 'search' )->withDetails ( $products )->withQuery ( $q );
}
return view ( 'search' )->withMessage ( 'No Products!' );
} );
Now i want add an Drop down Filter with <select> to Search Page like:
<select name="sortby">
<option value="newproducts">New Products</option>
<option value="cheapprice">Cheapest Price</option>
</select>
Can i do it in my Route like:
if (select( ..newproducts... ) > 0)
return view ( 'search' )->withDetails ( $products )->withQuery ( $q );
}
Thanks for some tips:)
Sure you can add it there, but not with a conditional. You already pass a query parameter to search, just give the select a name and send that along too. You would use ->orderBy(...) on you collection you get when searching for $q.
// from your html
<select name="sortby">
// in your controller/route
$products->orderBy(request->get('sortBy'))
// new products
If (request->get('sortBy') === 'newproducts')
$products->orderBy('created_at', 'desc');
// cheap price
If (request->get('sortBy') === 'cheapprice')
$products->orderBy('price', 'asc');
https://laravel.com/docs/5.5/eloquent-collections#available-methods
I want sort my Search Results with an URL. I cant use Controller in my way because i use Route for /search.
My Search Route:
Route::get ( '/', function () {
$mydb= Product::paginate(200);
return view ( 'search' )->withProduct($mydb);
} );
Route::any ( '/search', function () {
$q = Input::get ( 'q' );
$sort = Product::where ( 'name', 'LIKE', '%' . $q . '%' )->orderBy('created_at','desc')->paginate(20);
if($q != ""){
$products = Product::where ( 'name', 'LIKE', '%' . $q . '%' )->orWhere ( 'description', 'LIKE', '%' . $q . '%' )->paginate (200)->setPath ( '' );
$pagination = $products->appends ( array (
'q' => Input::get ( 'q' )
) );
if (count ( $products ) > 0)
return view ( 'search' )->withDetails ( $products )->withQuery ( $q );
}
Now i want create an Button where i can Sort the results from query search.
Button Example:
Sort by Price
I want add like this to my Route:
$sort = Product::where ( 'name', 'LIKE', '%' . $q . '%' )->orderBy('created_at','desc')->paginate(20);
This dont work..
And then add the {{ $sort }}behind my Button URL like:
Sort by Price
Any Idea how i can do it correct? Sorry i am an Beginner with Laravel and i know its not correct.
Thanks!
There appears to be a lot of errors in your code.
But this line
Sort by Price
could be
Sort by Price
Then in your closure
$q = Input::get ( 'q' );
$orderby = Input::has('orderby') ? Input::get('orderby') : 'created_at';
$sort = Product::where ( 'name', 'LIKE', '%' . $q . '%' )->orderBy($orderby,'desc')->paginate(20);