3

This is a bit of a complex one, and a bit tricky to explain - but here it goes.

I'm trying to build an advanced filter system for an eCommerce website. Hypothetically, it would look like this (with [ ] symbolising a checkbox)

BRANDS

[ ] Brand 1 [cat id=1]

[ ] Brand 2 [cat id=2]

[ ] Brand 3 [cat id=3]

SIZE

[ ] Small [cat id=4]

[ ] Medium [cat id=5]

[ ] Large [cat id=6]


Currently I have built a prototype using dynamic_parameter that allows me to filter by those categories.

But if I were to check Brand 1, Brand 2 and Small (which would in English mean "Show me small products by either Brand 1 or Brand 2) it of course is still effectively running

category="1&2&4"

Which instead is "Show me all small products by both Brand 1 and Brand 2" - which isn't so useful for filtering purposes.

For this website, combinations within a category group (Brand, Size, among others) should be OR and outside of the groups should be AND.

In a perfect world, this would work...

category="(1|2)&(4)"

So, is there a workaround to this?

Thanks in advanced, it's quite a complex one and I may be completely over complicating this!

4 Answers 4

1

Assuming, that your pulling all your data from one or more channels, have you considered just using Javascript filters, like Isotope. I've linked to the Isotope: Combination Filters Because, they're closer to what you want.

But here's an example of EE with Isotope, on a project still in development, Getting Started Guide: Madisonium. I haven't optimize images or javascript yet, since its still in active development, so it a tad slower than I like, but here's sample code of what I'm doing

The Filters: I'm just using basic filters, not combination, in the true sense. They are combined with categories, but not with other tags.

<!-- BREADCRUMB FILTERS -->

<section id="options" class="clearfix">
    <ul id="filters" class="option-set clearfix breadcrumbs" data-option-key="filter">
        <li><span><b>Filters</b></span></li>
        <li><span><a href="#filter" data-option-value="*" class="selected">show all</a></span></li>
        {exp:tag:cloud limit="6" orderby="total_entries" sort="desc"}
        <li><span><a href="#filter" data-option-value=".{tag}">{tag}</a></span></li>{/exp:tag:cloud}
    </ul>
</section>

<!-- // END BREADCRUMB FILTERS-->

The Entries: The entries are primarily just images with an overlay to provide more info.

<div id="filterable-profiles" class="clearfix">

{exp:channel:entries site="guide" channel="people" limit="30" orderby="title" sort="asc"}

    <div class="clearfix profile four columns{exp:tag:tags entry_id='{entry_id}' limit='5' orderby='total_entries' sort='desc'} {tag}{/exp:tag:tags}">
        <div class="profile-meta">
            <h3><a href="/{profile_type}/profile/{url_title}/">{title}</a></h3>
            <h4><a href="/{profile_type}/profile/{url_title}/">{if profile_position !=""}{profile_position}{/if}{if profile_organization !="" AND profile_position !=""}, {profile_organization}{if:else}{profile_organization}{/if}</a></h4>
            <p>{profile_summary}</p>
        </div>
    <img src="/images/profiles/{profile_image}" alt="{title}" />
    </div>

{/exp:channel:entries}
</div>

The Javascript: This is just straight from Isotope, with minor modifications. Our item selector is our profile class, and the container is id="filterable-profiles". We use CloudFlare as a CDN for client projects, so that's the rocketscript reference you'll see.

<script type="text/rocketscript" data-rocketsrc="http://gettingstartedguide.org/scripts/isotope/jquery.isotope.min.js"></script>
<script type="text/rocketscript">
    $(function(){

      var $container = $('#filterable-profiles');

      $container.isotope({
        itemSelector : '.profile'
      });


      var $optionSets = $('#options .option-set'),
          $optionLinks = $optionSets.find('a');

      $optionLinks.click(function(){
        var $this = $(this);
        // don't proceed if already selected
        if ( $this.hasClass('selected') ) {
          return false;
        }
        var $optionSet = $this.parents('.option-set');
        $optionSet.find('.selected').removeClass('selected');
        $this.addClass('selected');

        // make option object dynamically, i.e. { filter: '.my-filter-class' }
        var options = {},
            key = $optionSet.attr('data-option-key'),
            value = $this.attr('data-option-value');
        // parse 'false' as false boolean
        value = value === 'false' ? false : value;
        options[ key ] = value;
        if ( key === 'layoutMode' && typeof changeLayoutMode === 'function' ) {
          // changes in layout modes need extra logic
          changeLayoutMode( $this, options )
        } else {
          // otherwise, apply new options
          $container.isotope( options );
        }

        return false;
      });


    });
    </script>

Basically though, as long as you can add the categories or other parameters as part of the <div class="brand1 size1 color1"> component, Isotope can filter, singularly or in combination. My example, is the singular. But it would work with combinations as well. No search required.

1
  • I really like this idea and will give it a go when I'm back in the office.
    – Mutual
    Jan 23, 2013 at 19:23
3

If you can't find a solution with existing EE search addons, you could build a plugin to grab the entries that match your criteria.

The plugin could perform a custom query capable of doing the advanced conditionals you need. It could ultimately return a piped list of all the entries that match the category assignments desired:

323|122|321|116|990

You could then use your plugin tag as the entry_id parameter in a standard EE entries tag (with parse="inward" and dynamic="no"):

entry_id="{exp:your_addon:get_filtered_ids}"

or

entry_id="{exp:your_addon:get_filtered_ids categories='1|2&4' channel_id='2'}"

You could pass your category IDs to the plugin as a parameter or maybe even access as POST vars if desired. You would need to parse the strings in a way that makes sense to you in order to get your MySQL WHERE statements setup accurately.

It's not the most elegant solution, and it would add an extra database query, but it could accomplish what you're looking for with a relatively simple plugin.

0

The Dandy Cat module does exactly what you're looking for.

-1

You should try to use Super Search module. Which seems be better for it.

5
  • 1
    Thank you for participating Bhashkar. Can you profile additional info to support your answer? A link to the addon, a link to the tags that might help? In general, it's better to error on the side of more to support your answer.
    – Anna_MediaGirl
    Jan 23, 2013 at 17:10
  • Sorry, I thought you might heard about this old one module developed by Solspace. You can fine full documentation of this this module from here solspace.com/software/detail/super_search Jan 23, 2013 at 17:22
  • Super Search seems interesting but I can't find in the documentation how I could achieve what I describe. Could you provide some further guidance please?
    – Mutual
    Jan 23, 2013 at 18:11
  • Perhaps if I could use category="Brand1+Brand2&&Small" That would work. That'd be "Brand 1 or Brand 2 - AND small". Is that possible?
    – Mutual
    Jan 23, 2013 at 18:18
  • I could be wrong, but I don't think Super Search can currently mix conditionals the way you need. Worth investigating though.
    – Jim Butts
    Jan 24, 2013 at 2:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.