D. 777KLM
D. 777KLM

Reputation: 470

Laravel - AJAX Search allow Multiple Filters to be applied

I have a controller that works on an AJAX jQuery call when I need to search/filter the database:

$launchsitesatellite = DB::table('satellites')
->where(function($q) use ($request) {
    if(empty($request->type) && empty($request->rocket_type)) {
        $q->orWhere('satname','LIKE','%'.$request->search.'%')
            ->orWhere('norad_cat_id','LIKE','%'.$request->search.'%')
            ->orWhere('country','LIKE','%'.$request->search.'%')
            ->orWhere('object_id','LIKE','%'.$request->search.'%');
    } else {
        if(!empty($request->type)) {
            $q->orWhere($request->type,'LIKE','%'.$request->search.'%');
        }
        if(!empty($request->object_type)) {
            $q->orWhere('object_type','LIKE','%'.$request->object_type.'%');
        }
        if(!empty($request->launch_year)) {
            $q->orWhere('launch','LIKE','%'.$request->launch_year.'%');
        }
    }
})
->where('site', $site_code)->Paginate(300);

This controller can search/filter my database with no problem. The only thing I would like to fix is to allow multiple filters to be applied. For example, currently when I filter by Object Type and then decide to filter by Country, it resets the Object Type.

What I want to be able to do is to allow it to filter by Object Type AND Country, not only one.

There was a lack of examples/documentation so I could not find any examples of how this is done.

EDIT: JS AJAX Call

$("#filter-type").change(function() {
$value=$(this).val();
  $.ajax({
    type: "get",
    url: "{{$launchsitename->site_code}}",
    data: {'search':$value, type:'object_type'},
    success: function(data){
      $('#launchsatdisplay').html(data);
    }
});
});

Upvotes: 0

Views: 5949

Answers (1)

Rwd
Rwd

Reputation: 35190

I think the reason you're having this issue is because you're using orWhere rather than where so in theory the more filters you use the more results you will have returned (rather than limiting the results).

$launchsitesatellite = DB::table('satellites')
    ->where(function ($q) use ($request) {

        if (!$request->has('type') && !$request->has('rocket_type')) {
            $q->orWhere('satname', 'LIKE', '%' . $request->search . '%')
                ->orWhere('norad_cat_id', 'LIKE', '%' . $request->search . '%')
                ->orWhere('country', 'LIKE', '%' . $request->search . '%')
                ->orWhere('object_id', 'LIKE', '%' . $request->search . '%');
        } else {
            if ($request->has('type')) {
                $q->where($request->type, 'LIKE', '%' . $request->search . '%');
            }
            if ($request->has('object_type')) {
                $q->where('object_type', 'LIKE', '%' . $request->object_type . '%');
            }
            if ($request->has('launch_year')) {
                $q->where('launch', 'LIKE', '%' . $request->launch_year . '%');
            }
        }
    })
    ->where('site', $site_code)
    ->Paginate(300);

Also, just FYI, Laravel Query Builder comes with a when() method which is an alternative to using multiple if statements. So the main else section would look like:

$q
    ->when($request->has('type'), function ($q) use ($request) {
        $q->where($request->type, 'LIKE', '%' . $request->search . '%');
    })
    ->when($request->has('object_type'), function ($q) use ($request) {
        $q->where('object_type', 'LIKE', '%' . $request->object_type . '%');
    })
    ->when($request->has('launch_year'), function ($q) use ($request) {
        $q->where('launch', 'LIKE', '%' . $request->launch_year . '%');
    });

Obviously, you don't have to do this though (I just thought I'd mention it).

Hope this helps!

Upvotes: 2

Related Questions