enso-ui/filters

Drill down filters / Filter dependncies

robbykrlos opened this issue · 6 comments

This is a feature request.

Prerequisites

  • Are you running the latest version?
  • Did you perform a cursory search?
  • Did you check the documentation?
  • Are you reporting to the correct repository?
    (enso is made of many specialized packages: https://github.com/laravel-enso)

Description

I'm looking for a way to make one select-filter dependent on another selection (eg. Country and City). Is there a ways to achieve this out of the box? I checked documentation and seems not to be an easy way.

Another idea I had is to trigger the reloading of the second filter (eg. City) based on some current filter selection (eg. Country) and send that further to the Http/Controllers/Model/Options controller.

If not considered for a feature-request any other ideas will be much appreciated.

Thank you,

Hi @robbykrlos ,

If I correctly understand your question, this is something already possible.

The vue-select/enso-select/select-filter/enso-select-filter support a params property that, when present, is used to further filter out the available options.

So, what you need to do is

  • have a v-model on the first (master) select.
  • then, create a computed params value for the second select, using the master select's currently selected value.
  • on the second select (slave), pass the computed value to the params property

Rough pseudo-code

<enso-select-filter
     source="administration.companies.options"
     v-model="manufacturer"/>

<enso-select-filter
    source="products.options"
    :params="manufacturerParams"
     v-model="product"/>
....
computed: {
    manufacturerParams() {
        return { manufacturer_id: this.manufacturer }
   }
}

Let me know if you've figured it out, and if not, please also paste your code

Thank you, will try it out today.

Hi @gandesc ,

Works like a charm. Didn't know about this thing - I see now that the where condition is altered when using the :params and the parent/master id is injected in there. I didn't check but will this work for many-to-many tables as well? or only one-to-many?

Also, if I need to complicate things, is there an option to merge the conditions from 2 sets of parent/master options ? Ex.:

<enso-select-filter
     source="administration.companies.options"
     v-model="manufacturer"/>

<enso-select-filter
    source="madeInCountries.options"
     v-model="madeInCountry"/>

<enso-select-filter
    source="products.options"
    :params="manufacturerAndCountryParams"
     v-model="product"/>

....
computed: {
    manufacturerAndCountryParams() {
        return { 
                     manufacturer_id: this.manufacturer.
                     made_in_country_id: this.madeInCountry.
                    }
   }
}

At the moment the example above only applies the last condition applied by recently changed master filter. Later Edit : correction - I had defined only one filter for product :manufacturer_id. If i add both filters, the product slave filter will not populate again...
This is just a question, not a feature request anymore. My initial question was answered - I'll close the ticket - thank you for the help.

I guess I have to do some adaptations in the Options controller for the 'slave' model, so that the 2 conditions are merged somehow. I see that OptionsBuilder trait has some magic in that direction...

I'm looking into it.

Works like a charm. Didn't know about this thing - I see now that the where condition is altered when using the :params and the parent/master id is injected in there. I didn't check but will this work for many-to-many tables as well? or only one-to-many?

Answering myself : it should work for many-to-many as well : check this:

vendor/laravel-enso/select/src/Services/Options.php

private function applyPivotParams(): self
    {
        $this->pivotParams()->each(fn ($param, $relation) => $this->query
            ->whereHas($relation, fn ($query) => (new Collection($param))
                ->each(fn ($value, $attribute) => $query
                    ->whereIn($attribute, (array) $value))));

        return $this;
    }

Glad it worked out, we tried to make it as flexible as possible.

If, however, you find a very specific scenario that doesn't work out of the box you can also:

  • use the customParams property as opposed to the automatic params
  • in the Options controller, add the query method, and compose your query using the parameters passed in the request
public function query(Request $request) {
    $myParams = json_decode($request->get('customParams'));
   
    return  Model::where(....);
}

You can also mix the two types of parameters, as in you can use the automatic features as well as customizing the query.