Technote

by sizuhiko

バリデーションプラグインと組み合わせて使うと便利な、確認画面を出すjQueryプラグイン

<!– more –>これまで確認画面を出すだけのものや、入力チェックだけをするものはプラグインとして出ていたのですが、どうも組み合わせて使おうとすると不便なことが多かったので、プラグインを自作してみました。

ダウンロード:

ソースコードは以下のgithubで公開しています。

https://github.com/sizuhiko/confirmForm

デモ:

まずどのような動作をするのか、デモページで確認したほうがわかりやすいと思います。以下のURLから操作してみてください。

/demo/confirmForm/demo/index.html

デモサイトでは入力チェックにex-valudationプラグインを使っています。

必須条件:

特徴:

  • 確認画面を出すかどうかは自分で判断します
  • 確認画面でOKが選択されるまでフォームはSubmitされません
  • 一般的なフォームの形式であれば、ほとんどカスタマイズ(オプションで指定する)の必要なし

一般的なフォームって?

このプラグインでは以下のような構造のHTMLフォームが利用されることを想定しています。

<form action="posted.html" method="get" id="inputForm">
  <div>
    <label for="user_id">ID:</label>
    <input type="text" name="id" id="user_id" value=""><span class="required">*</span>
  </div>
  <div>
    <label for="user_name">Name:</label>
    <input type="text" name="name" id="user_name" value=""><span class="required">*</span>
  </div>
  <div>
    <label for="user_sex">Sex:</label>
    <fieldset id="user_sex">
      <input type="radio" name="sex" id="user_sex_male" value="1"><label for="user_sex_male">Male</label>
      <input type="radio" name="sex" id="user_sex_female" value="2"><label for="user_sex_female">Female</label>
      <span class="required">*</span>
    </fieldset>
  </div>
  <div>
    <label for="user_lang">Language:</label>
    <select name="lang" id="user_lang">
      <option value="">-- please select --</option><option value="jp">Japanese</option><option value="en">English</option>
    </select><span class="required">*</span>
  </div>
  <div>
    <label for="user_receive_news">Receive News Mail:</label>
    <fieldset id="user_receive_news">
      <input type="checkbox" name="news" id="user_reveive_news_sports" value="1"><label for="user_receive_news_sports">Sports</label>
      <input type="checkbox" name="news" id="user_reveive_news_music" value="2"><label for="user_receive_news_music">Music</label>
      <input type="checkbox" name="news" id="user_reveive_news_computer" value="3"><label for="user_receive_news_computer">Computer</label>
    </fieldset>
  </div>
  <div class="buttons">
    <input type="submit" value="next" id="submit_ok">
  </div>
</form>

これはデモページのフォーム部分そのものなのですが、項目をdivタグで囲い、その中の項目名はlabelで入力フィールドはinputやselectを使うようなデザインです。

プラグインで必要になる記述

javascriptファイルをロードします。 jqModelプラグインを使っているので、jqModal、もちろんjqueryもロードしてください。

<script charset="utf-8" type="text/javascript" src="http://code.jquery.com/jquery-1.4.2.js"></script>
<script charset="utf-8" type="text/javascript" src="http://dev.iceburg.net/jquery/jqModal/jqModal.js"></script>
<script src="../src/confirmform.js"></script>

jqModalのスタイルシートが必要になります。また、jqModalのexampleで記述されているConfirmサンプルのスタイル定義を利用しているので、サンプルHTML上から切り出したスタイルシートをvendorディレクトリに用意しました。これを使うと簡単に利用を開始することができます。

<link charset="utf-8" href="../vendor/jqModal/jqmConfirm.css" type="text/css" rel="stylesheet"></link>
<link charset="utf-8" href="http://dev.iceburg.net/jquery/jqModal/jqModal.css" type="text/css" rel="stylesheet"></link>

プラグインの初期化

プラグインを利用するためには、HTML上に1つ確認画面用の空エレメントを追加する必要があります。場所はbody内であればどこでもかまいません。

<div id="confirmForm"></div>

idの値も特に意味はありません。ここではconfirmFormという値にしておきます。

プラグインのインスタンスを初期化するには、$(“入力フォームのセレクタ”).confirmForm(“確認画面用のセレクタ”, オプション) を使います。

