在 Yii 中使用表单的主要方式是通过 yii\widgets\ActiveForm。当表单基于模型时,应优先选择此方法。此外,yii\helpers\Html 中还有一些有用的方法,通常用于为任何表单添加按钮和帮助文本。
在大多数情况下,在客户端显示的表单将对应一个 模型,该模型用于在服务器端验证其输入(有关验证的更多详细信息,请查看 验证输入 部分)。在创建基于模型的表单时,第一步是定义模型本身。该模型可以基于 活动记录 类,表示来自数据库的一些数据,也可以是一个通用的模型类(从 yii\base\Model 扩展而来),用于捕获任意输入,例如登录表单。
提示:如果表单字段与数据库列不同,或者存在仅特定于该表单的格式和逻辑,建议创建一个单独的模型,从 yii\base\Model 扩展而来。
在下面的示例中,我们展示了如何将通用模型用于登录表单
<?php
class LoginForm extends \yii\base\Model
{
public $username;
public $password;
public function rules()
{
return [
// define validation rules here
];
}
}
在控制器中,我们将向视图传递该模型的实例,在该视图中,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() ?>
begin()
和 end()
包裹 ¶在上面的代码中,ActiveForm::begin() 不仅创建了一个表单实例,而且还标记了表单的开始。放置在 ActiveForm::begin() 和 ActiveForm::end() 之间的所有内容都将被包装在 HTML <form>
标签内。与任何小部件一样,您可以通过将数组传递给 begin
方法来指定一些关于如何配置小部件的选项。在这种情况下,传递了额外的 CSS 类和标识 ID,以在打开的 <form>
标签中使用。有关所有可用选项,请参考 yii\widgets\ActiveForm 的 API 文档。
为了在表单中创建表单元素,以及该元素的标签和任何适用的 JavaScript 验证,调用 ActiveForm::field() 方法,该方法返回 yii\widgets\ActiveField 的实例。当直接回显该方法的结果时,结果是一个常规的(文本)输入。要自定义输出,您可以将 ActiveField 的其他方法链接到此调用
// a password input
<?= $form->field($model, 'password')->passwordInput() ?>
// adding a hint and a customized label
<?= $form->field($model, 'username')->textInput()->hint('Please enter your name')->label('Name') ?>
// creating a HTML5 email input element
<?= $form->field($model, 'email')->input('email') ?>
这将根据表单字段定义的模板创建所有<label>
、<input>
和其他标签。输入字段的名称由模型的表单名称和属性名称自动确定。例如,上面示例中username
属性的输入字段的名称将为LoginForm[username]
。此命名规则将导致登录表单所有属性的数组在服务器端$_POST['LoginForm']
中可用。
提示:如果您表单中只有一个模型,并且想要简化输入名称,可以通过覆盖模型的formName()方法以返回空字符串来跳过数组部分。这对于在GridView中使用的过滤器模型创建更友好的URL很有用。
指定模型的属性可以通过更复杂的方式完成。例如,当属性在上传多个文件或选择多个项目时可能采用数组值时,您可以通过将[]
附加到属性名称来指定它。
// allow multiple files to be uploaded:
echo $form->field($model, 'uploadFile[]')->fileInput(['multiple'=>'multiple']);
// allow multiple items to be checked:
echo $form->field($model, 'items[]')->checkboxList(['a' => 'Item A', 'b' => 'Item B', 'c' => 'Item C']);
命名表单元素(例如提交按钮)时要小心。根据jQuery 文档,有一些保留名称会导致冲突。
表单及其子元素不应使用与表单属性冲突的输入名称或 ID,例如
submit
、length
或method
。名称冲突会导致令人困惑的错误。有关规则的完整列表以及如何检查您的标记是否存在这些问题,请参见DOMLint。
可以使用纯 HTML 或使用Html 帮助程序类中的方法向表单添加其他 HTML 标签,如上面示例中使用Html::submitButton()所做的那样。
提示:如果您在应用程序中使用 Twitter Bootstrap CSS,您可能希望使用yii\bootstrap\ActiveForm 而不是yii\widgets\ActiveForm。前者继承自后者,并在生成表单输入字段时使用 Bootstrap 特定的样式。
提示:为了用星号对必填字段进行样式化,您可以使用以下 CSS
div.required label.control-label:after { content: " *"; color: red; }
有 3 种类型的列表
要创建列表,您必须准备项目。这可以通过手动方式完成
$items = [
1 => 'item 1',
2 => 'item 2'
]
或通过从数据库检索
$items = Category::find()
->select(['label'])
->indexBy('id')
->column();
这些$items
必须由不同的列表小部件进行处理。表单字段的值(以及当前活动项目)将由$model
属性的当前值自动设置。
我们可以使用 ActiveField 的 yii\widgets\ActiveField::dropDownList() 方法来创建下拉列表
/* @var $form yii\widgets\ActiveForm */
echo $form->field($model, 'category')->dropdownList([
1 => 'item 1',
2 => 'item 2'
],
['prompt'=>'Select Category']
);
我们可以使用 ActiveField 的 yii\widgets\ActiveField::radioList() 方法来创建单选列表
/* @var $form yii\widgets\ActiveForm */
echo $form->field($model, 'category')->radioList([
1 => 'radio 1',
2 => 'radio 2'
]);
我们可以使用 ActiveField 的 yii\widgets\ActiveField::checkboxList() 方法来创建复选框列表
/* @var $form yii\widgets\ActiveForm */
echo $form->field($model, 'category')->checkboxList([
1 => 'checkbox 1',
2 => 'checkbox 2'
]);
Pjax 小部件允许您更新页面中的某个特定部分,而不是重新加载整个页面。您可以使用它来仅更新表单并在提交后替换其内容。
您可以配置$formSelector 以指定哪个表单提交可能触发 pjax。如果没有设置,Pjax 包含内容中的所有具有data-pjax
属性的表单都会触发 pjax 请求。
use yii\widgets\Pjax;
use yii\widgets\ActiveForm;
Pjax::begin([
// Pjax options
]);
$form = ActiveForm::begin([
'options' => ['data' => ['pjax' => true]],
// more ActiveForm options
]);
// ActiveForm content
ActiveForm::end();
Pjax::end();
提示:小心Pjax 小部件内的链接,因为响应也会在小部件内呈现。为避免这种情况,请使用
data-pjax="0"
HTML 属性。
在处理文件和提交按钮值时使用jQuery.serializeArray()
存在已知问题,这些问题不会得到解决,而是被弃用,转而使用 HTML5 中引入的FormData
类。
这意味着对使用 ajax 或Pjax 小部件的文件和提交按钮值的唯一官方支持取决于浏览器对FormData
类的支持。
下一节验证输入处理服务器端提交的表单数据的验证,以及 ajax 和客户端验证。
要了解有关表单更复杂用法的更多信息,您可能需要查看以下部分
发现错别字或您认为此页面需要改进?
在 github 上编辑它 !
注册或登录以发表评论。