Perl(Amon2)で、Formに自動でエラーメッセージを埋め込みたい。
2015年3月5日
FormValidator::Liteとかでバリデートした結果でエラーがあった場合に、自動でエラーを埋め込むような感じにしたいなーと。
で、とりあえず書いてみたプラグインが下記。
package MyApp::Web::Plugin::HTML::FillInFormError; use strict; use warnings; use utf8; use Amon2::Util; use HTML::Filter::Callbacks; sub init { my ( $self, $c ) = @_; Amon2::Util::add_method($c, 'fillin_formerror', \&_fillin_formerror); } sub _fillin_formerror { my ( $c, $error ) = @_; $c->add_trigger( 'HTML_FILTER' => sub { my ($c, $html) = @_; my $f = HTML::Filter::Callbacks->new(); $f->add_callbacks( '*' => { start => sub { my $self = shift; if ( $self->attr('name') ) { my $name = $self->attr('name'); if ( exists $error->{ $name } ) { $self->prepend('<p class="error">'. $error->{ $name } .'</p>'); } } }, }, ); $html = $f->process($html); return $html; }, ); return; } 1;
HTML::Filter::Callbacksっていう、タグを置換するようなモジュールがあったんでこれを使って、
nameが一致したinputタグの前にprependでpタグ(エラーメッセージ)を追加。
で、上記のプラグインをロード。
__PACKAGE__->load_plugins( '+MyApp::Web::Plugin::HTML::FillInFormError', );
これをエラー発生時に呼び出す。
sub index { my ( $class, $c ) = @_; # FormValidator::Liteの結果 my $error = { age => 'error message!!' }; $c->fillin_formerror( $error ); $c->render('index.tx'); }
で、上で読み込んでるindex.txは下記のような感じ。
<form> <input type="text" name="age"> </form>
これを実行してみると、
<form> <p class="error">error message!!</p><input type="text" name="age"> </form>
って感じなhtmlが出力されるはずです。
と、ここまで書いてみて、
実際はFillinFormと一緒に使う事になるんですが、このまま使うと生成されたhtmlを2回パーズする事になるんでパフォーマンス的にイケてない気が・・。
ここはまだまだ検討の余地がありそう。。