section: javascript
id: chosen
description: 提供数据选择和筛选功能
icon: icon-search
filter:
---

# Chosen

Chosen是用来增强单选列表和多选列表的更佳选择。

<div class="alert alert-danger">
  <h4>兼容性问题</h4>
  <p>在触摸屏及移动设备上无法启用 Chosen。</p>
</div>

## 示例

### 单项选择和多项选择

<div class="example">
  <div class="row">
    <div class="col-md-3">
      <select data-placeholder="选择一个宠物..." class="chosen-select form-control" tabindex="2">
        <option value=""></option>
        <option value="cat">小猫</option>
        <option value="fish">金鱼</option>
        <option value="dragon">龙</option>
        <option value="mammoth">猛犸</option>
        <option value="gollum">咕噜</option>
      </select>
    </div>
    <div class="col-md-3">
      <select data-placeholder="选择一些爱吃的水果..." class="chosen-select form-control" tabindex="2" multiple="">
        <option value="strawberries">草莓</option>
        <option value="apple">苹果</option>
        <option value="orange">橙子</option>
        <option value="cherry" selected>樱桃</option>
        <option value="banana" selected>香蕉</option>
        <option value="figs" selected>无花果</option>
      </select>
    </div>
  </div>
</div>

```html
<select data-placeholder="选择一个宠物..." class="chosen-select form-control" tabindex="2">
  <option value=""></option>
  <option value="cat">小猫</option>
  <option value="fish">金鱼</option>
  <option value="dragon">龙</option>
  <option value="mammoth">猛犸</option>
  <option value="gollum">咕噜</option>
</select>
```

```html
<select data-placeholder="选择一些爱吃的水果..." class="chosen-select form-control" tabindex="2" multiple="">
  <option value="strawberries">草莓</option>
  <option value="apple">苹果</option>
  <option value="orange">橙子</option>
  <option value="cherry">樱桃</option>
  <option value="banana">香蕉</option>
  <option value="figs">无花果</option>
</select>
```

```js
$('select.chosen-select').chosen({
    no_results_text: '没有找到',    // 当检索时没有找到匹配项时显示的提示文本
    disable_search_threshold: 10, // 10 个以下的选择项则不显示检索框
    search_contains: true         // 从任意位置开始检索
});
```

### 扩展检索

有时我们希望用户检索的更加开心，例如为汉语选项添加拼音检索支持。Chosen提供了扩展字段专门用来检索，只需要为`<option>`标签增加`data-keys="*"`属性。

`data-keys`属性可以用空格或英文逗号来分隔多个供检索的关键字。

<div class="example">
  <select data-placeholder="使用拼音检索，试试“m”或“xm”" class="chosen-select form-control" tabindex="2">
    <option value=""></option>
    <option value="cat" data-keys="xiaomao xm 猫科动物">小猫</option>
    <option value="fish" data-keys="jinyu jy">金鱼</option>
    <option value="dragon" data-keys="long">龙</option>
    <option value="mammoth" data-keys="mengma mm">猛犸</option>
    <option value="gollum" data-keys="gulu gl 神话">咕噜</option>
  </select>
</div>

```html
<select data-placeholder="使用拼音检索，试试“m”或“xm”" class="chosen-select form-control" tabindex="2">
  <option value=""></option>
  <option value="cat" data-keys="xiaomao xm 猫科动物">小猫</option>
  <option value="fish" data-keys="jinyu jy">金鱼</option>
  <option value="dragon" data-keys="long">龙</option>
  <option value="mammoth" data-keys="mengma mm">猛犸</option>
  <option value="gollum" data-keys="gulu gl 神话">咕噜</option>
</select>
```

```js
$('select.chosen-select').chosen({
    no_results_text: '没有找到',    // 当检索时没有找到匹配项时显示的提示文本
    disable_search_threshold: 10, // 10 个以下的选择项则不显示检索框
    search_contains: true         // 从任意位置开始检索
});
```

<div class="alert alert-primary-inverse">
  <h4>提示</h4>
  <p>扩展检索本身并不提供拼音检索功能，如果你需要支持使用拼音检索时，需要你自己在chosen初始化之前在<code>data-keys</code>属性中写入拼音字符串。</p>
