I have a search form with multiple input and select boxes I need help to get if conditions in my query in order to each part works separately and all at once.
here is my blade codes:
<form action="{{route('advancesearch')}}" method="post">
{{csrf_field()}}
<div class="sidebar-title">
<span>Advanced Search</span>
<i class="fa fa-caret-down show_sidebar_content" aria-hidden="true"></i>
</div>
<!-- ./sidebar-title -->
<div id="tags-filter-content" class="sidebar-content">
<div class="filter-tag-group">
@foreach($options as $option)
<div class="tag-group">
<p class="title">
<span class="filter-title show_filter_content">{{$option->title}} <span class="pull-right"><i class="fa fa-minus"></i></span></span>
</p>
<div class="filter-content">
<div class="checkbox">
@foreach($option->suboptions as $suboption)
<label for="suboptions">
<input name="suboptions[]" type="checkbox" value="{{$suboption->id}}">
{{ucfirst($suboption->title)}}
</label>
@endforeach
</div>
</div>
</div>
@endforeach
<!-- ./tag-group -->
<div class="tag-group">
<p class="title">
<span class="filter-title show_filter_content">Brand <span class="pull-right"><i class="fa fa-minus"></i></span></span>
</p>
<div class="filter-content">
<div class="checkbox">
@foreach($brands as $brand)
<label for="brands">
<input name="brands[]" type="checkbox" value="{{$brand->id}}">
{{$brand->title}}
</label>
@endforeach
</div>
</div>
</div>
<!-- ./tag-group -->
<div class="tag-group">
<p class="title">
<span class="filter-title show_filter_content">Price Range <span class="pull-right"><i class="fa fa-minus"></i></span></span>
</p>
<div class="row filter-content">
<div class="col-md-6">
<div class="form-group">
<label for="min_price" hidden>Min</label>
<input type="text" name="min_price" class="form-control" placeholder="Rp Min">
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label for="max_price" hidden>Max</label>
<input type="text" name="max_price" class="form-control" placeholder="Rp Max">
</div>
</div>
</div>
</div>
<!-- tag-group -->
<div class="text-center mt-20">
<button type="submit" class="btn btn-danger">TERPAKAN</button>
</div>
</div><!-- ./filter-tag-group -->
</div><!-- ./sidebar-content -->
</form>
and this is my route:
Route::post('/advanced-search', 'frontend\SearchController@filter')->name('advancesearch');
finally my function code is:
public function advancedsearch(Request $request) {
$brands = Brand::all(); // uses for other part of the page. (not related to search function)
$options = Option::all(); // uses for other part of the page. (not related to search function)
$suboptions = DB::table('product_suboption'); // where my product_id and subopyion_id saves
//search function
$products = Product::where(function($query){
//getting inputs
$suboptions2 = Input::has('suboptions') ? Input::get('suboptions') : [];
$min_price = Input::has('min_price') ? Input::get('min_price') : null;
$max_price = Input::has('max_price') ? Input::get('max_price') : null;
$brands2 = Input::has('brands') ? Input::get('brands') : [];
//returning results
$query->where('price','>=',$min_price)
->where('price','<=',$max_price);
})->get();
return view('front.advancesearch', compact('products', 'brands', 'options'));
}
My models relations:
product
model:
public function options(){
return $this->belongsToMany(Option::class);
}
public function suboptions(){
return $this->belongsToMany(Suboption::class, 'product_suboption', 'product_id', 'suboption_id');
}
public function brand(){
return $this->belongsTo(Brand::class);
}
Option
model:
public function suboptions(){
return $this->hasMany(Suboption::class, 'option_id');
}
public function products(){
return $this->belongsToMany(Product::class);
}
Suboption
model:
public function option(){
return $this->belongsTo(Option::class, 'option_id');
}
public function products(){
return $this->belongsToMany(Product::class);
}
Brand
model:
public function products(){
return $this->hasMany(Product::class);
}
note
My brands
search is coming from products table where I have column brand_id
for each product.
BUT
My suboptions
come from 3rd table named product_suboption
(as you see in my models codes) where i save product_id
and suboption_id
.
SOLVED
After weeks of playing with codes finally I came to the right results for myself (in my case it works this way for others maybe works with other suggested answers)
Special thanks to Ravindra Bhanderi for his
count($request['']
suggestion.Here's how I'd do it. Note the use of
when
for simplifying optional where conditions (no need to set variables either), and the closure for constraining both thewhereHas
and thewith
(if you want to eager load the relationships).This is just to give an idea. You can use a multiple
->where()
and eager loading->with()
for your query. Take a look with this query below:Finally, you can filter the products which matches the
specifications
, - theproduct
with an emptyspecifications
means this product does not match the criteria, therefore we'll have to remove it from the collection.I suggest tu use each separeted and its help you to feature easaly manupulate code
as your typical condition your sub_option come from third table last relation ship is used.
for min price max price i assume your price in procuct table
for brand as you say brand_id column in product table then
You can use laravel
orWhere
andorWhereHas
to get results separately and all at once, let's say you do not selectmin_price
andmax_price
but you have selectedbrand
then all products with this brnad should be return, your query will look like this$products
will have products collection If any of the condition stated in above query matched.Hope this helps.
This is the method I use to search using laravel eloquent with multiple input:
The method above will return all products if no input is submitted, and will filter the result based on the input if available, on top of this it's also a good practice to sanitize your inputs with validations before proceeding with the query