3 个关注者

创建表单

基于 ActiveRecord 的表单:ActiveForm

在 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 文档。

ActiveField

为了在表单中创建表单元素,以及该元素的标签和任何适用的 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,例如submitlengthmethod。名称冲突会导致令人困惑的错误。有关规则的完整列表以及如何检查您的标记是否存在这些问题,请参见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

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 上编辑它 !