</div>

### 调整弹出菜单宽度

#### 固定宽度

通常弹出菜单的宽度与下拉按钮的宽度一致，但仍然可以使用 `drop_width` 来更改弹出菜单宽度。下面的例子中弹出菜单宽度固定为 `200px`：

<div class="example">
  <select class="chosen-select form-control" data-drop_width="200px">
    <option value=""></option>
    <option value="cat">小猫</option>
    <option value="fish">金鱼</option>
    <option value="dragon">龙</option>
    <option value="mammoth">猛犸</option>
    <option value="gollum">咕噜</option>
  </select>
</div>

```html
<select class="chosen-select form-control" data-drop_width="200px">
  <option value=""></option>
  <option value="cat">小猫</option>
  <option value="fish">金鱼</option>
  <option value="dragon">龙</option>
  <option value="mammoth">猛犸</option>
  <option value="gollum">咕噜</option>
</select>
```

#### 自动宽度

有时需要根据弹出菜单内的条目文字长度自动设置弹出面板宽度，尽量减少弹出菜单条目换行，此时可以使用 `drop_max_width` 来设置一个最大宽度。下面的例子中弹出菜单宽度最大不超过 `300px`，在最大值返回内尽量减少换行情况：

<div class="example">
  <div class="row">
    <div class="col" style="width: 120px">
      <select class="chosen-select form-control" data-max_drop_width="200" style="width: 100px">
        <option value=""></option>
        <option value="cat">小猫</option>
        <option value="fish">金鱼的尾巴好长好长好长好长好长好长好长好长啊</option>
        <option value="dragon">龙</option>
        <option value="mammoth">猛犸</option>
        <option value="gollum">咕噜</option>
      </select>
    </div>
  </div>
</div>

```html
<div class="row">
  <div class="col" style="width: 120px">
    <select class="chosen-select form-control" data-max_drop_width="200" style="width: 100px">
      <option value=""></option>
      <option value="cat">小猫</option>
      <option value="fish">金鱼的尾巴好长好长好长好长好长好长好长好长啊</option>
      <option value="dragon">龙</option>
      <option value="mammoth">猛犸</option>
      <option value="gollum">咕噜</option>
    </select>
  </div>
</div>
```

### 紧凑的单项选择

使用 `compact_search` 选项来应用更加紧凑的单选选择框，搜索框与选择框合并一起显示。

<div class="example">
  <select class="chosen-select form-control" data-compact_search="true">
    <option value=""></option>
    <option value="cat">小猫</option>
    <option value="fish">金鱼</option>
    <option value="dragon">龙</option>
    <option value="mammoth">猛犸</option>
    <option value="gollum">咕噜</option>
  </select>
</div>

```html
<select class="chosen-select form-control" data-compact_search="true">
  <option value=""></option>
  <option value="cat">小猫</option>
  <option value="fish">金鱼</option>
  <option value="dragon">龙</option>
  <option value="mammoth">猛犸</option>
  <option value="gollum">咕噜</option>
</select>
```

```js
$('select.chosen-select').chosen({
    compact_search: true           // 启用紧凑的单项选择
});
```

### 记录多选选项选择的顺序

有时需要记录用户选择多选选项时的顺序，可以通过 `[data-sort_field]` 属性（或初始化选项 `sort_field`）指定一个表单域（可以为文本库或隐藏域）来存储选中项值的顺序。

<div class="example">
  <select data-placeholder="选择一些爱吃的水果..." class="chosen-select form-control" tabindex="2" multiple="" data-sort_field="#chosenSortField" data-sort_value_splitter=",">
    <option value="strawberries">草莓</option>
    <option value="apple">苹果</option>
    <option value="orange">橙子</option>
    <option value="cherry" selected>樱桃</option>
    <option value="banana" selected>香蕉</option>
    <option value="figs" selected>无花果</option>
  </select>
  <input type="text" class="form-control" readonly="readonly" value="figs,cherry,banana" id="chosenSortField" style="margin-top: 10px">
</div>

