# Filtering in Adalo

Filtering is a powerful feature that allows you to refine and organize data within your app. Whether you're a seasoned app builder or just getting started, understanding filtering concepts will help you tailor your app to meet your specific needs.

### **Key Filtering Concepts:**

**Filter Criteria:** This refers to the rules you set to determine which data should be displayed or hidden. For example, you might want to only display orders placed in the last 30 days or show tasks assigned to a specific team member using a Relationship Property.

**Filter Fields:** These are the Properties in your Collections of data that you can use to filter. For instance, if you're managing a list of products, your filter fields could include product name, price, or category.

**Filter Operators:** Operators are used to define the relationship between the filter criteria and the data. Adalo supports various operators such as equals, not equals, contains, greater than, less than, and many more depending on the Property Type. These operators help you specify how you want to filter your data.

**Logical Operators:** Logical operators are used to combine multiple filter criteria to create complex filtering conditions. Adalo supports **AND** and **OR** operators in Lists.  They allow you to refine your filters further by specifying conditions that must be met simultaneously or independently.

### **Where to Find Filters**

Filters are typically found in List components and components that display whole groups of records such as:

* Lists
* Counts
* Dropdown Component
* Deck Swiper
* Image Swiper
* Calendar
* Chart Kits
* ...and many more!

### Filters <a href="#filters" id="filters"></a>

Filters can be found in most commonly in Lists that show groups of data from your Collections. In the example below, we have a **List of Trips** and the default filter is set to **All Trips.** You can filter further based on the Available Screen Data or Logged in User data by selecting the dropdown.&#x20;

<figure><img src="https://3467607506-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LhGHkPsv15svPIU5I7C%2Fuploads%2FavuyqGBHOZ4fB67h1sNn%2FFilter%20Dropdown.png?alt=media&#x26;token=6e74d7f8-7d8b-45d3-8df8-30d49ab4c7e5" alt="" width="194"><figcaption></figcaption></figure>

### Custom Filters

Custom Filter can be added anywhere you see the **+Add Custom Filter** button. These are used to combine logic and display very specific groups of records using Filter Operators. In the same example as above, we want to only display the **Trips** where the **Travelers (Relationship to Users)** contains the **Logged in User**.&#x20;

<figure><img src="https://3467607506-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LhGHkPsv15svPIU5I7C%2Fuploads%2FSKatKqPL0b89XaVsqe14%2FCustom%20Filter.png?alt=media&#x26;token=d0975179-04d6-4290-907f-d621e9b73a03" alt="" width="193"><figcaption></figcaption></figure>

**Filter Operators:**

Filter Operators are how Adalo determines what records to show. They result in either being true or false. Based on this information, either Adalo should (true) show records based on this operator or it should not (false). Both filters and conditions use operators to determine what do to with records, components, or actions.

Following the *if-then* logic mentioned earlier we can use logical operators within filters and conditions to instruct Adalo that "if this thing is true, then do this other thing".&#x20;

#### Operator Types

{% tabs %}
{% tab title="Text" %}

#### Operators:

* **Is equal to** - This operator is case sensitive and the two pieces of text must match each other *exactly* - even if there is a hidden return or space in the text. This operator is very strict.

  &#x20;<mark style="color:red;">"Day" is equal to "day" = false</mark>      <mark style="color:green;">"Day" is equal to "Day" = true</mark>
* **Is not equal to** - This operator is also case sensitive and determines if the two pieces of text are different from one another - even by a space or return. This operator is very strict. Hint: it's often easier to exclude items that to determine if they match exactly.

  <mark style="color:green;">"Day" is not equal to "day" = true</mark>&#x20;

  <mark style="color:red;">"Day" is not equal to "Day" = false</mark>
* **Contains** - This operator determine if a string of text contains another string of text. This operator is not very strict and not case sensitive, but can sometimes have unintended consequences if multiple records share the same text string. For example, *<test@gmail.com>* and *<gmail@test.com>* both contain "gmail" but they are not the same result. This also makes it great for searching for records in your app.

  <mark style="color:green;">"Day" contains "day" = true</mark>               <mark style="color:green;">"Day" contains "Day"= true</mark>

  &#x20;                          <mark style="color:green;">"Tuesday" contains "Day" = true</mark>
  {% endtab %}

{% tab title="Number" %}

#### Operators:

