WHAT'S NEW?
Loading...
ラベル フォーム の投稿を表示しています。 すべての投稿を表示
ラベル フォーム の投稿を表示しています。 すべての投稿を表示
« 11日 msng氏「CakePHPでデバッグレベルが0の時だけ発生するエラー
Datasourceを使い倒す」kaz_29氏 13日 »

スタンド名「スパスティック」
特技「空気読まない」
俺のスタンドだ。距離はゼロメートル。
むしろ俺自身がスタンド。

さて、CakePHP Advent Calendar 12日目の担当だ。
なんで12日目を選んだかというと、12という数字がすきだからだ。
それにyamlよりiniファイル好きな俺としては、12はドメスティックに愉快だとおもわないか?

ま、そんな話は完全に無視して良い。

12ということで、テストしたCakePHPのバージョンは1.2を使用してみた。

ところでテーマだけど、俺はフォームヘルパーに関して、ざっくりとやってみたい。

完全にオレオレフレームワークでプロプライエタリな開発環境だが、いい加減メジャーなフレームワークに移行したいといういろいろな開発者、もしくはその関係者に対して、俺はCakePHPがMVCフレームワークの中でもかなりの勢いがあるし、何しろ俺がやってるから俺が直接教えることができるんだ!的な普及活動をしているんだけど、質問の多くを占める、inputタグに関する滞りを払拭してみたいと思った。

CakePHPのバリデーションは非常に便利だ。1.1時代はかなりショボすぎる感があったけど、1.2になって、直感的にかなり分かりやすいものになった。

具体的に例を出すと、例えばメールフォームがあたっとして、内訳が
  • 件名:subject
  • 宛先:to
  • 本文:body
があったとする。
それらにバリデーションを入れる場合、例えば件名は空禁止、toはemail形式、本文は最低5文字(実際には5バイト)入力するのを強制する場合は、以下のような内容でモデルを設定することになる。
class Mail extends AppModel {
  public $name = 'Mail';
  public $validate = array(
    // 件名のバリデーション
    'subject' => array(
      // 空入力
      array(
        'rule' => array('notEmpty'),
        'message' => '件名を入力してください',
        'last' => true,
        'required' => true,
      ),
    ),
    // 宛先のバリデーション
    'to' => array(
      // email形式
      array(
        'rule' => array('email'),
        'message' => '正しいメールアドレスを入力してください',
        'last' => true,
        'required' => true,
      ),
    ),
    // 本文のバリデーション
    'body' => array(
      // 入力文字数
      array(
        'rule' => array('minLength', 5),
        'message' => '最低5バイトは入力してください',
        'last' => true,
        'required' => true,
      ),
    ),
  );
記事を書いた後CakePHP武将のecworks_masap氏に言われて気がついたんだけど、1点注意!「5バイト」なんて文字は運用では使わない。ユーザに対して「バイト」なんて単位を書くのはおかしいからだ。しかしここではあくまで例として(minLengthを使ったため)コードとの整合性を重視し、あえて「5バイト」と書いてみた。
各フィールド名の中には複数の条件を入れることができる。そしてそれらの条件1個1個に名前を付けることもできるが、今回は1つのフィールドに1個しか条件を入れてないので、特に名前は付けていない。

だから、'subject' => array()の中にいきなりarray()で条件をかいている。

各条件のコメント分にも書いてあるような内容を名前にしておくとあとで便利になる場合がある。もしくは厳密に名前を独自に付けることによるコントローラ側でのバリデーション判別などする場合も便利になる。具体的には以下のように、いきなり
array()ではなく、名前を指定してarray()を代入する。
'subject' => array( 'empty_case' => array( 'rule' => ・・・・・・ 'required'=> true));

どうしてもCakePHP内のビューやコントローラ内で、php自体によってHTMLタグを生成したいという人以外は、可能な限り以下の方法をとると、寝覚めが良いはずだ。
  • HTMLタグには極力アトリビュートを付けない
  • 付けるのは少しのIDといくつかのclass程度
  • 当然TABLEタグでレイアウトなんぞは組まない
 どういう事かというと、吐出されたHTMLタグまでをphpで制御しようというのはおかしいと思っているから、そういう完全に見た目という意味でのビューは、jQueryなどのクライアントサイドスクリプトでやっちまえばいいだろう。

こういう考えで開発していくと、CakePHPのFormヘルパーが吐き出す、そっけなく簡素で女々しいHTMLタグも、むしろそれでいてくれてありがとうと思えるほど便利になる。

さて、俺が何を言いたいのか、わかっていただけてるかな。


「CakePHPのFormヘルパーで出力されたラジオボタンを整列したい」という問に対してphpでHTMLタグを出力させ、cssなどで整形するという解決

これ、完全に、デザイナの領域なのに、開発側で対応しようというのがそもそもの間違いであり、こういった作業は往々にして大した結果に至らない。要するに解決にならない場合が多いのではないだろうか。

とにかく、無理矢理が良くない、ということを言いたい。

CakePHPはほぼphpで書かれたMVCだけど、Vから先のことはこう考えるとよいだろう。

JavaScriptで、HTML(DOM)とCSSをコントロールする

だ。俺が言いたいことがわかっていただけたかな。

CakePHPのMVCよろしく、jQueryをコントローラとし、DOMで拾う内容をモデルとし、それらを吐き出すためにcss、場合によってはHTMLで整形してビューとする、というような流れを考えたほうが良い。

このほうが何しろソースは綺麗になるわ、サーバの負荷分散にもなるわ、デザイナのスキルアップにもなるわ、開発者の手間も省けるわ、で、いいことずくめだ。どうしてやらない?と俺は聞きたい。

ちなみにこの方法が実現できない様な糞ブラウザ(IE)を上司から要求されたら、そいつにこう言ってあげるとよいだろう。

「おや?部長、口からクソがはみ出てますよ?」

と。


というわけで、前置きが長くなったけど、CakePHPで素直に出力したcheckboxを、DOM操作で整列させるjQueryプラグインを作ったので披露してみたい。

CakePHP側では以下のようなビューを使用することとする。
echo $form->input('hobbies', array(
      'type' => 'select',
      'multiple' => 'checkbox',
      'options' => $masters['hobby'],
      'div' => true,
      'label' => false,
    ))
$masters['hobby']には、find('list')などして生成したマスタデータが入っている。

そしてこのビューを素直に表示させたときのサンプルがこうだ。
 まぁこんな感じだよな。当然縦に長くなる。

正直いって、生粋の開発者として長年生きてる人にとっては、この時点でこれ以上いじるのはやめたほうが良い。ろくなことがない。デザイナがやりにくくなるだけだ。2列にしてと言われても、開発者はやっちゃだめだ。