6月 04
13.checkbox問題
で、まあ、そうっすね、とりあえず、入力フォームの、Favorite(好きな物)がmultipleセレクトになってるのを直しますか。
日本では複数選択にセレクトなんてほとんど使われないですよね。
こうなっているのを、
echo $form->input('Favorite');
こうします。
echo $form->input('Favorite', array('multiple'=>'checkbox', 'label' => '好きな物'));
これでとりあえずチェックボックスになるんですが、
ここで大変な問題が!!
ブラウザで見ると、「チェックボックスがずれてしまう」
例のCSSで、block化して左floatしたlabelとinput要素ですが、この部分のソースとしては以下のようになっている訳で、
<div class="input select"> <label for="FavoriteFavorite">好きな物</label> <input type="hidden" name="data[Favorite][Favorite]" value="" /> <div class="checkbox"> <input type="checkbox" name="data[Favorite][Favorite][]" value="1" id="FavoriteFavorite1" /> <label for="FavoriteFavorite1">apple</label> </div> <div class="checkbox"> <input type="checkbox" name="data[Favorite][Favorite][]" value="2" id="FavoriteFavorite2" /> <label for="FavoriteFavorite2">orange</label> </div> <div class="checkbox"> <input type="checkbox" name="data[Favorite][Favorite][]" value="3" id="FavoriteFavorite3" /> <label for="FavoriteFavorite3">grape</label> </div> </div>
どうにも最初のチェックボックスにしかfloatの効果が及ばないようで、2個目以下がずれてしまっています。
どうしたらいいんでしょう?
ということで対策案その1。
上記の
<div class="input"> <label for="..."></label> <input type="..." /> </div>
という構造を無理矢理 tr td のテーブル構造にしてしまう案。
jQuery を使いますのでダウロードして解凍しておいてください。
/app/webroot/js 以下に jquery.js としてコピーしておきます。ついでに jQuery の form プラグインもダウンロードして、 form.js として置いておきます。
で、さらにここに新規に util.js という名前でファイルを作ります。
中身は、こんな感じで。
$(document).ready(function() {
var pval = $('input[type=password]').val();
$('div.input').each(function(){
var line = $(this).html();
line = line.replace(/label>/i, 'label></th><td>');
$(this).replaceWith('<tr><th>' + line +'</td></tr>');
});
$('form[id$=Form] tr').wrapAll(document.createElement("table"));
$('input[type=password]').attr("value", pval);
});
解説:
4行目:div class=”input”で囲まれる部分についてループします
5行目:上記のdivで囲まれた部分のhtmlを変数に入れて
6行目:lableタグの後ろに</th><td>をいれます
7行目:最初と最後に<tr><th>、</td></tr>をくっつけてはさみます。
9行目:trがむきだしになってるので、tableタグで囲みます。
3行目と10行目:IEだとパスワードの値が入ってこないのでその対策
で、 add.ctp の一番上に、
<?php echo $javascript->link(array('jquery','form','util'), false); ?>
を追加しておきます。
members_controller.php の helpers のところに ‘Javascript’ を追加します。
var $helpers = array('Html', 'Form', 'Javascript');
ブラウザで確認してみると、ちゃんとテーブルになっています。ソースは元のままですが・・。
テーブルのねつ造ですね。
まあ、そんな裏技みたいなことしなくても・・・。
という人は対策案その2.
ビューで普通にテーブルで組んで、
<tr>
<td>お名前</td>
<td><?php echo $form->text("Member.name", array("size" => 50, "maxlength" => 50)) ?><br />
<?php echo $form->error("Member.name") ?></td>
</tr>
という具合に、こつこつ作っていけばいいと思います。今までやってたことに比べればたいした手間じゃないでしょう。
で、ついでなので、さっきのJavascriptの util.js の $(document).ready(function() {});
の中に、以下を追加しておきます。
$('#back').click(function(){
$('#MemberMode').val('back');
$("#MemberConfirm").submit();
});
解説:
1行目:id=”back” のボタンをクリックしたら
2行目:id=”MemberMode” の valueを “back” にして
3行目:id=”MemberConfirm” のフォームをサブミットする
members_controller.php の前回追加したif~elseの中に以下のelseifを追加します。{}の中は空でいいです。
if ($this->data['Member']['mode'] == 'confirm') {
//・・・
}elseif ($this->data['Member']['mode'] == 'back') {
} else {
//・・・
}
これで、確認画面から入力画面への「戻る」ボタンが動くようになります。
あとは、そうっすね、誕生日の入力フォームが洋風で気に入らないので、以下に変更します。
echo $form->input('birthday');
こうなってるのを、
echo $form->input('birthday', array('dateFormat'=>'YMD','maxYear'=>date('Y'),'minYear'=>date('Y')-100,'monthNames'=>false, 'label' => array('text'=>'誕生日', 'for'=>'MemberBirthdayYear')));
こうに。
'for'=>'MemberBirthdayYear'
の指定は、やってみると分かりますが、これをしないと、入力画面でタブ送りした時に、フォーカスが年月日の月に飛んでしまうからです。
最後、一応公開側は完了画面を出すことにするので、「登録されました」みたいな適当なビューを complete.ctp という名前で作っておいて、
members_controller.php のaddアクションのsaveの後の、
$this->redirect(array('action'=>'index'));
となっているのを、
$this->redirect(array('action'=>'complete'));
に変更し、
function complete() {
}
を追加しておきます。
次、どうもやはり「好きな物」、周りがおかしいですね。
