<p>One method is to build your params before performing the search.</p>

<pre class="lang-twig prettyprint-override"><code>{# set base params #}
{% set params = {
    section: 'portfolio',
    limit: null
} %}
{% set relatedParams = ['and'] %}

{# status #}
{% if craft.request.getParam('status') %}
    {% set status = craft.request.getParam('status') %}
    {% set params = params|merge({'companyStatus':status}) %}
{% endif %}

{# industry #}
{% if craft.request.getParam('industry') %}
    {% set category = craft.categories.group('industries').slug(craft.request.getParam('industry')).first %}
    {% set relatedParams = relatedParams|merge([{ targetElement:category }]) %}
{% endif %}

{# board member #}
{% if craft.request.getParam('boardMember') %}
    {% set boardMember = craft.entries.section('team').slug(craft.request.getParam('boardMember')).first %}
    {% set relatedParams = relatedParams|merge([{ targetElement:boardMember }]) %}
{% endif %}

{# add relatedParams to params #}
{% if relatedParams|length &gt; 1 %}
    {% set params = params|merge({'relatedTo':relatedParams}) %}
{% endif %}

{# perform search #}
{% set searchParams = craft.request.getParam('q') %}
{% set entries = craft.entries(params).search(searchParams|trim) %}

{# display results #}
{% for entry in entries %}
    {{ entry.title }}
    ...
{% endfor %}
</code></pre>

<p>To AJAX load results you would place this in another template and load it dynamically with jquery. See <a href="https://craftcms.stackexchange.com/questions/4414/search-contact-person-plugin-via-ajax/4415#4415">this answer</a> for an example.</p>

<p>To paginate the results you will need to submit your form as "GET" and append the query to your nextPage and prevPage links. See <a href="https://craftcms.stackexchange.com/questions/6655/search-results-pagination-with-multiple-form-fields">this answer</a> for an example.</p>

CC BY-SA 3.0
2015-02-03T08:20:12.130Z
You should avoid passing a single `['and']` to the `relatedTo` param (→ ["Users relatedTo multiple categories"](http://craftcms.stackexchange.com/q/5107/125)).
carlcs
CC BY-SA 3.0
2015-02-03T17:06:09.157Z
@DouglasMcDonald appreciate the response. This method definitely makes sense to me. Unfortunately it's throwing a template error at: `{% set params = params|merge(['status':status]) %}` and `{% set params = params|merge(['relatedTo':relatedParams]) %}`

**"An array element must be followed by a comma. Unexpected token "punctuation" of value ":" ("punctuation" expected with value ",")"**

A comma there doesn't make sense to me. I also tried it for the hell of it and the search doesn't work with commas there. So I'm not sure what I should do to fix the template error.
zackspear
CC BY-SA 3.0
2015-02-03T18:55:18.153Z
Try `{% set params = params|merge({'relatedTo':relatedParams}) %}`. I'll update the answer.
Douglas McDonald
CC BY-SA 3.0
2015-02-03T23:03:54.917Z
Awesome, that fixed the template error. The only thing not working now is the status param. It doesn't throw an error or anything it just doesn't filter anything. Seeing if I can fix it. I'll update this comment if I get it.
zackspear
CC BY-SA 3.0
2015-02-03T23:12:37.300Z
I think that the reason 'status' is not working is that there is a craft parameter called [status](http://buildwithcraft.com/docs/templating/craft.entries#status). Possible values are 'live', 'pending', 'expired', 'disabled', and null. You may need to rename that variable.
Douglas McDonald
CC BY-SA 3.0
2015-02-04T16:26:28.157Z
That definitely seems have have been it. I've changed it to `companyStatus` and all it working correctly. I was also able to modify this to work with AJAX based off the links you provided. Thanks for all the help Doug!
zackspear
CC BY-SA 3.0
2015-02-05T02:38:58.420Z
Great! Glad you got it working.
Douglas McDonald
CC BY-SA 3.0
2015-02-03T01:52:25.827Z
2017-11-08T04:18:15.510Z
2017-11-08T04:18:15.510Z
Douglas McDonald
<p>I'll do my best to explain this.</p>

<p>I have a Portfolio of companies, which I have as a structure, that I need to be able to filter/search through by using up to four different parameters.</p>

<ol>
<li><strong>Keyword</strong> - a basic search field that a user can type into</li>
<li><strong>Industry</strong> - a category field</li>
<li><strong>Company Status</strong> - a dropdown field</li>
<li><strong>Board Members</strong> - a relation to a different structure</li>
</ol>

<p>I know how to search these individually but I'm not quite sure how to use any combo of these all at once. Whether that be using a keyword and industry to search, all four items to search, maybe just by industry and board members, or maybe just by industry.</p>

<p>Below is what I have so far. Hoping someone will be able to point me in the right direction or help me piece this together.</p>

<p><strong>This handles the search</strong></p>

<pre class="lang-html prettyprint-override"><code>{# What is being searched #}
{% set portfolio = craft.entries.section('portfolio') %}

{# Potential Query Strings #}
{% set query = craft.request.getParam('q') %}
{% set industryParam = craft.request.getParam('industry') %}
{% set statusParam = craft.request.getParam('status') %}
{% set boardMemberParam = craft.request.getParam('boardMember') %}

{# Related to Industry and/or Board Member #}
{% set industry = craft.categories.group('industries').slug(industryParam).first %}

{# Here's where I'm not sure how to combine the relatedTo for the industry, status, and/or board members #}
{% set relationParam = industryParam ? {targetElement: industry} : '' %}

{% set entries = portfolio.relatedTo(relationParam).search(query) %}

{# Probably best to not use search, as it's slower than relatedTo, so I commented this out. #}
{# .search('companyStatus::"' ~ statusParam ~ '"') #}

{# Spit out the entries #}
{% if entries|length %}

  {% for entry in entries %}
    &lt;article class="portfolio-item grid-3"&gt;
      &lt;a class="portfolio-item-content" href="{{ entry.url }}"&gt;
        &lt;h3 class="portfolio-item-title"&gt;{{ entry.title }}&lt;/h3&gt;
      &lt;/a&gt;
    &lt;/article&gt;
  {% endfor %}

{% else %} {# If nothing matches the search criteria #}

  &lt;p&gt;Sorry, no results.&lt;/p&gt;

{% endif %}
</code></pre>

<p><strong>Stripped down version of where the user sets the parameters</strong></p>

<pre class="lang-html prettyprint-override"><code>&lt;form action="{{ url('portfolio') }}"&gt;
  &lt;h3 class="sidebar-title"&gt;Filter by Keyword&lt;/h3&gt;
  &lt;input type="search" name="q" placeholder="Search"&gt;

  &lt;h3 class="sidebar-title"&gt;Filter by Industry&lt;/h3&gt;
  &lt;select class="fancy" name="industry"&gt;
    &lt;option value=""&gt;All Industries&lt;/option&gt;

    {# Only get categories that are being used. #}
    {# This will definitely need some cache tags. #}
    {% set categories = craft.categories.group('industries').order('title asc') %}
    {% set entriesWithCategories = craft.entries.relatedTo(categories) %}
    {% set categoriesInUse = craft.categories.relatedTo(entriesWithCategories) %}

    {% for category in categoriesInUse %}
      &lt;option value="{{ category.slug }}"&gt;{{ category.title }}&lt;/option&gt;
    {% endfor %}
  &lt;/select&gt;

  &lt;h3 class="sidebar-title"&gt;Filter by Status&lt;/h3&gt;
  &lt;select class="fancy" name="status"&gt;
    &lt;option value=""&gt;All Statuses&lt;/option&gt;
    &lt;option value="active"&gt;Active&lt;/option&gt;
    &lt;option value="past"&gt;Past&lt;/option&gt;
  &lt;/select&gt;

  &lt;h3 class="sidebar-title"&gt;Filter by Board Member&lt;/h3&gt;
  &lt;select class="fancy" name="boardMember"&gt;
    &lt;option value=""&gt;All Board Memebers&lt;/option&gt;
    {% set team = craft.entries.section('team') %}
    {% for member in team %}
      &lt;option value="{{ member.slug }}"&gt;{{ member.title }}&lt;/option&gt;
    {% endfor %}
  &lt;/select&gt;

  &lt;input type="submit" value="Go"&gt;
&lt;/form&gt;
</code></pre>

<p>And if possible, how would I do this with AJAX? This can come later, initial search function is 100% okay. I know I could do the the AJAX filter completely on the Front-End but there's potential that the client will want to eventually add pagination if they start adding a bunch of companies to their portfolio.</p>

<p>Thanks in advance.</p>

CC BY-SA 3.0
2015-02-03T00:55:24.353Z
Hey Zack - I'll take a look at the search in a bit, but as for the AJAX, you'll be able to do that using Routes and the built in [pagination](http://buildwithcraft.com/docs/templating/paginate) template tag. Separate that into a new question once this one is resolved to give it some room to be answered :)
Aaron Berkowitz
CC BY-SA 3.0
2015-02-03T01:41:26.533Z
Awesome, thanks @aberkie. And separating the AJAX is definitely a good idea. I'll see if I can take a shot at it once the "basic" search is taken care of. Looking forward to seeing what you come up with.
zackspear
<relations><search><ajax>
Searching a specific section by four different types of parameters?
# Searching a specific section by four different types of parameters?

(Asked by: username_0 on 2015-02-02)

I'll do my best to explain this.
I have a Portfolio of companies, which I have as a structure, that I need to be able to filter/search through by using up to four different parameters.

Keyword - a basic search field that a user can type into
Industry - a category field
Company Status - a dropdown field
Board Members - a relation to a different structure

I know how to search these individually but I'm not quite sure how to use any combo of these all at once. Whether that be using a keyword and industry to search, all four items to search, maybe just by industry and board members, or maybe just by industry.
Below is what I have so far. Hoping someone will be able to point me in the right direction or help me piece this together.
This handles the search
{# What is being searched #}
{% set portfolio = craft.entries.section('portfolio') %}

{# Potential Query Strings #}
{% set query = craft.request.getParam('q') %}
{% set industryParam = craft.request.getParam('industry') %}
{% set statusParam = craft.request.getParam('status') %}
{% set boardMemberParam = craft.request.getParam('boardMember') %}

{# Related to Industry and/or Board Member #}
{% set industry = craft.categories.group('industries').slug(industryParam).first %}

{# Here's where I'm not sure how to combine the relatedTo for the industry, status, and/or board members #}
{% set relationParam = industryParam ? {targetElement: industry} : '' %}

{% set entries = portfolio.relatedTo(relationParam).search(query) %}

{# Probably best to not use search, as it's slower than relatedTo, so I commented this out. #}
{# .search('companyStatus::"' ~ statusParam ~ '"') #}

{# Spit out the entries #}
{% if entries|length %}

  {% for entry in entries %}
    
      
        {{ entry.title }}
      
    
  {% endfor %}

{% else %} {# If nothing matches the search criteria #}

  Sorry, no results.

{% endif %}

Stripped down version of where the user sets the parameters

  Filter by Keyword
  

  Filter by Industry
  
    All Industries

    {# Only get categories that are being used. #}
    {# This will definitely need some cache tags. #}
    {% set categories = craft.categories.group('industries').order('title asc') %}
    {% set entriesWithCategories = craft.entries.relatedTo(categories) %}
    {% set categoriesInUse = craft.categories.relatedTo(entriesWithCategories) %}

    {% for category in categoriesInUse %}
      {{ category.title }}
    {% endfor %}
  

  Filter by Status
  
    All Statuses
    Active
    Past
  

  Filter by Board Member
  
    All Board Memebers
    {% set team = craft.entries.section('team') %}
    {% for member in team %}
      {{ member.title }}
    {% endfor %}
  

  


And if possible, how would I do this with AJAX? This can come later, initial search function is 100% okay. I know I could do the the AJAX filter completely on the Front-End but there's potential that the client will want to eventually add pagination if they start adding a bunch of companies to their portfolio.
Thanks in advance.

**Tags:** relations, search, ajax

> **Comments:**
> **username_1**: Hey Zack - I'll take a look at the search in a bit, but as for the AJAX, you'll be able to do that using Routes and the built in [pagination](http://buildwithcraft.com/docs/templating/paginate) template tag. Separate that into a new question once this one is resolved to give it some room to be answered :)  
> **username_0**: Awesome, thanks @aberkie. And separating the AJAX is definitely a good idea. I'll see if I can take a shot at it once the "basic" search is taken care of. Looking forward to seeing what you come up with.  

---

## 1 answers

### Answer by username_2 on 2015-02-03. Score: 8 | Accepted answer

One method is to build your params before performing the search.
{# set base params #}
{% set params = {
    section: 'portfolio',
    limit: null
} %}
{% set relatedParams = ['and'] %}

{# status #}
{% if craft.request.getParam('status') %}
    {% set status = craft.request.getParam('status') %}
    {% set params = params|merge({'companyStatus':status}) %}
{% endif %}

{# industry #}
{% if craft.request.getParam('industry') %}
    {% set category = craft.categories.group('industries').slug(craft.request.getParam('industry')).first %}
    {% set relatedParams = relatedParams|merge([{ targetElement:category }]) %}
{% endif %}

{# board member #}
{% if craft.request.getParam('boardMember') %}
    {% set boardMember = craft.entries.section('team').slug(craft.request.getParam('boardMember')).first %}
    {% set relatedParams = relatedParams|merge([{ targetElement:boardMember }]) %}
{% endif %}

{# add relatedParams to params #}
{% if relatedParams|length > 1 %}
    {% set params = params|merge({'relatedTo':relatedParams}) %}
{% endif %}

{# perform search #}
{% set searchParams = craft.request.getParam('q') %}
{% set entries = craft.entries(params).search(searchParams|trim) %}

{# display results #}
{% for entry in entries %}
    {{ entry.title }}
    ...
{% endfor %}

To AJAX load results you would place this in another template and load it dynamically with jquery. See this answer for an example.
To paginate the results you will need to submit your form as "GET" and append the query to your nextPage and prevPage links. See this answer for an example.

> **Comments:**
> **username_3**: You should avoid passing a single `['and']` to the `relatedTo` param (→ ["Users relatedTo multiple categories"](http://craftcms.stackexchange.com/q/5107/125)).  
> **username_0**: @DouglasMcDonald appreciate the response. This method definitely makes sense to me. Unfortunately it's throwing a template error at: `{% set params = params|merge(['status':status]) %}` and `{% set params = params|merge(['relatedTo':relatedParams]) %}`  **"An array element must be followed by a comma. Unexpected token "punctuation" of value ":" ("punctuation" expected with value ",")"**  A comma there doesn't make sense to me. I also tried it for the hell of it and the search doesn't work with commas there. So I'm not sure what I should do to fix the template error.  
> **username_2**: Try `{% set params = params|merge({'relatedTo':relatedParams}) %}`. I'll update the answer.  
> **username_0**: Awesome, that fixed the template error. The only thing not working now is the status param. It doesn't throw an error or anything it just doesn't filter anything. Seeing if I can fix it. I'll update this comment if I get it.  
> **username_2**: I think that the reason 'status' is not working is that there is a craft parameter called [status](http://buildwithcraft.com/docs/templating/craft.entries#status). Possible values are 'live', 'pending', 'expired', 'disabled', and null. You may need to rename that variable.  
> **username_0**: That definitely seems have have been it. I've changed it to `companyStatus` and all it working correctly. I was also able to modify this to work with AJAX based off the links you provided. Thanks for all the help Doug!  
> **username_2**: Great! Glad you got it working.  

---

