jQuery UI TabsとjQuery Form Plugin
jQuery UI/Tabsを使用してタブを作成し、タブの内容をAjaxで取得するようにしてみた。
やり方は単純に本家のサンプルを見ればわかるとおり、書き方としては単純にリンクを張っただけ。
<script type="text/javascript"> $(document).ready(function() { $("#tab > ul").tabs( {fx : {opacity :'toggle'}}); }); </script> // ~省略~ <div id="tab" class="flora"> <ul> <li><a href="#fragment-1"><span>トップ</span></a></li> <li><a href="#fragment-2"><span>日記</span></a></li> <li><s:link href="/image/"><span>画像アップロード</span></s:link></li> <- ここがAjaxなコンテンツ </ul> <div id="fragment-1">静的なトップの内容</div> <div id="fragment-2">静的な日記の内容</div> </div>
その先に何かの入力画面でそこから確認、完了画面へ進む機能を作りたい。
ただ、せっかくタブの内容に入力画面を表示したのに通常の<form>タグでの遷移を行ってしまうと確認画面の方にもタブを作成しなければならなくなってしまう。それかタブの中に表示した画面はすべてAjax等で遷移しない作りにしないといけなくなる。
そこでjQuery Form Pluginと組み合わせれば通常の遷移する機能を作ってその<form>タグをAjax化すれば良いということに気がついた。
が
更新するtarget指定がjQuery UI Tabsで作るとタブの数などで動的に変わってid属性で指定できない。
<s:form styleId="targetForm"> <input type="text" name="email" value=""> <input type="submit" value="確認"/> </s:form> <p> <script> <!-- $('#targetForm').ajaxForm({target: 'ここに何を指定するのが問題'}); --> </script> </p>
そこで何とかタブの数や並び順が変わっても大丈夫な指定方法は無いかと色々見ていたところ、jQuery UI Tabsではタブのコンテンツ部分にはCSSのクラスとして「ui-tabs-panel」というのが付くようになっているようだ。そして表示されていないタブのコンテンツにはさらに「ui-tabs-hide」というのが付いている。
ということで以下のようにすればとりあえず期待通りに動いた。
$('#targetForm').ajaxForm({target: '.ui-tabs-panel:not(.ui-tabs-hide)'});
こんなことをしなくても別に正しいやり方があるのかなぁ。
今回の件でChromeとFirefoxの挙動が違うところに気がついた。通常の遷移する画面で以下のような画面を作っていたのだがFirefoxでは動いたがChromeでは動かなかった。
<html> <head> // 最初はheadタグの中に書いていた <script type="text/javascript"> $(document).ready(function()) { $('#targetForm').ajaxForm({target: '.ui-tabs-panel:not(.ui-tabs-hide)'}); } </script> </head> <body> // コンテンツ </body> </html>
挙動としてはChromeで上記のHTMLをAjaxで取ってきて表示とやると<body>タグの中しか評価されない感じ。結果として<head>の中に書いたJavaScriptがうまく動かなかった。それを回避するために<body>の中に<script>タグを書いて対処した。
いつものことだがこれが正しいやり方なのか分からない。
<html> <head> </head> <body> // コンテンツ <p> // bodyタグの中に記述するように修正 <script type="text/javascript"> <!-- $(document).ready(function()) { $('#targetForm').ajaxForm({target: '.ui-tabs-panel:not(.ui-tabs-hide)'}); } --> </script> </p> </body> </html>