4 フォロワー

表形式の入力を収集する

単一のフォームで同じ種類の複数のモデルを処理する必要がある場合があります。たとえば、各設定が名前と値のペアとして格納され、Setting アクティブレコード モデルで表現される複数の設定などです。この種のフォームは、「表形式入力」とも呼ばれます。これに対して、異なる種類の異なるモデルを処理する方法は、「複数のモデルを持つ複雑なフォーム」のセクションで説明されています。

以下に、Yii で表形式入力を実装する方法を示します。

対処する必要のある状況は3つあり、それぞれ少しずつ異なる方法で処理する必要があります。

  • データベースから固定されたレコードセットを更新する
  • 動的な新しいレコードセットを作成する
  • 1つのページでレコードを更新、作成、削除する

以前に説明した単一モデルのフォームとは対照的に、ここではモデルの配列を扱っています。この配列は、テーブルのようなスタイルで各モデルの入力フィールドを表示するためにビューに渡され、一度に複数のモデルのロードと検証を可能にする yii\base\Model のヘルパーメソッドを使用します。

固定されたレコードセットの更新

まず、コントローラのアクションから始めましょう。

<?php

namespace app\controllers;

use yii\web\Controller;
use app\models\Setting;

class SettingsController extends Controller
{
    // ...

    public function actionUpdate()
    {
        $settings = Setting::find()->indexBy('id')->all();

        if ($this->request->isPost) {
            if (Setting::loadMultiple($settings, $this->request->post()) && Setting::validateMultiple($settings)) {
                foreach ($settings as $setting) {
                    $setting->save(false);
                }
                return $this->redirect('index');
            }
        }

        return $this->render('update', ['settings' => $settings]);
    }
}

上記のコードでは、データベースからモデルを取得する際に indexBy() を使用して、モデルの主キーでインデックスされた配列を作成しています。これらは後でフォームフィールドを識別するために使用されます。Model::loadMultiple() は、POST から送信されたフォームデータで複数のモデルを埋め、Model::validateMultiple() はすべてのモデルを一度に検証します。モデルを検証済みであるため、validateMultiple() を使用して、save()false をパラメータとして渡して、検証を二度実行しないようにします。

次に、update ビューにあるフォームです。

<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;

$form = ActiveForm::begin();

foreach ($settings as $id => $setting) {
    echo $form->field($setting, "[$id]value")->label($setting->name);
}

echo Html::submitButton('Save');

ActiveForm::end();

ここでは、各設定に対して名前と値を持つ入力欄をレンダリングしています。Model::loadMultiple() がどのモデルにどの値を入力するかを判断する方法であるため、入力名のインデックスを適切に追加することが重要です。

新しいレコードの動的なセットの作成

新しいレコードの作成は、モデルをインスタンス化する部分を除いて、更新と似ています。

public function actionCreate()
{
    $settings = [];
    if ($this->request->isPost) {
        $count = count($this->request->post($setting->tableName()));
        for ($i = 0; $i < $count; $i++) {
            $settings[$i] = new Setting();
        }
        if (Setting::loadMultiple($settings, $this->request->post()) && Setting::validateMultiple($settings)) {
            foreach ($settings as $setting) {
                $setting->save(false);
            }
            return $this->redirect('index');
        }
    }
    $settings[] = new Setting();

    return $this->render('create', ['settings' => $settings]);
}

ここでは、ビューに常に少なくとも1つのテキストフィールドが表示されるように、デフォルトで1つのモデルを含む初期の $settings 配列を作成します。さらに、受け取った可能性のある入力行ごとに追加のモデルを追加します。

ビューでは、JavaScriptを使用して新しい入力行を動的に追加できます。

1つのページでの更新、作成、削除の組み合わせ

注:このセクションは開発中です。

まだコンテンツはありません。

TBD(後日追記)

タイプミスを見つけたり、このページを改善する必要があると思われますか?
githubで編集してください !