Ajax Frontend Filter Multiple Relations

Dear October Community, i followed the tutorial by Ivan to make a ajax frontend filter. But all i can find is with only one relation and other infos are directly from the Movies / Vehicles entry.
In my filter i try to use multiple relations like categories, manufacturers, locations etc…
i use a scopeListFrontEnd query with options in my Vehicle Model.

public function scopeListFrontEnd($query, $options = []){
        extract(array_merge([
            'page' => 1,
            'perPage' => 999,
            'sort' => 'sort_order',
            'manufacturers' => null,
            'categories' => null,
            'industries' => null,
            'tonnagen' => null,
            'locations' => null,
            'rooffinishes' => null,
        ], $options));

        /*
         * Manufacturers
         */
        if($manufacturers !== null ){

            if(!is_array($manufacturers)){
                $manufacturers = [$manufacturers];
            }

            foreach ($manufacturers as $manufacturer){
                $query->whereHas('manufacturers', function($q) use ($manufacturer){
                    $q->where('slug', '=', $manufacturer);
                });
            }
        }
        

        /*
         * Categories
         */
        if($categories !== null ){

            if(!is_array($categories)){
                $categories = [$categories];
            }

            foreach ($categories as $category){
                $query->whereHas('categories', function($q) use ($category){
                    $q->where('slug', '=', $category);
                });
            }
        }
        /*
         * Tonnagen
         */
        if($tonnagen !== null ){

            if(!is_array($tonnagen)){
                $tonnagen = [$tonnagen];
            }

            foreach ($tonnagen as $tonnage){
                $query->whereHas('tonnagen', function($q) use ($tonnage){
                    $q->where('id', '=', $tonnage);
                });
            }
        }

at the page i Preparevars and Update the form and Partial with the oc.request onchange functions.

function onStart() { $this->prepareVars(); }
function onFilterVehicles() { $this->prepareVars(); }

function prepareVars() {
        $options = post('Filter', []);

        $this['vehicles'] = Vehicle::listFrontEnd($options);
        $this['manufacturers'] = Manufacturer::all();
        $this['vehicletypes'] = VehicleType::all();
        $this['tonnagen'] = Tonnage::all();
        $this['categories'] = Category::all();
        $this['locations'] = Location::all();
        $this['rooffinishes'] = RoofFinish::all();
        $this['industries'] = Branche::all();
        $this['pages'] = $this['vehicles']->lastPage();
    }

and the form looks like:

<form onchange="oc.request('#VehiclesFilter', 'onFilterVehicles', { update: { 'vehicles/vehicles': '#listVehicles' }})">
<div>Many code with dropdown fields that all are displaying the correct database entries of all relations.
<select class="" name="Filter[manufacturers][]">

                            <option value="">{{ 'Choose Manufacturer...'|_ }}</option>
                            {% for manufacturer in manufacturers %}
                            <option value="{{ manufacturer.slug }}">{{ manufacturer.title }}</option>
                            {% endfor %}

                        </select>
...more dropdowns etc. - NO SUBMIT button..
</div>
</form>
<div id="listVehicles">
    {% partial 'vehicles/vehicles' %}
</div>

Actually the filter only works when all Dropdowns are selected but i want to filter step by step to reduce the results shown in the vehicle partial.
For example: When Manufacturer is Chosen all entries with the manufacturer should be displayed.
When only Tonnagen, Categories or Locations is selected all Tonnage or location entries should be displayed.

I think my mistake is in the Vehicle Model query or the prepareVars but cant figure out exactly where the problem is. I hope anyone can help me to get this filter work.

Best regards and thanks for all your hints and help.

Hi @nxt_dominic

Looking at this code, nothing stands out about why this would happen. You are using the onchange event on the form that will fire any time an input changes, including the select. Then inside the filter, only filters are applied when a value is supplied.

One thing you might like to try is changing these

if($manufacturers !== null ){

To this

if($manufacturers){

This means it will not apply the filter for an empty string (“”) which doesn’t pass as null. It’s possible that the inputs are passing an empty string and this might try to filter against it.

I hope this helps.

Hi daftspunky, i already tried that and different things but nothing will work. Also tried it with elseif statements. Still cant figure out where the problem might be. When im back from vacation i will have a look again in these case