# Create a filter

Combining [Query node](/app-builder/app-construction/query.md) and [Interactions](/app-builder/app-construction/interactions.md), you can allow users to filter data based on their input. This tutorial will show you how to use Form to collect user's input, use interaction to set SQL parameters in query nodes and filter a table.

Examples in this tutorial will reference table `company_daily_stock_price` containing stock information, you'll find the table in the sample Postgres database.

<figure><img src="/files/de9guD9YAoZ1g4JvKTBo" alt=""><figcaption><p>company_daily_stock_price</p></figcaption></figure>

## Setting up your query node

In order to use user inputs to change SQL parameters to filter your data, you'll need to add parameters to your node. The syntax to add parameters varies slightly based on the type of data node you are using. See [Query](/app-builder/app-construction/query.md) for syntax details and more information on parameters.

Consider the data type output by the element triggering the filter. For example, a [Switch](/app-builder/app-construction/elements/form-elements/switch.md) element produces a boolean value, or a [Multiselect](/app-builder/app-construction/elements/form-elements/multiselect.md) produces an array. When initializing parameters, you'll want the initialized value to be of the same data type.

When building your query, you'll also want to make sure that the data type of the parameter matches the column that it's filtering. Your statement should handle any necessary type casting or additional processing.

The following examples are all queries made in PostgreSQL query nodes. To create such a query node, locate the `company_daily_stock_price` in table node list and create a query node from it.

<figure><img src="/files/QmjwfFj2g2nADistYfmC" alt=""><figcaption><p>Create the query node from <code>company_daily_stock_price</code> table node</p></figcaption></figure>

### Example: Numerical and string inputs

This example shows how to deal with numerical and string columns.

It will pull all records where `total_volume` is greater than or equal to the user's input for `min_volume`, and where `exchange_short` matches what the user selects. The query was built and parameters were initialized so all data is shown before the user selects any filters.&#x20;

<figure><img src="/files/0Q4qWqErWRwClfZruW0K" alt=""><figcaption></figcaption></figure>

Query:

```sql
SELECT ticker, company_name, exchange_short, volume, close, change 
FROM company_daily_stock_price
WHERE volume >= {{min_volume}}
AND exchange_short LIKE CONCAT('%','{{exchange}}','%');
```

Parameter initialization (See how to set parameter in [/pages/uHfRIhYYIjWrmxqZdTNt#1.-add-new-parameter](https://docs.acho.io/app-builder/popular-use-cases/pages/uHfRIhYYIjWrmxqZdTNt#1.-add-new-parameter "mention")):

```sql
{
  "min_volume": 0,
  "exchange": ""
}
```

The parameter `min_volume` is initialized to `0`, a numerical value that can be compared against the column `total_volume`. `exchange` is initialized as an empty string, and in the query, turned into a [Regex](https://dataschool.com/how-to-teach-people-sql/how-regex-works-in-sql/) expression using the `CONCAT()` function. This allows all records to be pulled when the string is empty, and will match specific values when the parameter value is changed.

### Example: Array input

Some form elements output arrays. For example, let's say we plan on having a [Multiselect](/app-builder/app-construction/elements/form-elements/multiselect.md) input element where I allow users to choose which ticker values they'd like to see data for, and display all rows where the ticker matches.

<figure><img src="/files/i6uZF2I2v7cfYsmJsgOI" alt=""><figcaption></figcaption></figure>

Query:

```sql
{% set comma = joiner() %}

SELECT ticker, company_name, exchange_short,  volume, close, change 
FROM company_daily_stock_price
WHERE 

{% if ticker_list | length > 0%} 
ticker IN ({% for ticker_item in ticker_list %}{{ comma() }} '{{ticker_item}}' {% endfor %}) 
{% else %} TRUE
{% endif %};
```

Parameter initialization:

```sql
{
  "ticker_list": [],
  "ticker_item": ""
}
```

This example shows how you can pull all records for the tickers that the user has selected. In this statement, if `ticker_list` is not empty, we use a for loop to reconstruct the array in the right format and check if `ticker` appears in it. If the array is empty, all records will be displayed.

## Create your elements for filtering

A common way to create a filter is to insert [Form Elements](/app-builder/app-construction/elements/form-elements.md) into a [Custom Form](/app-builder/app-construction/elements/form-elements/custom-form.md). The form can then collect the inputs and use them to change your SQL parameters.

Following from the data node examples above, we've created a form, which contains an [Input](/app-builder/app-construction/elements/form-elements/input.md) element to collect the minimum total volume, a [Radio Button](/app-builder/app-construction/elements/form-elements/radio-button.md) to select an exchange, and a [Multiselect](/app-builder/app-construction/elements/form-elements/multiselect.md) to select tickers.

![](/files/EMijA6hPS1jM5lInuMrF)

Each form element has a form item name, which is the name that the form will use to access the user input. They're also configured based on the specifications in our query.

* **Minimum volume:** The `total_volume` column is numerical, so we'll want to process the input as a number.\
  ![](/files/Kj4fiV8svK9yLZzU3Sni)
* **Exchange:** Recall that in our query, we display all records when the `exchange` parameter is an empty string. So when a user selects the "All" option, the value we're changing the parameter to is empty.\
  ![](/files/F1F08fcJjvxHUvWJPA0U)
* **Tickers:** Add ticker values for the user to choose from. Either enter the value:label pairs into  the input boxes, or click on `</>` under Options to use an accessor to an array of objects with `"label"` and `"value"` keys.\
  ![](/files/Z39w1bX2HH9Zpo3mEX3f)

## Create the interaction to change SQL parameters

Once the form elements and data node have been set up, the last step is to create the interactions that will change the SQL parameters.

### What the form will do when it's submitted

Add interactions to change SQL parameters on the form element when it is submitted.&#x20;

Add a Submit event block to the form, and create an action. Select API Service -> Set SQL Parameter. Make sure you're setting parameters under the right data node.

Access the user inputs from the event payload using `${event.form.min_volume}` and `${event.form.exchange}`.

<figure><img src="/files/nLiGtjc5nBPzPw5F2qBv" alt=""><figcaption></figcaption></figure>

Similarly, the interaction to filter tickers can be accessed with `${event.form.ticker_list}`.

<figure><img src="/files/LWNkmAbxhozyT3q6oHLr" alt=""><figcaption></figcaption></figure>

### Submitting the form

We've set up the interactions to change SQL parameters upon submission of the form. However, we still need to create a way to submit the form.

On an element, such as a button, set up an interaction to submit the form.

<figure><img src="/files/S1bfFkAy9MCu13wavJ9R" alt=""><figcaption></figcaption></figure>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.acho.io/app-builder/popular-use-cases/create-a-filter.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
