表形式入力の収集

ときとして、ユーザの入力をバッチモードで集めたいと思う事があります。 すなわち、ユーザは複数のモデルインスタンスの情報を入力でき、それらを一度にまとめて送信できる、という方式です。 こういった場合の入力フィールドは HTML テーブルで提供される事が多いので、ここではこれを 表形式入力 (tabular input) と呼びます。

表形式入力では、まず初めに、データを挿入するか更新するかに従って、モデルインスタンスの配列を新規に作成またはデータベースから読み出します。 次に、ユーザの入力したデータを $_POST 変数から収集して、各モデルへ割り当てます。 単一のモデルの場合とのわずかな違いは、入力データの収集のために、$_POST['ModelClass'] ではなく $_POST['ModelClass'][$i] を用いる点です。

public function actionBatchUpdate()
{
    // 一括で更新をするために複数のアイテムを収集します。
    // 各アイテムは 'Item' モデルクラス だと仮定します。
    $items=$this->getItemsToUpdate();
    if(isset($_POST['Item']))
    {
        $valid=true;
        foreach($items as $i=>$item)
        {
            if(isset($_POST['Item'][$i]))
                $item->attributes=$_POST['Item'][$i];
            $valid=$item->validate() && $valid;
        }
        if($valid)  // 全てのアイテムが検証を通ったら
            // 何かをする …
    }
    // 表形式入力を収集するためのビューを表示
    $this->render('batchUpdate',array('items'=>$items));
}

アクションが準備できたので、HTML テーブルとして入力フィールドを表示するための batchUpdate ビューの作成に取り掛かる必要があります。

<div class="form">
<?php echo CHtml::beginForm(); ?>
<table>
<tr><th>Name</th><th>Price</th><th>Count</th><th>Description</th></tr>
<?php foreach($items as $i=>$item): ?>
<tr>
<td><?php echo CHtml::activeTextField($item,"[$i]name"); ?></td>
<td><?php echo CHtml::activeTextField($item,"[$i]price"); ?></td>
<td><?php echo CHtml::activeTextField($item,"[$i]count"); ?></td>
<td><?php echo CHtml::activeTextArea($item,"[$i]description"); ?></td>
</tr>
<?php endforeach; ?>
</table>
 
<?php echo CHtml::submitButton('Save'); ?>
<?php echo CHtml::endForm(); ?>
</div><!-- form -->

上記では、CHtml::activeTextField をコールする際の二番目のパラメータとして、"name" の代わりに "[$i]name" を使用している事に注意してください。

もし何か検証にエラーがある場合は、単一モデルでの入力の際に述べたのと同様に、対応する入力フィールドが自動的にハイライトされます。

$Id$

Be the first person to leave a comment

Please to leave your comment.