変換後、外側の要素に、内側と同じclass属性を付けたい
はじめに
バリデーションエラー時、inputタグに対してサーバ側でclass属性を追加することがあるかと思います。
jQuery Mobile使用時、「type="text"」の場合は素直にclass属性によって見た目が変わるのですが、「type="search"」の場合は、期待通りに見た目が変わらなかったのでメモ。
期待通りに行かない理由
type="search"の場合、jQuery Mobileによって、DOMにタグが追加されます。
このため、素直にinputタグのみにclassを指定すると、追加されたタグにスタイルが適用されないのです。
・変換前
<input type="search" class="error"></input>
・変換後(divタグが外側に入って装飾が行われる。)
<div class="ui-input-search ui-shadow-inset ui-btn-corner-all ui-btn-shadow ui-icon-searchfield ui-body-c"> <input type="text" data-type="search" class="error ui-input-text ui-body-c"> (略) </div>
対策
外側のDIVタグにもバリデーションエラー用classを付ければ、コントロール全体の見た目を変更できます。
ただし、外側のDIVタグは、サーバサイドでHTMLを生成した時点では、当然存在しません。よって、jQuery Mobileによる変換後、JavaScriptでバリデーションエラー用classを付けます。
例えば、以下のような実装になります。
(もう少し短く書けるとは思いますが、そこはおいておいてください)
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="js/jquery/jquery.mobile-1.2.0.css" /> <script src="js/jquery/jquery.js"></script> <script src="js/jquery/jquery.mobile-1.2.0.js"></script> <style type="text/css"> div.error { background-color: red; } </style> <script type="text/javascript"> $('#page').live('pagebeforeshow',function(event, ui){ //jQuery Mobileによる変換後に付与されるclass属性を使用して、処理対象のタグを特定する。 var searchElm = $("[data-type='search']"); jQuery.each(searchElm, function() { //バリデーションエラーが発生した検索用フィールドのみ処理 //(すなわち、class属性にerrorが付与されているフィールドのみ処理) if($(this).hasClass("error")){ //親のdivタグを取得。 //多分常に検索フィールド用の装飾用のDIVタグは存在するが、なかったら変な風に色が付いてしまうので、検索フィールド用の装飾用のdivタグのみを拾えるよう、classを指定しておく。 var divElm = $(this).parent("div.ui-input-search"); jQuery.each(divElm, function() { //外側のdivタグにclass属性を追加する。 $(this).addClass("error"); }); } }); }); </script> </head> <body> <div data-role="page" id="page" class="type-home"> <div data-role="content"> <input type="search" class="error"></input> </div> </div> </body> </html>
さいごに
最初、「type="search"」→「type="text"」の変換が行われることに気づかなかったため、上手く要素を選択できず、苦労しました。