* **Is equal to** - Determines if two number values are equal to each other. This operator is very strict - down to decimals. Can also handle negative numbers.

  <mark style="color:green;">4 is equal to 4 = true</mark>                                       <mark style="color:red;">4 is equal to 3 = false</mark>
* **Is not equal to** - Determines if two number values are not equal to each other. This operator is very strict - down to decimals. Can also handle negative numbers.

  <mark style="color:red;">4 is not equal to 4 = false</mark>                               <mark style="color:green;">4 is not equal to 3 = true</mark>
* **Is greater than** - Determines if one number value is greater than another. This operator is very strict - down to decimals. Can also handle negative numbers.

  <mark style="color:red;">4 is greater than 4 = false</mark>                              <mark style="color:green;">4 is greater than 3 - true</mark>
* **Is greater than or equal to** - Determines if one number value is greater than OR equal to another. This operator is strict - down to decimals. Can also handle negative numbers.&#x20;

  <mark style="color:green;">4 is greater than or equal to 4 = true</mark>            <mark style="color:green;">4 is greater than or equal to 3 = true</mark>
* **Is less than** - Determines if one number value is less than another. This operator is very strict - down to decimals. Can also handle negative numbers.

  <mark style="color:red;">4 is less than 4 = false</mark>                                   <mark style="color:red;">4 is less than 3 = false</mark>
* **Is less than or equal to** - Determines if one number value is less than OR equal to another. This operator is very strict - down to decimals. Can also handle negative numbers.

  <mark style="color:green;">4 is less than or equal to 4 = true</mark>                 <mark style="color:red;">4 is less than or equal to 3 = false</mark>
* **Is between** - Determines if a number value is between two other number values. The first value provided is included in the range, the second value provided is excluded from the range. The operator is very strict - down to decimals. It can also handle negative numbers.

  <mark style="color:green;">4 is between 4 and 6 = true</mark>                          <mark style="color:red;">6 is between 4 and 6 = false</mark>

  &#x20;                                       <mark style="color:green;">5 is between 4 and 6 = true</mark>
  {% endtab %}

{% tab title="Date" %}
**Operators:**

* **Is after** - Determines if one date property or datetime property occurs after another. You can compare dates and datetimes interchangeably.

  <mark style="color:green;">Aug 12, 1992 4:00PM is after Aug 12, 1980 = true</mark>
* **Is before** - Determines if one date property or datetime property occurs before another. You can compare dates and datetimes interchangeably.

  <mark style="color:red;">Aug 12, 1992 4:00PM is before Aug 12, 1980 = false</mark>
* **Is between** - Determines if one date or datetime property occurs between two other dates or datetimes. The first datetime provided is inclusive, but the second datetime is exclusive. You can compare dates and datetimes interchangeably.

  <mark style="color:green;">Aug 12, 1992 4:00PM is between Aug 12, 1980 and Aug 12, 2021 = true</mark>

  <mark style="color:green;">Aug 12, 1980 4:00PM is between Aug 12, 1980 and Aug 12, 2021 = true</mark>

  <mark style="color:red;">Aug 11, 1980 4:00PM is between Aug 12, 1980 and Aug 12, 2021 = false</mark>
  {% endtab %}

{% tab title="Relationship" %}
The only type of relationship that can be compared with logical operators in Adalo are one-to-many relationships. You cannot compare many records with many other records.

**Operators:**&#x20;