```html
<select data-placeholder="选择一些爱吃的水果..." class="chosen-select form-control" tabindex="2" multiple="" data-sort_field="#chosenSortField" data-sort_value_splitter=",">
  <option value="strawberries">草莓</option>
  <option value="apple">苹果</option>
  <option value="orange">橙子</option>
  <option value="cherry" selected>樱桃</option>
  <option value="banana" selected>香蕉</option>
  <option value="figs" selected>无花果</option>
</select>
<input type="text" class="form-control" readonly="readonly" value="figs,cherry,banana" id="chosenSortField" style="margin-top: 10px">
```

## 用法

### 引入资源

Chosen 为独立组件，你需要从本地或 CDN 单独引入 lib 目录下的资源：

```html
<link href="lib/chosen/chosen.min.css" rel="stylesheet">
<script src="lib/chosen/chosen.min.js"></script>
```

### 选项

<table class="table table-bordered">
  <thead>
    <tr>
      <th>参数</th>
      <th style="width: 80px">名称</th>
      <th style="width: 300px">可选值</th>
      <th>说明</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>`lang`</td>
      <td>界面语言</td>
      <td>
        <ul>
          <li><code>'zh_cn'</code>（默认）</li>
          <li><code>'zh_tw'</code></li>
          <li><code>'en'</code></li>
        </ul>
      </td>
      <td>如果不设置此值，会自动优先从 `<html>` 的 `[lang]` 属性作为界面语言设置。</td>
    </tr>
    <tr>
      <td>`allow_single_deselect`</td>
      <td>允许取消单选</td>
      <td>
        <ul>
          <li><code>'true'</code>：允许取消</li>
          <li><code>'false'</code>（默认）：不允许</li>
        </ul>
      <td>如果允许单选取消，则会在用户选择选项之后，显示一个移除按钮，点击此按钮会移除用户选择的项目。</td>
    </tr>
    <tr>
      <td>`disable_search`</td>
      <td>禁用检索</td>
      <td>
        <ul>
          <li><code>'true'</code>：禁用</li>
          <li><code>'false'</code>（默认）：不禁用</li>
        </ul>
      </td>
      <td>禁用检索功能，将不再显示搜索框来让用户检索选项。</td>
    </tr>
    <tr>
      <td>`disable_search_threshold`</td>
      <td>自动禁用的最大值</td>
      <td>数字，默认为`0`</td>
      <td>当可选选项数目小于或等于此值时，自动禁用检索选项。</td>
    </tr>
    <tr>
      <td>`inherit_select_classes`</td>
      <td>继承 `<select>` 的 CLASS</td>
      <td>默认为`false`</td>
      <td>如果设置为`true`，chosen 在初始化之后会获取原 `<select>` 上的CSS CLASS 值并添加在chosen容器 `.chosen-container`上。</select></td>
    </tr>
    <tr>
      <td>`max_selected_options`</td>
      <td>最大选择数目</td>
      <td>数字，默认为`Infinity`</td>
      <td>仅多选生效；当用户选择的选项数目达到此值时，将会触发`chosen:maxselected`事件。</td>
    </tr>
    <tr>
      <td>`no_results_text`</td>
      <td>无结果时的文本</td>
      <td>字符串，默认从语言配置获取</td>
      <td>当用户检索时没有匹配的结果会显示此文本。</td>
    </tr>
    <tr>
      <td>`placeholder_text`</td>
      <td>空值占位文本</td>
      <td>字符串，默认为`""`</td>
      <td>当用户没有选择选项时显示此文本；此选项也可以通过`<select>`的`data-placeholder`属性来指定。</select></td>
    </tr>
    <tr>
      <td>`placeholder_text_multiple`</td>
      <td>多选空值占位文本</td>
      <td>字符串，默认为`""`</td>
      <td>如果没有设置此选项，则会尝试读取`placeholder_text`选项的值。</td>
    </tr>
    <tr>
      <td>`placeholder_text_single`</td>
      <td>单选空值占位文本</td>
      <td>字符串，默认为`""`</td>
      <td>如果没有设置此选项，则会尝试读取`placeholder_text`选项的值。</td>
    </tr>
    <tr>
      <td>`search_contains`</td>
      <td>启用任意位置检索</td>
      <td>默认为`false`</td>
      <td>默认情况下，仅仅会从选项或检索关键字的开始进行匹配，例如`"he"`仅仅能匹配`"hello"`，不能匹配`"ahead"`，如果启用此选项，则可以从关键的任意位置进行匹配。</td>
    </tr>
    <tr>
      <td>`compact_search`</td>
      <td>是否启用紧凑的单选选择外观</td>
      <td>默认为`false`</td>
      <td>如果设置为 `true`，则搜索框与选择框合并一起显示。</td>
    </tr>
    <tr>
      <td>`single_backstroke_delete`</td>
      <td>启用退格键删除</td>
      <td>默认为`true`</td>
      <td>仅多选生效；启用此选项允许用户在多选时按退格键（Backspace）和删除键（Delete）来删除上一个选择项。</td>
    </tr>
    <tr>
      <td>`width`</td>
      <td>宽度</td>
      <td>默认为原始`<select>`的宽度</select></td>
      <td>默认chosen的宽度与原始的`<select>`一致，如果原始的`</select>`在chosen初始化之前不可见，可能需要手动指定一个宽度，否则chosen的宽度会为`0`；如果使用响应式布局，建议宽度设定为`'100%'`。</td>
    </tr>
    <tr>
      <td>`display_disabled_options`</td>
      <td>显示不可选的选项</td>
      <td>默认为`true`</td>
      <td>默认情况下会在选项列表菜单中显示不可选的选项，禁用此选项来隐藏不可选的选项。</td>
    </tr>
    <tr>
      <td>`display_selected_options`</td>
      <td>显示已选择的选项</td>
      <td>默认为`true`</td>
      <td>仅多选生效；禁用此选项则在选项列表菜单中隐藏已选择的选项。</td>
    </tr>
    <tr>
      <td>`drop_direction`</td>
      <td>选项列表菜单弹出方向</td>
      <td>
        <ul>
          <li><code>"auto"</code>（默认) 根据弹出时根据弹出菜单高度和所在位置自动决定</li>
          <li><code>"down"</code></li>
          <li><code>"up"</code></li>
        </ul>
      </td>
      <td>在自动决定情况下默认向下弹出，如果下方空间不够会自动改为向上弹出，搜索过程中不会改变弹出位置。</td>
    </tr>
    <tr>
      <td>`drop_width`</td>
      <td>选项列表菜单宽度</td>
      <td>例如 `200px`</td>
      <td>如果不指定此选项则与选择按钮宽度一致。</td>
    </tr>
    <tr>
      <td>`max_drop_width`</td>
      <td>选项列表菜单最大宽度</td>
      <td>此选项的值只能是数值，以 `px` 为单位表示最大宽度。</td>
      <td>使用此选项后会自动根据选项列表条目上的文字长度来调整选项列表宽度。</td>
    </tr>
    <tr>
      <td>`highlight_selected`</td>
      <td>是否一直高亮选中项</td>
      <td>默认为 `true`</td>
      <td></td>
    </tr>
    <tr>
      <td>`middle_highlight`</td>
      <td>高亮的选项居中</td>
      <td>
        <ul>
          <li><code>false</code>（默认) 不改变高亮选项位置</li>
          <li><code>true</code>，当展开弹出菜单时滚动列表使得高亮的选项在弹出菜单的中间位置</li>
          <li><code>"always"</code>，当展开弹出菜单时以及切换选择高亮的选项时滚动列表使得高亮的选项在弹出菜单的中间位置</li>
        </ul>
      </td>
      <td></td>
    </tr>
    <tr>
      <td>`no_wrap`</td>
      <td>是否禁用选项文本换行</td>
      <td>
        <ul>
          <li><code>false</code>（默认) 不禁用换行，允许换行</li>
          <li><code>true</code>，禁用换行</li>
        </ul>
      </td>
      <td></td>
    </tr>
    <tr>
      <td>`sort_field`</td>
      <td>用于记录多选选项顺序的表单域</td>
      <td>该选项的值可以为 DOM 元素、jQuery 对象或者 jQuery 对象选择字符串</td>
      <td>表单域可以隐藏域或者文本框</td>
    </tr>
    <tr>
      <td>`sort_value_splitter`</td>
      <td>用于记录多选选项值顺序时用于拼接的字符</td>
      <td>默认为 `','`</td>
      <td></td>
    </tr>
  </tbody>
