PHPackages                             ahmedabdo/searchable - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Database &amp; ORM](/categories/database)
4. /
5. ahmedabdo/searchable

ActiveLibrary[Database &amp; ORM](/categories/database)

ahmedabdo/searchable
====================

package for adding search functionality to laravel models

v1.0.10(2y ago)27919↓83.8%4MITPHP

Since Sep 5Pushed 1y ago2 watchersCompare

[ Source](https://github.com/ahmed-abd0/searchable)[ Packagist](https://packagist.org/packages/ahmedabdo/searchable)[ RSS](/packages/ahmedabdo-searchable/feed)WikiDiscussions main Synced 3w ago

READMEChangelogDependenciesVersions (12)Used By (0)

Searchable
==========

[](#searchable)

Laravel Searchable is package that adds easy customizable searching and filtering ability to Laravel Eloquent Models

- [Installation](#installation)
- [Searching](#searching)

    - [Usage Example](#search-usage-example)
    - [Search Columns](#search-columns)
    - [Custom Search](#custom-search)
    - [Overwrite Default Columns](#overwrite-default-columns)
    - [Search Options](#search-options)
- [Filtering](#filtering)

    - [Usage Example](#filter-usage-example)
    - [Filtering Columns](#filtering-columns)
    - [Filter Query String](#filter-query-string)
    - [Operators](#operators)
    - [Filter Modes](#filter-modes)
    - [Filter Blade Script](#filter-blade-script)
    - [Filter Helpers](#filter-helpers)
    - [Custom Operators](#custom-operators)

Installation
------------

[](#installation)

```
composer require ahmedabdo/searchable
```

Searching
---------

[](#searching)

Search Usage Example
--------------------

[](#search-usage-example)

- Use the Abdo\\Searchable\\Searchable trait in your model.
- Define the columns you want to use for searching within the searchable array.
- Utilize the search scope to perform searches on the selected columns.

```
// model
use Abdo\Searchable\Searchable;
use Abdo\Searchable\Attributes\SearchAdd;
use Abdo\Searchable\Attributes\SearchColumns;
class User extends Authenticatable
{
    use Searchable;

    #[SearchColumns]
    public $searchable = [
	"columns" => [
	    "name",
	    "email",
	    "role.name",
	    "created_at"
	],
	"eager" => [
	    "role"
	]
    ];

    #[SearchAdd("created_at")]
    public function searchByCreatedAtDayName(Builder $q, string $searchWord) {
        $q->orWhereRaw("DAYNAME(created_at) like ?", ["%" . $searchWord . "%"]);
    }
}

// usage

User::search($searchWord)->get();
```

### Search Columns

[](#search-columns)

To define the search columns for a model, you can utilize a property decorated with the `#[SearchColumns]` attribute. This property will contain the default columns for searching the model, as well as any relations that need to be eagerly loaded. In case the `#[SearchColumns]` attribute is not set, the fillable columns will be used as a fallback.

```
#[SearchColumns]
public $searchable = [
    "columns" => [
        "colame",
	"relation.colname",
        "relation.relation.colname",
    ],
    "eager" => [
        "relation"
    ]
];
```

### Custom Search

[](#custom-search)

If you wish to customize the search query for a specific column, you can create a method with the `#[Search("colname")]` attribute and craft a custom query specifically for that chosen column.

```
#[SearchColumns]
public $searchable = [
    "columns" => [
        "time", // stored as Y-m-d H:i:s
    ]
];

#[Search("time")]
public function searchTime(Builder $q, string $searchWord) {
     $q->orWhere("time", "like", "%" . $searchWord . "%")
       ->orWhereRaw("DAYNAME(time) like ?", ["%" . $searchWord . "%"]);
}
```

In the example above, the "time" column is stored in the database as a datetime value. If you wish to customize the search functionality for this column by adding a new orWhere statement for searching by day name, you can employ the `#[SearchAdd("colname")]` attribute.

By utilizing this attribute, you can incorporate the desired orWhere statement into the column search query, while still leveraging the existing search query provided by the package.

Note

you may use as many searchAdd methods as you want.

```
#[SearchAdd("time")]
public function searchTimeByDayName(Builder $q, string $searchWord) {
     $q->orWhereRaw("DAYNAME(time) like ?", ["%" . $searchWord . "%"]);
}
```

If you have used either `#[Search("colname")]` or `#[SearchAdd("colname")]` to customize relation search, the builder instance passed to the custom method will be the builder for the relation model.

```
public $searchable = [
    "columns" => [
        "patient.name",
    ]
];

#[Search("patient.name")]// or #[SearchAdd("patient.name")]
public function searchPatientName(Builder $q, string $searchWord) {
     // $q is builder instance for Patient model
     $q->orWhere("name", "like", "%" . $searchWord . "%");
}
```

### Overwrite Default Columns

[](#overwrite-default-columns)

If you want to override the columns defined in the model, you can pass the columns as a second parameter to the search scope.

```
User::search($searchWord, ["fname", "lname"])->get();
```

### Search Options

[](#search-options)

You can add an options array for columns

```
#[SearchColumns]
public $searchable = [
    "columns" => [
        "name" => ["operator" => "="]
    ]
];

User::search($searchWord,[
    "name" => ["operator" => "=", "useCustom" => false, "useAddCondition" => false]
])
```

The column can have three options

optiondescriptionvaluesdefaultoperatorthe operator used for searching operation[Avaliable Operators](#operators)likeContainsuseCustomif it uses search method that has #\[Search(”col”)\]true or falsetrueuseAddConditionif it uses search methods that has #\[SearchAdd(”col”)\]true or falsetrueFiltering
---------

[](#filtering)

### Filter Usage Example

[](#filter-usage-example)

```
// model
use Abdo\Searchable\Searchable;
class User extends Authenticatable
{
     use Searchable;

     #[SearchColumns]
     public $searchable = [
        "columns" => [
            "name",
            "email",
            "role.name",
            "created_at"
        ],
        "eager" => [
            "role"
        ]
    ];
}

//request query string :
// ?name=ahmed&email=startsWith|ahmed&role:name=admin&created_at=from|2020-01-01

// usage
User::filter()->get();
```

### Filtering Columns

[](#filtering-columns)

By default, the columns used for filtering will be those defined in the property with the `#[SearchColumns]` attribute, combined with the columns specified in the fillable array. If you wish to use different columns as the default for filtering, you can define a property with the `#[FilterColumns]` attribute.

```
#[FilterColumns]
public $filterable = [
	"name","email", //...
];
```

### Filter Query String

[](#filter-query-string)

The query string parameter names should match to the column names. If you are filtering a relation, you can use a colon `:` as a separator between the relation name and the column name, instead of a dot `.` The query string should follow to this pattern.

```
// ?=|

User::filter()->get();
```

If you have used a parameter name that differs from the column name, you can pass both the column name and the filter value to the filter scope.

```
// ?=|
// To retrieve the filter value from the query string, you can utilize the "filterParam" helper

User::filter(["column_name" => filterParam("not_column_name")])->get();

// Note that if the rest of the query string parameter names match the column names
// you can employ a similar approach.
User::filter(["column_name" => filterParam("not_column_name")])->filter()->get();
```

### Operators

[](#operators)

The operators allowed for filtering include any operator that can be sent to the `where` builder method, plus additional operators.

OperatorDescriptionExample“contains” or “cont”filtering out entries where the column value contains the given value?name=cont|ahmed“startsWith” or “sw”filtering out entries where the column value starts with the given value?name=sw|ahmed“endsWith” or “ew”filtering out entries where the column value ends with the given value?name=ew|abdo“In”filtering out entries where the column value exists in the given values?role\_id=in|1,2,3,4,5“notIn”filtering out entries where the column value dosen’t exists in the given values?role\_id=notIn|1,5“is\_null”filtering out entries where the column value is null?role\_id=is\_null|“is\_not\_null”filtering out entries where the column value is not null?role\_id=is\_not\_null|“from”filtering out entries where the `date` column value is after the given value?created\_at=from|2010-01-01“from\_eq”filtering out entries where the `date` column value is after or equal the given value?created\_at=from\_eq|2010-01-01“to”filtering out entries where the `date` column value is before the given value?created\_at=to|2010-01-01“to\_eq”filtering out entries where the `date` column value is before or equal the given value?created\_at=to\_eq|2010-01-01“from\_time”same as “from” but for time?time=from\_time|12:30“from\_time\_eq”same as “from\_eq” but for time?time=from\_time\_eq|12:30“to\_time”same as “to” but for time?time=to\_time|12:30“to\_time\_eq”same as “to\_eq” but for time?time=to\_time\_eq|12:30“between” or “bt”filtering out entries where column value lies in the given range?created\_at=bt|2010-01-01,2015-01-01&amp;role\_id=bt|3,5“betweenEqual” or “bte”filtering out entries where column value lies in given range with boundry?created\_at=bte|2010-01-01,2015-01-01&amp;role\_id=bte|3,5“where” statement operatorsany operator used in “where” method can be used as filter operator?age=&lt;|20&amp;gender=maleNote

When using the "between" operator, two arguments must be provided, separated by a comma. If the `from` argument is not specified, the data will be filtered from negative infinity up to the `to` argument. Similarly, if the `to` argument is not provided, the data will be filtered up to positive infinity. For example: ?created\_at=bt|,2010-01-01 retrieves all records created before January 1, 2010. Another example: ?created\_at=bt|2010-01-01, retrieves all records created after January 1, 2010.

### Filter Modes

[](#filter-modes)

there is two filter modes `and` mode and `or` mode the default mode is `and`
for changing the mode

```
    // using or mode
    User::filter(mode: Mode::OR)->get();

    // using and mode
    User::filter(mode: Mode::AND)->get();
    User::filter()->get();
```

### Filter Blade Script

[](#filter-blade-script)

If you are utilizing regular Blade templates for the frontend, there is a simple JavaScript script available that simplifies the creation of filter forms. To include this script, add the `@searchableScripts` directive to your main layout.

then you can create filter form like by following steps

### Usage:

[](#usage)

- ensure that the form has class `filter`
- The input name should match the corresponding column name
- For relations, use a colon `:` as a separator ex: `relation:columnName`
- Set the desired filtering operator in the `data-filter` attribute, with the default being `=`
- use `filterValue("queryParam")` to get the filter value

```

    Age

    Created At From

    Created At To

    Role

        admin
        manager
        employee

    filter

```

### Filter Helpers

[](#filter-helpers)

**filterParam**

The "filterParam" helper function is utilized to extract the filter value from the query string. This helper function should be utilized when employing a blade filter form, especially if the input field name differs from the corresponding column name.

```
//model
#[SearchColumns]
public $searchable = [
    "columns" => [
        "name"
    ],
];

//blade

//usage
User::filter(["name" => filterParam("empName")])->get();
```

**filterValue**

The "filterValue" helper is employed to retrieve the value utilized for filtering in order to display this value in the input field, as an illustrative example.

```
//?name=cont|ahmed&role_id=in|2,3,4

filterValue("name") // ouptut ahmed
filterValue("role_id") // output 2,3,4
filterValue("role_id", true) //output [2,3,4]
```

### Custom Operators

[](#custom-operators)

In case you need to define a custom operator for filtering and searching, there are two distinct approaches available.

Note

custom operator must start with `sp_`

**In Config**
To publish the configuration file, execute the following command

```
php artisan vendor:publish --provider="Abdo\Searchable\ServiceProvider"
```

Once the configuration file has been published, you have the option to define your custom operators within the `operators` array.

```
    "operators" => [

        "sp_is_null" => function (Builder $builder, string $column, string $word) {
            return $builder->whereIsNull($column)->orWhere($column, 0);
        },
    ],
```

**In Service Provider**

Additionally, you can register your custom operators within the boot method of one of the service providers.

```
    ColumnConfigraution::registerOperator("sp_is_null", function (Builder $builder, string $column, string $word) {
        return $builder->whereIsNull($column)->orWhere($column, 0);
    });

    //after defining your custom operator you can use them like this
    //?status=sp_is_null|
```

###  Health Score

32

—

LowBetter than 69% of packages

Maintenance27

Infrequent updates — may be unmaintained

Popularity30

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity50

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~3 days

Total

11

Last Release

991d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/0e35de11d549981804ef004be489ebcb679d92a949e883b67f451777cef1b4e9?d=identicon)[Ahmed123567](/maintainers/Ahmed123567)

---

Top Contributors

[![ahmed-abd0](https://avatars.githubusercontent.com/u/89392661?v=4)](https://github.com/ahmed-abd0 "ahmed-abd0 (79 commits)")

---

Tags

searchlaraveleloquentfiltermodelssearchablefiltering

### Embed Badge

![Health badge](/badges/ahmedabdo-searchable/health.svg)

```
[![Health](https://phpackages.com/badges/ahmedabdo-searchable/health.svg)](https://phpackages.com/packages/ahmedabdo-searchable)
```

###  Alternatives

[tucker-eric/eloquentfilter

An Eloquent way to filter Eloquent Models

1.8k5.0M31](/packages/tucker-eric-eloquentfilter)[jedrzej/searchable

Searchable trait for Laravel's Eloquent models - filter your models using request parameters

125266.7k5](/packages/jedrzej-searchable)[jedrzej/pimpable

Laravel 4/5/6 package that allows to dynamically filter, sort and eager load relations for your models using request parameters

104184.9k1](/packages/jedrzej-pimpable)[lacodix/laravel-model-filter

A Laravel package to filter, search and sort models with ease while fetching from database.

17555.1k](/packages/lacodix-laravel-model-filter)[indexzer0/eloquent-filtering

Powerful eloquent filtering

22529.9k4](/packages/indexzer0-eloquent-filtering)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