$(document).ready(function(){
  ...
  $("#inputForm").confirmForm("#confirmForm", {});
  ...
}

ひとまず、このようにシンプルな宣言で動作します。実際に利用する場面では、入力フォームでselectボックスやcheckbox,radioボタンなどを利用していると思います。デフォルトの挙動では値をinputのvalueから取り出して表示するだけなので、コード値を名前に変換する必要があるかもしれません。このあたりのカスタマイズは、オプション節で解説します。

確認画面を表示する

このプラグインでは確認画面は自分で表示する必要があります。たとえばバリデーションプラグインの成功時コールバックで呼び出すようなイメージです。

$("#inputForm").confirmShow();

これはとてもシンプルで、confirmShow関数を呼び出すだけです。

OKが押されたかどうかチェックする

このプラグインでは、確認画面でOKが選択されたらもう一度入力フォームでSubmitを実行します。そのため入力チェックが再実行されて、コールバックが呼び出されるかもしれません。そのためにOKが既に選択されていたらそのままreturnするような実装にすることになると思います。

validCallback:function() {
  if($("#inputForm").isConfirmed()) {
    return;
  }
  $("#inputForm").confirmShow();
}

確認済みかどうかはisConfirmed関数を呼び出すだけです。入力内容が問題ないときのコールバックがvalidCallbackだったとすると、上記のような実装になります。

オプション

実際に利用する場面では、必ずしもinputのvalue値が確認画面に出れば良い訳ではありません。また、タイトルを変更したりボタンのラベルを変更したりもしたいでしょう。そのためにプラグイン初期化時にオプションを指定できるようにしてあります。

オプション一覧:

名前意味デフォルト値概要

title タイトル Are you sure? 確認画面上部に表示されるタイトルを文字列で指定

yes はいボタンのラベル Yes 文字列で指定

no いいえボタンのラベル no 文字列で指定

findLavel ラベルを探索して文字列を返すためのコールバック 1つ前の要素のtext部分(一般的なフォームのtextボックスではlabelになる) radioやcheckboxのようにラベルがfieldsetの外側にあるようなケースで独自にコールバック関数を実装する

formatValue 値をカスタマイズするためのコールバック inputやselectのvalue値 value値がコードだが、確認画面では値(名前)で出したい場合に独自にコールバック関数を実装する

separator 複数選択値の区切り文字 ,(コンマ) 同一nameがある場合に、値を区切る文字列

ラベル文字列のコールバック

デフォルトの挙動は以下のとおりです。

'findLabel': function(inputField) {
    return $(inputField).prev().html();
}

textボックスは直前の要素がlabelであることを想定しているので、すべてが一般的なフォームのレイアウトで、textボックスしか利用していなければ、オプションの指定は必要ありません。しかし実際はlabelが右だったり1つ親の要素だったりすることがあります。 このような場面ではコールバックを実装してください。

例えばデモページでは以下のようなコードになっています。

'findLabel': function(field) {
    switch(field.name) {
    case 'sex':
        return 'Sex';
    case 'news':
        return 'Receive News Mail';
    default :
        str = $(field).prev().html();
        return str.substring(0, str.length-1);
    }
}

findLabelに関してはformatValurのように項目別ではなく、functionで受け取って独自にカスタマイズする方式を取っています。これは項目名は一括ルールで変換できる場合が想定できるためです。

※このオプションに関しては、将来formatValueのようにhashでも指定できる(併用)方式に変更する予定です。

値をカスタマイズするためのコールバック

inputやselectのvalue値は必ずしも確認表示用には向いていないこともある(例えばコード値になっているなど)ので、このようなケースではコールバック関数を実装してください。

例えばデモページでは以下のようなコードになっています。

'formatValue':{
  'sex':function(field) {
    return {1:"Male", 2:"Female"}[$(field).val()];
  },
  'lang':function(field) {
    return {'jp':"Japanese", 'en':"English"}[$(field).val()];
  },
  'news':function(field) {
    return {1:"Sports", 2:"Music", 3:"Computer"}[$(field).val()];
  }
}

formatValue自体は各入力項目のname属性をキーにしたhashで定義します。

さいごに

今後以下の機能について、バージョンアップを予定しています。

  • yes,noボタンの左右を逆に指定できるようにする
  • selectやcheckbox、radioなどタイプごとに推奨フォームを想定してラベル値を取得する
  • findLabelをhashでもオプション指定できるようにする

その他カスタマイズ要望などあれば、機能追加していきたいな、と思っています。