</table>

#### 事件

Chosen的事件绑定在原始`<select>`上，使用jQuery方法来监听事件。目前可以使用以下事件：

<table class="table table-bordered">
  <thead>
    <tr>
      <th>事件</th>
      <th>说明</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>`change`</td>
      <td>当选择的值发生改变时发生。</td>
    </tr>
    <tr>
      <td>`chosen:ready`</td>
      <td>当完成初始化之后触发。</td>
    </tr>
    <tr>
      <td>`chosen:maxselected`</td>
      <td>当达到最大选择数目（通过`max_selected_options`指定）时发生</td>
    </tr>
    <tr>
      <td>`chosen:showing_dropdown`</td>
      <td>当弹出显示选项列表菜单时发生。</td>
    </tr>
    <tr>
      <td>`chosen:hiding_dropdown`</td>
      <td>当隐藏选项列表菜单时发生。</td>
    </tr>
    <tr>
      <td>`chosen:no_results`</td>
      <td>当没有检索到匹配的选项时发生。</td>
    </tr>
  </tbody>
</table>

```js
$('select.chosen-select').on('change', function(){
    // 用户改变了选择，快快处理
});
```

#### 方法

可以通过触发事件来调用chosen的方法。

```js
// 当原始select中的选项发生变化时通知chosen更新选项列表菜单
$('select.chosen-select').trigger('chosen:updated');
```

