1
votes

Goodmorning

I'm trying to make a filter with multiple variables for example I want to filter my products on category (for example 'fruit') and then I want to filter on tag (for example 'sale') so as a result I get all my fruits that are on sale. I managed to write seperate filters in laravel for both category and tag, but if I leave them both active in my productsController they go against eachother. I think I have to write one function with if/else-statement but I don't know where to start. Can somebody help me with this please?

These are my functions in my productsController:

 public function productsPerTag($id){
    $tags = Tag::all();
    $products = Product::with(['category','tag','photo'])->where(['tag_id','category_id'] ,'=', $id)->get();
    return view('admin.products.index',compact('products','tags'));
}
public function productsPerCategory($id){ 
    $categories = Category::all(); //om het speciefieke id op te vangen heb ik alle categories nodig
    $products = Product::with(['category','tag','photo'])->where('category_id', '=', $id)->get(); 
    return view('admin.products.index',compact('products','categories'));
}

These are my routes in web.php. I guess this will also have to change:

Route::get('admin/products/tag/{id}','AdminProductsController@productsPerTag')->name('admin.productsPerTag');

Route::get('admin/products/category/{id}','AdminProductsController@productsPerCategory')->name('admin.productsPerCategory');

3
is your $id is same for both tag_id and category_id ??void

3 Answers

1
votes

For filter both

change your URL like

    Route::get('admin/products/tag/{tag_id?}/{category_id?}','AdminProductsController@productsPerTag')->name('admin.productsPerTag');

Make your function into the controller like

 public function productsPerTag($tagId = null, $categoryId = null){
    $tags = Tag::all();
    $categories = Category::all();

    $query = Product::with(['category','tag','photo']);
    if ($tagId) {
        $query->where(['tag_id'] ,'=', $tagId);
    }
    if ($tagId) {
        $query->where(['category_id'] ,'=', $categoryId);
    }
    $products = $query->get();

    return view('admin.products.index',compact('products','tags', 'categories'));
}
0
votes

You are trying to filter in your query but you pass only 1 parameter to your controller, which is not working.

1) You need to add your filters as query params in the URL, so your url will look like:

admin/products/tag/1?category_id=2

Query parameters are NOT to be put in the web.php. You use them like above when you use the URL and are optional.

2) Change your controller to accept filters:

public function productsPerTag(Request $request)
{
    $categoryId = $request->input('category_id', '');
    $tags = Tag::all();
    $products = Product::with(['category', 'tag', 'photo'])
        ->where('tag_id', '=', $request->route()->parameter('id'))
        ->when((! empty($categoryId)), function (Builder $q) use ($categoryId) {
            return $q->where('category_id', '=', $categoryId);
        })
        ->get();

    return view('admin.products.index', compact('products', 'tags'));
}

Keep in mind that while {id} is a $request->route()->parameter('id')

the query parameters are handled as $request->input('category_id') to retrieve them in controller.

0
votes

Hope It will give you all you expected outcome if any modification needed let me know:

public function productList($tag_id = null , $category_id = null){
    $tags = Tag::all();
    $categories = Category::all();
    if($tag_id && $category_id) {
        $products = Product::with(['category','tag','photo'])
                           ->where('tag_id' , $tag_id)
                           ->where('category_id' , $category_id)
                           ->get();
    } elseif($tag_id && !$category_id) {
        $products = Product::with(['category','tag','photo'])
                           ->where('tag_id' , $tag_id)
                           ->get();
    } elseif($category_id && !$tag_id) {
        $products = Product::with(['category','tag','photo'])
                           ->where('category_id' , $category_id)
                           ->get();

    } elseif(!$category_id && !$tag_id) {
        $products = Product::with(['category','tag','photo'])
                           ->get();
    }
    return view('admin.products.index',compact(['products','tags','products']));
}

Route:

Route::get('admin/products/tag/{tag_id?}/{category_id?}','AdminProductsController@productsPerTag')->name('admin.productsPerTag');