---
metaTitle: FilterChosen component | AwesCode UI
meta:
  - name: description
    content: The &lt;AwFilterChosen /&gt; component is used to render FilterChosen - UI Vue component for AwesCode UI.
title: FilterChosen
---

# AwFilterChosen

**Category:** Organism | **Import:** Dynamic

The `AwFilterChosen` component displays currently active filter parameters as removable chips. It syncs with URL query parameters and provides a convenient way to visualize and clear active filters.

## Overview

`AwFilterChosen` provides a filter chip display with:
- Automatic chip generation from URL query parameters
- Individual chip removal functionality
- "Reset all" button to clear all filters
- Support for single and multi-value filters
- Custom slot support for chip content
- Horizontal slider layout for many filters
- Automatic page and search param cleanup on reset

## Usage

### Best Practice: Always Use Custom Slots

**Important:** Always use custom slots to display user-friendly text instead of raw parameter values. This provides a better user experience.

```markup
<AwFilterChosen :watch-params="['is_active', 'permissions']">
    <template #is_active="{ value }">
        {{ getStatusLabel(value) }}
    </template>
    <template #permissions="{ value }">
        {{ getPermissionLabel(value) }}
    </template>
</AwFilterChosen>

<script>
export default {
    methods: {
        getStatusLabel(value) {
            if (value === true || value === 'true') return 'Active'
            if (value === false || value === 'false') return 'Inactive'
            return value
        },

        getPermissionLabel(value) {
            if (!value) return value

            const permissions = Array.isArray(value)
                ? value
                : typeof value === 'string'
                  ? value.split(',').map((p) => p.trim())
                  : [value]

            const permissionOptions = [
                { id: 'manage-profile', title: 'Manage profile' },
                { id: 'manage-users', title: 'Manage users' }
            ]

            return permissions
                .map((perm) => {
                    const option = permissionOptions.find(
                        (opt) => opt.id === perm || String(opt.id) === String(perm)
                    )
                    return option ? option.title : perm
                })
                .join(', ')
        }
    }
}
</script>
```

### Omit Search Parameter

**Important:** Do not include `'search'` in `watch-params`. The search parameter is typically handled separately and doesn't need to be displayed as a chip.

```markup
<!-- ✅ GOOD - Search is omitted -->
<AwFilterChosen :watch-params="['is_active', 'permissions']" />

<!-- ❌ BAD - Search should not be watched -->
<AwFilterChosen :watch-params="['search', 'is_active', 'permissions']" />
```

### Complete Example with Filters

```markup
<template>
    <AwPage title="Users">
        <div class="flex flex-wrap gap-4 mb-6">
            <AwFilterSelect
                param="is_active"
                label="Status"
                :options="statusOptions"
                single
            />
            <AwFilterSelect
                param="permissions"
                label="Permissions"
                :options="permissionOptions"
            />
            <AwSearch class="ml-auto" />
        </div>

        <AwFilterChosen :watch-params="['is_active', 'permissions']">
            <template #is_active="{ value }">
                {{ getStatusLabel(value) }}
            </template>
            <template #permissions="{ value }">
                {{ getPermissionLabel(value) }}
            </template>
        </AwFilterChosen>

        <AwTableBuilder
            :collection="users"
            :watch-params="['search', 'is_active', 'permissions']"
        >
            <AwTableCol field="first_name" title="First Name" />
        </AwTableBuilder>
    </AwPage>
</template>
```

### With Icons

```markup
<AwFilterChosen :watch-params="['status', 'type']">
    <template #status="{ value }">
        <AwIcon :name="statusIcon(value)" class="mr-1" />
        {{ statusLabel(value) }}
    </template>
    <template #type="{ value }">
        <span class="font-bold">{{ value }}</span>
    </template>
</AwFilterChosen>
```

### Default Chip Rendering

If you don't provide custom slots, the component will use default rendering:

```markup
<AwFilterChosen :watch-params="['category', 'brand']">
    <template #default="{ value, prop }">
        <span class="opacity-50 mr-1">{{ prop }}:</span> {{ value }}
    </template>
</AwFilterChosen>
```

**Note:** Default rendering shows raw parameter values, which is usually not user-friendly. Always prefer custom slots.

## API

### Props

| Name | Description | Type | Required | Default |
|------|-------------|------|----------|---------|
| watchParams | Array of query parameter keys to watch and display as chips | `Array` | `true` | - |

### Slots

| Name | Description | Props | Default Slot Content |
|------|-------------|-------|---------------------|
| [param] | Custom content for specific parameter (e.g., `#status`) | `{ value, pathOr }` | Falls through to default slot |
| default | Default chip content for all parameters | `{ value, prop, pathOr }` | `<span class="opacity-50 mr-1">{{ prop }}:</span> {{ val }}` |

**Slot Props:**
- `value` - The filter value for this chip
- `prop` - The query parameter name
- `pathOr` - Rambdax pathOr utility function

### Events

This component does not emit custom events. It handles routing internally via `$router.replace()`.

### Computed Properties

| Name | Description |
|------|-------------|
| chips | Array of `{ prop, val }` objects representing active filters |

### Methods

| Name | Parameters | Description |
|------|------------|-------------|
| reset | `(prop, val)` | Remove specific filter chip or reset all filters if no params provided |
| pathOr | - | Rambdax utility exposed in methods for slot usage |

## Related Components

- [AwFilterSelect](./aw-filter-select.md) - Dropdown filter component
- [AwFilterDateRange](./aw-filter-date-range.md) - Date range filter component
- [AwFilterMonth](./aw-filter-month.md) - Month filter component
- [AwChip](./aw-chip.md) - Chip component used internally
- [AwSlider](../atoms/aw-slider.md) - Slider component for horizontal scrolling

## Best Practices

1. **Always use custom slots** - Display user-friendly text instead of raw parameter values
2. **Omit `'search'` from watch-params** - Search is handled separately and doesn't need to be displayed as a chip
3. **Handle different value types** - Values can be strings, booleans, arrays, or comma-separated strings depending on how they're stored in the URL
4. **Map IDs to labels** - Use your filter options to map raw IDs to readable labels
5. **Handle arrays and comma-separated values** - Multi-value filters may come as arrays or comma-separated strings

## Notes

- **Import Method:** Dynamic - Component is loaded on-demand as an organism
- Component automatically hides when there are no active filters
- When removing a filter, both `page` and `search` query params are also removed
- Multi-value filters (arrays in query params) are displayed as separate chips
- Each chip shows a close icon on hover with error color
- Reset button clears all watched params plus `page` and `search` params
- Uses `$router.replace()` to avoid adding history entries
- Router errors are caught and logged to console
- Chips are displayed in a horizontal slider for better mobile support
- Component uses Rambdax utilities: `pick`, `omit`, `toPairs`, `isType`, `pathOr`
- Named slots take priority over default slot for custom chip rendering
- The `pathOr` utility is available in slots for safe nested object access
- **Important:** Do not watch `start_date` and `end_date` params from `AwFilterDateRange` in `watchParams`. These two params work together as a pair, and `AwFilterChosen` resets them individually, which breaks the date range filter. Use `AwFilterDateRange`'s built-in reset functionality instead
- **Important:** Do not include `'search'` in `watch-params`. Search parameters are typically handled separately and don't need to be displayed as filter chips