所有可以通过事件触发的方法有：

<table class="table table-bordered">
  <thead>
    <tr>
      <th>触发事件</th>
      <th>说明</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>`chosen:updated`</td>
      <td>通知chosen重新从原始select中更新选项列表菜单。</td>
    </tr>
    <tr>
      <td>`chosen:activate`</td>
      <td>让chosen激活并获取焦点；激活之后的chosen会捕获用户输入并执行操作。</td>
    </tr>
    <tr>
      <td>`chosen:open`</td>
      <td>打开（弹出）选项列表菜单面板。</td>
    </tr>
    <tr>
      <td>`chosen:close`</td>
      <td>隐藏选项列表菜单面板。</td>
    </tr>
  </tbody>
</table>

详细用法可以参考[chosen官方文档](http://harvesthq.github.io/chosen/options.html)。

## 图标选择插件

### 示例

为方便选择[漂亮的图标](#control/icon)，依赖于Chosen新作了[图标](#control/icon)选择插件。

<div class="example">
  <form>
    <select class="chosen-icons form-control" name="chosenIcons" id="chosenIcons" data-value="icon-star"></select>
  </form>
</div>

```html
<select class="chosen-icons form-control" name="chosenIcons" id="chosenIcons" data-value="icon-star"></select>
```

```js
$('select.chosen-icons').chosenIcons(options);
```

### 用法

图标选择插件独立组件，并且依赖 Chosen 插件，你需要从本地或 CDN 单独引入 lib 目录下的资源：

```html
<!-- 引入 Chosen 相关资源 -->
<link href="lib/chosen/chosen.min.css" rel="stylesheet">
<script src="lib/chosen/chosen.min.js"></script>

<!-- 引入图标选择插件相关资源 -->
<link href="lib/chosenicons/zui.chosenicons.min.css" rel="stylesheet">
<script src="lib/chosenicons/zui.chosenicons.min.js"></script>
```

图标选择插件可以使用chosen的所有选项和方法。

<link href="dist/lib/chosen/chosen.min.css" rel="stylesheet">
<script src="dist/lib/chosen/chosen.min.js"></script>
<link href="dist/lib/chosenicons/zui.chosenicons.min.css" rel="stylesheet">
<script src="dist/lib/chosenicons/zui.chosenicons.min.js"></script>
<script>
function onPageLoad() {return false;}
function afterPageLoad() {
    if($.fn.chosen) {
        $('#pageBody .chosen-select').each(function() {
            $(this).chosen($.extend({
                allow_single_deselect: true,
                search_contains: true,
                width: '100%'
            }, $(this).data()));
        }).on('change', function(e, data){
            console.log('change', e, data);
        });
    }
    if($.fn.chosenIcons) $('#chosenIcons').chosenIcons();
    setTimeout($.doc.stopPageLoading, 500);
}
</script>
