Deep Insider の Tutor コーナー
>>  Deep Insider は本サイトからスピンオフした姉妹サイトです。よろしく! 
jQuery Mobile逆引きリファレンス

jQuery Mobile逆引きリファレンス

JavaScriptからフォーム要素を操作するには?

2014年9月4日

フォーム関連を自前で記述する場合、jQueryの知識を生かせるが、jQuery Mobile固有の注意点もある。その注意点を解説する。

  • このエントリーをはてなブックマークに追加

jQuery Mobileとは?

 jQuery Mobileは、jQueryを拡張するライブラリ(プラグイン)の一種で、名前の通り、スマホ/タブレットに代表されるモバイル対応アプリを開発するための機能を提供します。jQuery Mobileの導入方法や使い方、jQuery Mobileが提供する主要機能については、「jQuery Mobile逆引きリファレンス: jQuery Mobileを利用するには?」を参照してください。

 jQuery MobileはjQueryをベースにしていることから、自前でコードを記述しなければならない局面でも、jQueryで養った知識をほぼそのままに活用できます。「ほぼ」とは、jQuery Mobile固有の注意しなければならないポイントもあるということです。本稿では、その中でもフォームを操作する際の注意点にフォーカスして解説していきます。

フォーム要素の値を変更する

 JavaScript(jQuery)コードでフォーム要素の値を変更するには、valメソッドを利用します。

HTML
<script>
$(document).on('pagecreate', function(e, d){
  $('#light').val(40);
});
</script>
……中略……
<div class="ui-field-contain">
  <label for="light">明るさ:</label>
  <input id="light" name="light" type="range"
    min="0" max="50" step="2" value="20" />
</div>
スライダーの値をJavaScriptコードから操作するコード(change.html)
変更した値がスライダー本体に反映されない

 ただし、結果を見ても分かるように、valメソッドを呼び出しただけではウィジェットに正しく値が反映されません(min属性が「0」でmax属性が「50」なので、valメソッドで「40」を指定すれば、80%の位置にスライダーのつまみが配置されなければならない)。この例であれば、数値入力ボックスには値が反映されていますが、スライダー本体は初期値のままです。ネイティブなフォーム要素とウィジェットが自動的に同期されないために起こる問題です。

 そこで、以下のようにrefreshメソッドを呼び出すことで、ウィジェットに変更を通知します。今度は、JavaScriptコードからの修正が正しくスライダーにも反映されることを確認してください。

JavaScript
$('#light').val(40).slider('refresh');
ウィジェットに変更を通知するコード
値の変更をウィジェットに反映

フォーム要素を動的に追加する

 まず、JavaScript(jQuery)コードから単純にフォーム要素を追加してみましょう。

HTML
<script>
$(document).on('pagecreate', function(e, d){
  $('<div class="ui-field-contain"><label for="entry_name">名前:</label><input id="entry_name" name="entry_name" type="text" /></div>').appendTo('form');
});
</script>
……中略……
<div role="main" class="ui-content">
  <form>
  </form>
</div>
フォーム要素をページに動的に追加するコード(append.html)
JavaScriptコードからラベル/テキストボックスを追加

 結果を見ても分かるように、JavaScriptコードで動的に追加されたフォーム要素は自動初期化されません。つまり、ウィジェットのスタイルが適用されずに、ネイティブな要素がそのまま表示されてしまうのです。

 これを避けるためには、要素を追加した後にenhanceWithinメソッドを呼び出してください。enhanceWithinは、指定された要素配下に対してウィジェットを適用するためのメソッドです。

JavaScript
$('...').appendTo('form').enhanceWithin();
新規の要素に対してウィジェットを適用するためのコード
テキストボックスが正しく整形された

 別解として、テキストボックスに対してtextinputメソッドを呼び出して、明示的にウィジェットを適用するという方法もあります。textinputの部分は適用するウィジェットに応じて、selectmenucheckboxradiosliderなどと読み替えてください。複雑なフォームの場合には、enhanceWithinメソッドの方が、処理効率がよくないという問題もありますので、こちらの利用をお勧めします。

JavaScript
$('...').appendTo('form');
$('#entry_name').textinput();
新規の要素に対してウィジェットを適用するためのコード(別解)

フォーム要素を無効化する

 フォーム要素を無効化するには、disable/enableメソッドを利用します。

HTML
<script>
$(document).on('pagecreate', function(e, d){
  // [コメント]欄を無効化
  $('#entry_comment').textinput('disable');
});
</script>
……中略……
<form>
  <div class="ui-field-contain">
    <label for="entry_comment">コメント:</label>
    <input id="entry_comment" name="entry_comment" type="text" />
  </div>
  <button id="btn" type="submit" class="ui-btn">送信</button>
</form>
テキストボックスを無効化するためのコード(disabled.html)
[コメント欄]を無効化

 ただし、<button>/<a>要素については、「class="ui-btn"」属性でボタンとしてのスタイルを適用しているだけなので、disableメソッドは利用できません*1。代わりに、addClassメソッドでスタイルクラスui-state-disabledを付与してください。

JavaScript
$('#btn').addClass('ui-state-disabled');
addClassメソッドでスタイルクラスを付与するコード例
  • *1 type属性が「button」「submit」「reset」である<input>要素は例外です。内部的にButtonウィジェットを利用していますので、「$('#btn').button('disable');」のようにボタンを無効化できます。

※以下では、本稿の前後を合わせて5回分(第31回~第35回)のみ表示しています。
 連載の全タイトルを参照するには、[この記事の連載 INDEX]を参照してください。

jQuery Mobile逆引きリファレンス
31. jQuery Mobileの動作パラメーターを設定するには?

jQuery Mobileやウィジェットの動作を変更できる「動作パラメーター」の基本的な使い方を解説する。

jQuery Mobile逆引きリファレンス
32. $.mobile.pathオブジェクトでパス/URLの情報を取得/操作するには?

パスやURLを取得/操作するには、$.mobile.path.xxxxxメソッドが利用できる。各メソッドの基本的な使い方を解説する。

jQuery Mobile逆引きリファレンス
33. 【現在、表示中】≫ JavaScriptからフォーム要素を操作するには?

フォーム関連を自前で記述する場合、jQueryの知識を生かせるが、jQuery Mobile固有の注意点もある。その注意点を解説する。

jQuery Mobile逆引きリファレンス
34. JavaScriptからjQuery Mobileページ間の移動を制御するには?

通常のページ遷移ではlocation.hrefプロパティを利用するが、jQuery Mobileのページ遷移ではchangeメソッドやloadメソッドを利用する。その基本的な使い方を説明する。

jQuery Mobile逆引きリファレンス
35. ページのロード/切り替え時に初期化/後処理を実行するには?

ページを表示/切り替えするタイミングで発生するイベントにはどのようなものがあるのか。ページイベントの基本的な利用方法を説明する。

サイトからのお知らせ

Twitterでつぶやこう!