フォロワー数 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`メソッドに配列を渡すことで、ウィジェットの構成方法に関するいくつかのオプションを指定できます。この場合、開始<form>タグで使用される追加のCSSクラスと識別IDが渡されます。使用可能なすべてのオプションについては、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']にログインフォームのすべての属性の配列が利用可能になります。

ヒント:フォームにモデルが1つしかない場合、入力名を簡素化するために、モデルの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のドキュメントによると、競合を引き起こす可能性のある予約済みの名前がいくつかあります。

フォームとその子要素は、submitlengthmethodなど、フォームのプロパティと競合する入力名またはIDを使用しないでください。名前の競合は、混乱を招くエラーを引き起こす可能性があります。ルールの完全なリストと、これらの問題についてマークアップを確認するには、DOMLintを参照してください。

上記の例でHtml::submitButton()で行われているように、プレーンなHTMLまたはHtmlヘルパークラスのメソッドを使用して、フォームに追加のHTMLタグを追加できます。

ヒント:アプリケーションでTwitter Bootstrap CSSを使用している場合は、yii\widgets\ActiveFormの代わりにyii\bootstrap\ActiveFormを使用することをお勧めします。前者は後者から拡張され、フォーム入力フィールドの生成時にBootstrap固有のスタイルを使用します。

ヒント:必須フィールドをアスタリスクでスタイル設定するには、次のCSSを使用できます。

div.required label.control-label:after {
    content: " *";
    color: red;
}

リストの作成

リストには3つの種類があります。

  • ドロップダウンリスト
  • ラジオボタンリスト
  • チェックボックスリスト

リストを作成するには、アイテムを準備する必要があります。これは手動で行うことができます。

$items = [
    1 => 'item 1', 
    2 => 'item 2'
]

または、DBから取得することによって行うことができます。

$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で編集する !