条件によってテキストボックスの数が1個から10個に変化するフォームがあるとします。
(item_cd1,item_cd2, ,item_cd10等)
このフォームをバリデートする場合、どうするのがいいのでしょうか?
テンプレートのテキストボックスのnameに変数を使うとバリデートできないので、
条件により表示するようにしたテキストボックスをテンプレートに10個書いて、
バリデーションのyamlに10個の条件を書けばできますが、数が多くなれば大変です。
(item_cdのバリデート条件は一緒なので同じものを10回書くのも・・・・)
何かいい方法はないでしょうか?
宜しくお願いします。
> 条件によってテキストボックスの数が1個から10個に変化するフォームがあるとします。
> (item_cd1,item_cd2, ,item_cd10等)
> このフォームをバリデートする場合、どうするのがいいのでしょうか?
私は、そのような場合、次のように配列として入力を受け取るようにしています。
<ul>
<li><input type="text" name="item_cd[]" /></li>
......
<li><input type="text" name="item_cd[]" /></li>
</ul>
このようにしておいて、配列の中に重複した値がないかどうかチェックしたり、
最低1つは値が入力されていることを確認したりもしています。
ただし、この場合、item_cd のそれぞれの値に対してバリデーションを行うのが面倒です。
バリデーションの処理を自分で書いて WithMethod で呼ぶようにするか、
標準のバリデータを少し書き換えて、配列に対応させないといけないと思いますので、
条件を 10 個書いて済ませられるのなら、その方が早いかもしれません。
良い方法かどうか分かりませんが、参考になれば幸いです。
revuloさん、レスありがとうございます。
> 私は、そのような場合、次のように配列として入力を受け取るようにしています。
>
> <ul>
> <li><input type="text" name="item_cd[]" /></li>
> ......
> <li><input type="text" name="item_cd[]" /></li>
> </ul>
>
> このようにしておいて、配列の中に重複した値がないかどうかチェックしたり、
> 最低1つは値が入力されていることを確認したりもしています。
この方法は私も検討しましたが、バリデーションでエラーの場合、
それぞれの値をテキストボックスに再度表示させる方法がわからず、
あきらめました。
revuloさんはどうやって解決していますか?
> この方法は私も検討しましたが、バリデーションでエラーの場合、
> それぞれの値をテキストボックスに再度表示させる方法がわからず、
> あきらめました。
> revuloさんはどうやって解決していますか?
私は Smarty を使っているので、あまり参考にはならないと思いますが、
改めてテンプレートを見てみたところ、このように書いていました。
<?php for ($i = 0; $i < count($this->_tpl_vars['items']); $i++) : ?>
<li><input type="text" name="items[]" value="<?php if (isset($this-
>_tpl_vars['items'][$i])) echo $this->_tpl_vars['items'][$i] ?>" /></
li>
<?php endfor; ?>
PHP で直に書いています。もっとスマートに書けそうな気がしますが、
たしか、isset() による判定をしたいがために、こう書いたのだと思います。
おそらく Flexy ならもっと素直に書けるのではないでしょうか?
補足ですが、Flexy ならこんな感じで書けないでしょうか?
今、試せる環境がないので適当に書いています。
<ul flexy:foreach="items,item">
<li><input type="text" name="items[]" {if:item}value="{item}"{end:}
flexy:ignore="yes" /></li>
</ul>
実のところ、私は Flexy をあまり使っていないので、間違っていたらすみません。
revuloさんの方法を参考に、一応できました。
前提条件として、
stdClassの$obj(プロパティ$cd,$item)のリストがあります。
$cdには既に配列で値が入っています。
これを一覧表示して、$itemにテキストボックスで入力したいのです。
テンプレートで、item[]と配列で受け取るようにすると、
<ul flexy:foreach="obj.cd,key,val">
<li>{obj.val}</li>
<li><input type="text" name="item[]"
value="{func.aryval(obj.item,key)}"
flexy:ignore="yes" /></li>
</ul>
ここで、func.aryval()は、テンプレートに渡した関数です。
aryval(array(),key)でkeyの値を返すだけです。
後は、WithMethodでバリデートできました。
有り難うございました。