## 搜索組件
搜索組件用于 Index 頁面生成相對應的搜索表單, 所有搜索組件繼承 `app\common\component\SearchComponent`
### 常用組件說明
#### Input 組件 基礎組件
用于生成一個普通的 Input 表單
##### 參數:
無
##### 使用示例
```php
public $search = [
'category' => ['input'],
'name' => ['text', 'like'], // 找不到對應組件時將會默認使用 Input 組件, 并將組件名作為 Input 的類型
];
```
#### Selector 組件 選擇器
該組件用于生成一個 select 選擇器
##### 參數
`table`: 使用該參數的表的查詢結果作為選擇項
`field`: 需要用到的字段, 當 `format` 參數為空時, 只能填寫一個字段, 并且該字段將作為選擇項顯示的內容
`value`: 作為值的字段
`format`: 展示的格式, 該字段存在時, `field` 參數可以是多個字段, "hello \*field\*" 中 "\*field\*" 將會被替換成字段 field 的值
`join`: 數據庫查詢時 join 的規則, 同 `think\Db::join` 方法參數格式相同
`where` 數據庫查詢時 where 的規則, 同 `think\Db::where` 方法參數格式相同
`list`: 當該參數存在時, 將使用該數據作為查詢的結果, `list` 與 `table` 只能存在一個
##### 使用示例
```php
public $search = [
// 使用搜索組件中的 selector 組件, 使用 product_category 表中的數據
'cid' => ['selector', null, [
'table' => 'product_category',
'field' => 'name',
'value' => 'id'
]],
// 使用搜索組件中的 selector 組件, 使用固定數據
'status' => ['selector', null, [
'list' => [
[1, '上架'], // 等同與 [0 => 1, 1 => '上架'], 下同
[2, '下架']
],
'field' => 1,
'value' => 0
]],
];
```
#### Datetime 組件 時間范圍選擇
生成一個時間范圍選擇器
##### 參數
`type`: 可選, 默認 `datetime`, 時間類型, 當前支持: `datetime`, `date`, `time`
##### 使用示例
```php
public $search = [
'create_time' => ['datetime'],
'update_time' => ['datetime', null, ['type' => 'date']]
];
```
### 自定義搜索組件
**閱讀該說明前請先閱讀 [視圖組件.md](視圖組件.md)**
如果默認提供的組件無法滿足需求, 目前有兩種方法實現自定義的組件:
一種是直接使用一個有效的模板路徑作為組件名稱, 這樣的話該模板將會作為字段的組件模板參與渲染
另外一種是創建自己的搜索組件, 并使用
以上兩種方法, 一般來說都可以解決你的問題,
**第一種方法適用于組件的重復利用的可能性不大的情況, 并且靈活度較低, 無法處理返回值, 該方法較為簡單**
**第二種方法則相反, 創建的組件可以重復利用, 甚至可以移植到其它項目繼續使用, 靈活度較高, 但較為麻煩**
#### 使用模板路徑作為組件名
我們先介紹第一種方法, 下面將創建一個可以隨意修改屬性 input 組件
為了方便使用我們在項目種使用, 我們可以創建一個目錄專門用于保存這些 模板文件, 并且將該路徑定義為一個常量便于使用
創建 `application\admin\view\component` 目錄

在 `application\admin\common.php` 中定義常量 `C_PATH` 為 創建的模板文件目錄路徑

創建模板文件 `application\admin\view\component\attrInput.html`
模板的內容如下:
```php+HTML
<div class="col-md-3 col-sm-6">
<input type="text"
value="{$value}"
placeholder="{$name}"
name="{$field}"
class="form-control"
{$options.attr ?? null}
/>
</div>
```
**模板變量說明**
`$value`: 字段的值
`$name`: 字段的展示名
`$field`: 字段名稱(已編碼)
`$options`: 組件參數, 由于該值是可選的, 使用前請先判斷是否存在
將該模板應用到字段上
```php
public $search = [
'name' => [C_PATH . 'attrInput.html', 'like', [
'attr' => 'disabled'
]],
...
];
// 我們這里給 input 傳入一個 disabled 屬性
```
打開對應的頁面查看效果

可以看到 input 已經被禁用了, 這說明已經成功應用了該模板
雖然這種放非常簡單, 但是這樣沒有辦法很好的處理返回值, 比如說 搜索一個時間段, 這個時候, 我們要使用前端傳回的值來生成生成查詢語句, 那這種方法就不是特別合適了, 所以要用到第二種方法, 創建自定義搜索組件
#### 創建自定搜索組件
在此之前, 請先確定你閱讀過 [視圖組件.md](視圖組件.md) 了解了組件的命名方式和基本的工作方式
下面我們將創建一個多選搜索的組件, 搜索滿足任一條件的結果, 我們將其命名為 ICheckbox 組件
創建目錄, 模板文件, 類文件
搜索組件的命名前綴為 Search, 所以我們需要創建:
目錄 `application\common\component\SearchICheckbox`
模板文件 `application\common\component\SearchICheckbox\SearchICheckbox.html`
類文件 `application\common\component\SearchICheckbox\SearchICheckbox.html`
如圖所示:

模板文件 `SearchICheckbox.html` 內容:
```php
<div class="col-md-3 col-sm-6">
{volist name="options.list" id="vo"}
<label>
<input name="{$field}[]"
value="{$vo}"
{if condition="in_array($vo, $value ?? [])"}checked{/if}
type="checkbox">
{$vo}
</label>
{/volist}
</div>
```
這里的模板變量與方法一中的相同:
`$value`: 字段的值
`$name`: 字段的展示名
`$field`: 字段名稱(已編碼)
`$options`: 組件參數, 由于該值是可選的, 使用前請先判斷是否存在
所有的 搜索組件都需要繼承 `app\common\component\SearchComponent`
`SearchICheckbox.php` 的內容:
```php
<?php
namespace app\common\component\SearchICheckbox;
use app\common\component\SearchComponent;
class SearchICheckbox extends SearchComponent
{
}
```
現在我們可以先將該組件應用到視圖模型 `application\admin\viewModel\ProductCategory.php` 中去看看效果:
```php
public $search = [
'name' => ['i_checkbox', null, [
'list' => ['零食', '口腔護理', '冰箱', '家用電器']
]],
...
]
```
效果如圖所示:

可以看到勾選后點擊搜索這個時候將會報錯:

因為 `name` 的值是一個數組, where 不能直接處理這樣的一個數組, 所以我們可以直接在 組件中直接處理查詢實例
`SearchComponent` 繼承了 `Component` 并且有一個自己的方法, `search` 定義如下:
```php
abstract class SearchComponent extends Component
{
/**
* 生成查詢條件
* @param $field string 表單字段
* @param $params array 查詢參數
* @param $query Query Query 實例
*/
public static function search ($field, &$params, &$query)
{
$query->where($field, 'eq', $params[$field]);
}
}
```
所以在 `SearchICheckbox.php` 中, 我們重寫 `search` 方法:
```php
class SearchICheckbox extends SearchComponent
{
public static function search($field, &$params, &$query)
{
if ($params) {
$query->where($field, 'in', $params[$field]);
// 這里直接使用 in 方法查詢
}
}
}
```
那么現在這個組件已經可以正常工作了