Yuriko.Net 個別記事

2006-10-13
晴れ

QuickForm + Template_Flexy で動的フォームを作るのに悩む

ゆりこ による 00:02:12 の投稿
カテゴリー: ソフトウェア

Yuriko.Net は独自ウェブログシステムに移行しましたが、運営者が使う管理画面はまだ完成していません;-) 記事の作成・編集、カテゴリーの追加・編集、イベントの追加・編集は可能ですが、それ以外のデーターは phpMyAdmin 経由で MySQL データーベースを直接いじっています。phpMyAdmin が優秀なので、自前の管理画面がなくてもウェブログの管理ができてしまうため、開発をあわてる必要がないのです;-)

開発が遅い理由の1つに、わたしの PEAR ライブラリーの理解が十分でないことがあります。とくに、HTML_QuickFormHTML_Template_Flexy を組み合わせる部分が悩みの種です。どちらも高機能なパッケージで使いこなすのが大変な上に、QuickForm で作ったフォーム部品のレンダリングを Flexy でやらせるという組み合わせ技になると、ドキュメントが非常に少なくて試行錯誤しています。

フォーム部品が固定の場合は使い方がなんとか分かりましたが、「記事一覧」のようにフォーム部品の数が変化する場合は完成していません。フォーム部品を描画させるところはできたのですが、フォームの入力内容を検証するルールの設定が分かりません。そのため、正当な値を入れた場合は先に進みますが、不正な値を入れた場合は処理がおかしくなってします。どうせ管理画面は自分だけが使うものなので、値の検証がええ加減でもいいわけですが、やはりきちんと作りたいものです。

フォーム部品を作る部分のコードは以下のような感じです (説明用に抜粋しています)。

$form = new HTML_QuickForm('ev-mod', 'post');
$rows = array($form->addGroup(array(), 0, NULL, NULL)); // add dummy
foreach ($list as $e) {
    $cols = array();
    if (year_of($e['date']) < 1900) {
        $e['date'] = '2000-01-01';
    }
    $end = $e['end'] ? $e['end'] : $e['date'];
    $cols[] = $form->createElement('static', 'target', NULL, $e['id']);
    $cols[] = $form->createElement('date', 'date', '', 
        array('language' => 'ja', 'format' => 'Y年m月d日', 
        'minYear' => year_of($e['date']) -5, 
        'maxYear' => year_of($e['date']) +5));
    $cols[] = $form->createElement('checkbox', 'has_end', NULL, 
        '終了日を設定');
    $cols[] = $form->createElement('date', 'end', '', 
        array('language' => 'ja', 'format' => 'Y年m月d日', 
        'minYear' => year_of($end) -5, 
        'maxYear' => year_of($end) +5));
    $cols[] = $form->createElement('textarea', 'desc', '説明', 
        array('cols' => 48, 'rows' => 3));
    $cols[1]->setValue($e['date']);
    $cols[2]->setValue(isset($e['end']));
    $cols[3]->setValue($end);
    $cols[4]->setValue($e['description']);
    $rows[] = $form->addGroup($cols, intval($e['id']), NULL, NULL);
}
$form->addGroup($rows, 'list', NULL, NULL);
$form->addElement('submit', 'back', '戻る');
$form->addElement('submit', 'modify', '修正する');
$rules = array();
foreach($rows as $id => $cols) {
    $rule[$id]['date'][] = array('開催日を入力してください。', 'required', NULL, 'server');
    $rule[$id]['desc'][] = array('説明を入力してください。', 'required', NULL, 'server');
    $rule[$id]['desc'][] = array('説明は512文字以内です。', 'maxlength', 512, 'server');
}
$form->addGroupRule('list', $rules);
$rend =& new HTML_QuickForm_Renderer_ObjectFlexy($page);
$form->accept($rend);
$page->mod_form = $rend->toObject();
$output = new HTML_Template_Flexy();
$output->compile('events.html');
$output->outputObject($page);

そしてテンプレート (events.html) の抜粋は次の通り。

{mod_form.outputHeader():h}
{mod_form.hidden:h}
<table class="list" border="1" cellspacing="0">
<caption>イベント修正</caption>
<thead>
  <tr><th>ID</th><th>開催日</th><th>終了日</th><th>説明</th></tr>
</thead>
<tbody>
<tr flexy:foreach="mod_form.list,id,e">
<td class="id">{id}</td>
<td class="mod-date">{e.date.html:h}
<div class="error" flexy:if="e.date.error">{e.date.error}</div></td>
<td class="mod-date">{e.has_end.html:h}<br />{e.end.html:h}
<div class="error" flexy:if="e.end.error">{e.end.error}</div></td>
<td class="desc">{e.desc.html:h}
<div class="error" flexy:if="e.desc.error">{e.desc.error}</div></td>
</tr>
</tbody>
</table>
<div class="error" flexy:if="mod_form.errors.list">
{mod_form.errors.list}</div>
<div>{mod_form.back.html:h} {mod_form.modify.html:h}</div>
</form>

addGroup を2重にすることで、テンプレートは作りやすくなりましたが、ルールが上手く動きません。addGroupRule でうまくいきそうなんですが、これでは動作していません。うーん困った。

なお、QuickForm でのクライアント側検証は使わない主義です;-) (続きはリンク先エントリに移設)

トラックバック・コメント

コメントはありません。

上に戻る

ごめんなさい。現在コメントフォームは閉じられています。

上に戻る