# 創建表單
在 Yii 中使用表單的主要方式是通過 yii\widgets\ActiveForm。如果是基于模型的表單應首選這種方式。此外,在 yii\helpers\Html 中也有一些實用的方法用于添加按鈕和幫助文本。
在客戶端上顯示的表單,大多數情況下有一個相應的[模型](http://www.yiichina.com/doc/guide/2.0/structure-models),用來驗證其輸入的服務器數據 (可在?[輸入驗證](http://www.yiichina.com/doc/guide/2.0/input-validation)?一節獲取關于驗證的細節)。 當創建基于模型的表單時,第一步是定義模型本身。該模式可以是一個基于[活動記錄](http://www.yiichina.com/doc/guide/2.0/db-active-record)的類,表示數據庫中的數據, 也可以是一個基于通用模型的類(繼承自 yii\base\Model ),來獲取任意的輸入數據,如登錄表單。 在下面的例子中,我們展示了一個用來做登錄表單的通用模型:
~~~
<?php
class LoginForm extends \yii\base\Model
{
public $username;
public $password;
public function rules()
{
return [
// 在這里定義驗證規則
];
}
}
~~~
在控制器中,我們將傳遞一個模型的實例到視圖,其中 yii\widgets\ActiveForm 小部件用來顯示表單:
~~~
<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
$form = ActiveForm::begin([
'id' => 'login-form',
'options' => ['class' => 'form-horizontal'],
]) ?>
<?= $form->field($model, 'username') ?>
<?= $form->field($model, 'password')->passwordInput() ?>
<div class="form-group">
<div class="col-lg-offset-1 col-lg-11">
<?= Html::submitButton('Login', ['class' => 'btn btn-primary']) ?>
</div>
</div>
<?php ActiveForm::end() ?>
~~~
在上面的代碼中,yii\widgets\ActiveForm::begin() 不僅創建了一個表單實例,同時也標志著表單的開始。 放在 yii\widgets\ActiveForm::begin() 與 yii\widgets\ActiveForm::end() 之間的所有內容都被包裹在 HTML 的?`<form>`?標簽中。 與任何小部件一樣,你可以指定一些選項,通過傳遞數組到?`begin`?方法中來配置該小部件。在這種情況下, 一個額外的 CSS 類和 ID 會在`<form>`?標簽中使用。要查看所有可用的選項,請參閱 API 文檔的 yii\widgets\ActiveForm。
為了在表單中創建表單元素與元素的標簽,以及任何適用的 JavaScript 驗證,yii\widgets\ActiveForm::field() 方法在調用時,會返回一個 yii\widgets\ActiveField 的實例。 直接輸出該方法時,結果是一個普通的(文本)輸入。要自定義輸出,可以附加上 yii\widgets\ActiveField 的其它方法來一起調用:
~~~
// 一個密碼輸入框
<?= $form->field($model, 'password')->passwordInput() ?>
// 增加一個提示標簽
<?= $form->field($model, 'username')->textInput()->hint('Please enter your name')->label('Name') ?>
// 創建一個 HTML5 郵箱輸入框
<?= $form->field($model, 'email')->input('email') ?>
~~~
它會通過在 yii\widgets\ActiveField::$template 中定義的表單字段來創建?`<label>`,`<input>`?以及其它的標簽。 input 輸入框的 name 屬性會自動地根據 yii\base\Model::formName() 以及屬性名來創建。 例如,對于在上面的例子中?`username`?輸入字段的 name 屬性將是?`LoginForm[username]`。 這種命名規則使所有屬性的數組的登錄表單在服務器端的?`$_POST['LoginForm']`?數組中是可用的。
指定模型的屬性可以以更復雜的方式來完成。例如,當上傳時,多個文件或選擇多個項目的屬性,可能需要一個數組值, 你可以通過附加?`[]`?來指定它的屬性名稱:
~~~
// 允許多個文件被上傳:
echo $form->field($model, 'uploadFile[]')->fileInput(['multiple'=>'multiple']);
// 允許進行選擇多個項目:
echo $form->field($model, 'items[]')->checkboxList(['a' => 'Item A', 'b' => 'Item B', 'c' => 'Item C']);
~~~
命名表單元素,如提交按鈕時要小心。在?[jQuery 文檔](https://api.jquery.com/submit/)?中有一些保留的名稱,可能會導致沖突:
> 表單和它們的子元素不應該使用與表單的屬性沖突的 input name 或 id,例如?`submit`,`length`,或者?`method`。 要檢查你的標簽是否存在這些問題,一個完整的規則列表詳見?[DOMLint](http://kangax.github.io/domlint/)。
額外的 HTML 標簽可以使用純 HTML 或者 yii\helpers\Html-輔助類中的方法來添加到表單中,就如上面例子中的 yii\helpers\Html::submitButton()。
> 提示: 如果你正在你的應用程序中使用 Twitter Bootstrap CSS 你可以使用yii\bootstrap\ActiveForm 來代替 yii\widgets\ActiveForm。 前者繼承自后者并在生成表單字段時使用 Bootstrap 特有的樣式。
> 提示:為了設計帶星號的表單字段,你可以使用下面的 CSS:
>
> ~~~
> div.required label:after {
> content: " *";
> color: red;
> }
> ~~~
## 創建下拉列表
可以使用 ActiveForm 的?[dropDownList()](http://www.yiiframework.com/doc-2.0/yii-widgets-activefield.html#dropDownList()-detail)?方法來創建一個下拉列表:
~~~
use app\models\ProductCategory;
use yii\helpers\ArrayHelper;
/* @var $this yii\web\View */
/* @var $form yii\widgets\ActiveForm */
/* @var $model app\models\Product */
echo $form->field($model, 'product_category')->dropdownList(
ProductCategory::find()->select(['category_name', 'id'])->indexBy('id')->column(),
['prompt'=>'Select Category']
);
~~~
模型字段的值將被自動預先選定。
## 延伸閱讀
下一節?[輸入驗證](http://www.yiichina.com/doc/guide/2.0/input-validation)?處理提交的表單數據的服務器端驗證,以及 ajax- 和客戶端驗證。
要學會有關表格的更復雜的用法,你可以查看以下幾節:
* [收集列表輸入](http://www.yiichina.com/doc/guide/2.0/input-tabular-input)?同一種類型的多個模型的采集數據。
* [多模型同時輸入](http://www.yiichina.com/doc/guide/2.0/input-multiple-models)?在同一窗口中處理多個不同的模型。
* [文件上傳](http://www.yiichina.com/doc/guide/2.0/input-file-upload)?如何使用表格來上傳文件。
- 介紹(Introduction)
- 關于 Yii(About Yii)
- 從 Yii 1.1 升級(Upgrading from Version 1.1)
- 入門(Getting Started)
- 安裝 Yii(Installing Yii)
- 運行應用(Running Applications)
- 第一次問候(Saying Hello)
- 使用 Forms(Working with Forms)
- 玩轉 Databases(Working with Databases)
- 用 Gii 生成代碼(Generating Code with Gii)
- 更上一層樓(Looking Ahead)
- 應用結構(Application Structure)
- 結構概述(Overview)
- 入口腳本(Entry Scripts)
- 應用(Applications)
- 應用組件(Application Components)
- 控制器(Controllers)
- 模型(Models)
- 視圖(Views)
- 模塊(Modules)
- 過濾器(Filters)
- 小部件(Widgets)
- 前端資源(Assets)
- 擴展(Extensions)
- 請求處理(Handling Requests)
- 運行概述(Overview)
- 引導(Bootstrapping)
- 路由引導與創建 URL(Routing and URL Creation)
- 請求(Requests)
- 響應(Responses)
- Sessions and Cookies
- 錯誤處理(Handling Errors)
- 日志(Logging)
- 關鍵概念(Key Concepts)
- 組件(Components)
- 屬性(Properties)
- 事件(Events)
- 行為(Behaviors)
- 配置(Configurations)
- 別名(Aliases)
- 類自動加載(Class Autoloading)
- 服務定位器(Service Locator)
- 依賴注入容器(Dependency Injection Container)
- 配合數據庫工作(Working with Databases)
- 數據庫訪問(Data Access Objects): 數據庫連接、基本查詢、事務和模式操作
- 查詢生成器(Query Builder): 使用簡單抽象層查詢數據庫
- 活動記錄(Active Record): 活動記錄對象關系映射(ORM),檢索和操作記錄、定義關聯關系
- 數據庫遷移(Migrations): 在團體開發中對你的數據庫使用版本控制
- Sphinx
- Redis
- MongoDB
- ElasticSearch
- 接收用戶數據(Getting Data from Users)
- 創建表單(Creating Forms)
- 輸入驗證(Validating Input)
- 文件上傳(Uploading Files)
- 收集列表輸入(Collecting Tabular Input)
- 多模型同時輸入(Getting Data for Multiple Models)
- 顯示數據(Displaying Data)
- 格式化輸出數據(Data Formatting)
- 分頁(Pagination)
- 排序(Sorting)
- 數據提供器(Data Providers)
- 數據小部件(Data Widgets)
- 操作客戶端腳本(Working with Client Scripts)
- 主題(Theming)
- 安全(Security)
- 認證(Authentication)
- 授權(Authorization)
- 處理密碼(Working with Passwords)
- 客戶端認證(Auth Clients)
- 安全領域的最佳實踐(Best Practices)
- 緩存(Caching)
- 概述(Overview)
- 數據緩存(Data Caching)
- 片段緩存(Fragment Caching)
- 分頁緩存(Page Caching)
- HTTP 緩存(HTTP Caching)
- RESTful Web 服務
- 快速入門(Quick Start)
- 資源(Resources)
- 控制器(Controllers)
- 路由(Routing)
- 格式化響應(Response Formatting)
- 授權驗證(Authentication)
- 速率限制(Rate Limiting)
- 版本化(Versioning)
- 錯誤處理(Error Handling)
- 開發工具(Development Tools)
- 調試工具欄和調試器(Debug Toolbar and Debugger)
- 使用 Gii 生成代碼(Generating Code using Gii)
- TBD 生成 API 文檔(Generating API Documentation)
- 測試(Testing)
- 概述(Overview)
- 搭建測試環境(Testing environment setup)
- 單元測試(Unit Tests)
- 功能測試(Functional Tests)
- 驗收測試(Acceptance Tests)
- 測試夾具(Fixtures)
- 高級專題(Special Topics)
- 高級應用模版(Advanced Project Template)
- 從頭構建自定義模版(Building Application from Scratch)
- 控制臺命令(Console Commands)
- 核心驗證器(Core Validators)
- 國際化(Internationalization)
- 收發郵件(Mailing)
- 性能優化(Performance Tuning)
- 共享主機環境(Shared Hosting Environment)
- 模板引擎(Template Engines)
- 集成第三方代碼(Working with Third-Party Code)
- 小部件(Widgets)
- Bootstrap 小部件(Bootstrap Widgets)
- jQuery UI 小部件(jQuery UI Widgets)
- 助手類(Helpers)
- 助手一覽(Overview)
- Array 助手(ArrayHelper)
- Html 助手(Html)
- Url 助手(Url)