いわゆるフォームメールは、デザイナーさんに完全にお任せしたいものの筆頭です。
でも、意外と嫌らしくて、結局プログラマーが手を入れる、なんてことになりがちです。
その最大の理由は、Validationでしょうか。
いろいろなフォームメールシステムを見てきましたが、どんなに簡単である、と謳っているものでも、フィールド定義が独自のXMLとかだったりします。そんな独自のXML仕様書を読まなければならないと考えただけで頭が痛くなる人も少なくないでしょう。
かといって、フォームを自動生成するタイプのフォームメール(XOOPSであればliaiseとか)は、デザイナーさんにとって使い物になりません。なぜなら、彼らはHTMLを自由に書くのが仕事だからです。
…というわけで、アイデアとしてはずっと温めていたHTMLによるValidationを試しに最新のpicoに実装してみました。
試しに pico-1.50 で、こんなコンテンツを作ってみてください(オプションはSmartyのみON)。もちろん、HTMLの部分は自由に記述できますが、checkboxおよびradioは、入力値を保存できません。(まだ作りかけ)
※ 1.51でcheckboxとradioにも対応しました
※※ 1.51で仕様変更があったので、サンプルコンテンツも変更しました。
もう少し細かな注意点は次回以降に書きます。
<{capture}>
<form>
<label for="yourname">お名前</label>
<input type="text" name="yourname" id="yourname" class="required" />
<br />
Fruit:
<label for="checkbox_orange">orange</label>
<input type="checkbox" name="favorite_fruit[]" id="checkbox_orange" class="required" value="orange" />
<label for="checkbox_apple">apple</label>
<input type="checkbox" name="favorite_fruit[]" id="checkbox_apple" class="required" value="apple" />
<label for="checkbox_pear">pear</label>
<input type="checkbox" name="favorite_fruit[]" id="checkbox_pear" class="required" value="pear" checked="checked" />
<br />
<label for="youremail">email</label>
<input type="text" name="youremail" id="youremail" class="email" />
<br />
<label for="selbox">SELECTサンプル</label>
<select name="selbox" id="selbox" class="required">
<option value="">-- select it --</option>
<option value="0">0</option>
<option value="1">1</option>
<option value="2" selected="selected">2</option>
<option value="3">3</option>
</select>
<br />
<label for="content">要件</label>
<textarea name="content" id="body"></textarea>
<br />
<input type="submit" value="内容確認" />
</form>
<{/capture}>
<{formmail}>
if( strstr( $fieldsetblock , $tag ) && preg_match( '#<legend[^>]*>([^<]+)</legend>#' , $fieldsetblock , $sub_regs ) ) {
if( strstr( $fieldsetblock , $tag ) && preg_match( '#<legend[^>]*>(.+)</legend>#' , $fieldsetblock , $sub_regs ) ) {
ここ、私は否定先読みを使ってとやってました。一応これで上手くいくかと思います。if( preg_match( '#<fieldset(?:(?!fieldset).)*'.preg_quote($tag).'.*</fieldset>#isU' , $form_html , $regs ) ) {
実は1.60くらいでバグかな?と思っていたのですが、なんやかんやで先送りになってました。その時点でご報告していればよかったですね・・・
<fieldset>と<legend>の間に</fieldset>が見つかったら終了、って正規表現がパッと書けなかったので、preg_split()でいったん分割しました。
if( preg_match( '#<fieldset(?:(?!fieldset).)*'.preg_quote($tag).'.*</fieldset>#isU' , $form_html , $regs ) ) {
GIJOE wrotes:
<fieldset>と<legend>の間に</fieldset>が見つかったら終了、って正規表現がパッと書けなかったので、preg_split()でいったん分割しました。
1.75aを試してみてください。
# いただいたコードが悪いってことはないのですが、<fieldset>のブロックという概念から外れてしまうので。
jidaikobo wrotes:
pico の survey プラグインで遊ぼう!の picoSurveyAssistant を書いていて気づいたんですが、pico の formmail プラグインで、checkbox や radio が複数あるフォームの場合、最初の要素の legend が、以降すべての checkbox と radio のタイトルとして、メールで送られているようでした。
// search the nearest <regend> for radio/checkbox
if( preg_match( '#<fieldset.*'.preg_quote($tag).'.*</fieldset>#isU' , $form_html , $regs ) ) {
if( preg_match( '#<legend[^>]*>([^<]+)</legend>#' , $regs[0] , $sub_regs ) ) {
$label = strip_tags( @$sub_regs[1] ) ;
}
}
// search the nearest <legend> for radio/checkbox
if( preg_match( '#<fieldset.*'.preg_quote($tag).'.*</fieldset>#isU' , $form_html , $regs ) ) {
if( preg_match_all( '#<legend[^>]*>([^<]+)</legend>#' , $regs[0] , $sub_regs ) ) {
$sub_regs_tmp = isset( $sub_regs[1] ) ? array_pop( $sub_regs[1] ) : '' ;
$label = strip_tags( $sub_regs_tmp ) ;
}
}
I hope to read more about this new feature and
possibilities to replace liaise or formulize.