* **Contains** - Determines if a group or collection of records contains a selected record. This operator evaluates the record as a whole instead of just a single property like the others.

  ![](https://3467607506-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LhGHkPsv15svPIU5I7C%2Fuploads%2F9Gb43udTbd4ZIewQboBp%2FScreen%20Shot%202021-10-15%20at%208.44.14%20AM.png?alt=media\&token=bfb78c56-cc44-4ed2-b706-7245b93abc54)
* **Does not contain** - Determines if a group or collection of records does not contain a selected record. This operator evaluates the record as a whole instead of just a single property like the others.

  ![](https://3467607506-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LhGHkPsv15svPIU5I7C%2Fuploads%2FZCb9qiHhftm2sXYp1uTu%2FScreen%20Shot%202021-10-15%20at%208.46.22%20AM.png?alt=media\&token=10797557-0bb8-4ea4-93cd-591b968062d9)
  {% endtab %}

{% tab title="True/False" %}
**Operators:**

* **Is true** - Determines if a true/false property is checked
* **Is false** - Determines if a true/false property is not checked
  {% endtab %}
  {% endtabs %}

#### Logical Operators <a href="#logical-operators" id="logical-operators"></a>

Within filters you have the option to make custom filters be inclusive of each other, or exclusive of each other. For Lists that have multiple custom filters, you can choose whether ***all*** of those filters must be true in order to show records, or you can choose whether ***any*** of the filters are true.&#x20;

{% embed url="<https://youtu.be/lY_ZJgKwyIM>" %}

If you want to display data only when ***all*** criteria are met, you can click on the **+ AND** button. In the example below, we only want to display the **Trips** where the **Travelers (Relationship to Users)** *contains* the **Logged in User , AND** have a **Travel Date** *is after* the **Date** the Logged in User is viewing the List.&#x20;

<figure><img src="https://3467607506-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LhGHkPsv15svPIU5I7C%2Fuploads%2FlrVc7KqxwqOtK3oCrfFK%2FAND%20Filter.png?alt=media&#x26;token=0f930519-5fe7-4d75-9f11-55383c6a96b8" alt="" width="190"><figcaption></figcaption></figure>

If you want to display data only when ***any*** criteria are met, you can click on the **+Add Custom Filter** button. In the example below, we only want to display the **Trips** where the **Travelers (Relationship to Users)** *contains* the **Logged in User , OR** the **Trip Status** *is equal to* **Active**

<figure><img src="https://3467607506-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LhGHkPsv15svPIU5I7C%2Fuploads%2FA5zUiPuF1We6YEz3HkqI%2FOR%20Filter.png?alt=media&#x26;token=e649b750-9e6f-47e6-ad69-cb8a9c4d31b5" alt="" width="196"><figcaption></figcaption></figure>

**0 vs. Null (Empty):**

In data management, **0** and **Null** represent different states. **0** is a valid numerical value, indicating the absence of a quantity or a specific value. **Null** signifies the ***absence of any value or unknown value*** indicating that ***no data is present*** in a particular field. In Adalo, **Null** is referred to as ***Empty.***

#### **Filtering Empty Values:**&#x20;

* Empty **cannot** be used to evaluate whether a Relationship exists AND the operator is Empty.&#x20;
  * **Example:** You only want records where a relationship exists, but a certain property is empty.&#x20;
* Empty **cannot** be used to filter a **count** of records.
  * **Example:** You only want records that do not have a relationship count. Since Counts are Numbers, you must compare to a Number such as '0'

**Advanced Filtering Techniques:**

* **Checking Relationships:** You can check if a record has a relationship across a many-to-one relationship by examining the Relationship’s ID property for Empty.&#x20;
  * **Example:** You can get a list of **Leads** that do not have a **Sales Person** **\[many Leads, one Sales Person]**, by checking **Current Leads > Sales Person > ID** *is equal to* **Empty**.
* **Evaluating Image and File Properties:** You can evaluate if a record does or does not have an image or file saved for an Image or File property.&#x20;
  * **Example:** You can only show options in a Dropdown component that have a saved **Contract \[File property]**, by applying a custom filter to only show records where **Contract > URL** *is not equal to* **Empty**.
* **Evaluating Location Properties:** Similarly, you can evaluate if a record does or does not have a location saved for a Location property.&#x20;
  * **Example:** You can get a count of all **Restaurants** that do not have a **Location**, by using a Magic Text Count of all Restaurants with a custom filter set to **Restaurant's > Location > Full Address** *is equal to* **Empty.**

{% hint style="danger" %}
***Please Note:*****&#x20;Adding too many filters to any Component can negatively impact performance of the app for the end user.**&#x20;
{% endhint %}

## Learn More

* You can combine filters with conditions to give even more control over what happens in your app. For instance, you may change the visibility of a component based on a filtered count of a collection of records in your database.
* Currently conditional actions and conditional visibility can only have one filter attached to them, but filters for lists, counts, charts, and other components can have multiple filters.&#x20;

## Help

If you need additional help with this article, you can always ask in our[ community forum](https://forum.adalo.com/)! Be sure to paste the link to this article in your post as well!

Do you have a tutorial or help doc request? [Let us know!](https://ideas.adalo.com/tutorial-requests)
