【jQuery】フォーム全体の変更を監視


フォームの入力値変更を感知したい場合

$('input').change(function() {
});

$('select').change(function() {
});

などと、一つ一つ書くのが面倒なときがあります。
そういうときは、以下のようにするとフォーム全体の変更を感知できるようになります。

<form action="" name="testForm" method="post">
...略...
</form>

<script>
$('form[name=testForm]').change(function(e) {
    var target = $(e.target);
    var type = target.attr('type');
    var name = target.attr('name');
    var val = target.val();
    console.log(type, ':', name, ':', val);
});
</script>

これで「testForm」という名前のフォーム全体に対して、要素の変更を感知できるようになります。
「input type」やセレクトボックス、チェックボックス、ラジオボタンなどによって処理を変えたい場合は、「type」を見て「switch case」などで処理を分岐させると良いでしょう。


【jQuery】連想配列のマージ


複数の連想配列を、上書きでマージしたい場合のやり方について。

$.extend(target, obj1[, obj2, ...]);

target:マージ対象の連想配列
objXX:マージする連想配列
※マージする連想配列は複数指定可能

例)

var test1 = {a:'A', b:'B', c:'C', d:'D'};
var test2 = {b:'99', e:'1'};

$.extend(test1,test2);
console.log(test1);

出力結果
{a: “A”, b: “99”, c: “C”, d: “D”, e: “1”}

参考サイト:ko-atrandom
連想配列の中に、さらに連想配列を含む場合などの使い方も載っている。


フォームの入力内容をAjaxで加工後、別タブに送信(Ajaxとsubmitの2回送信)


フォームで入力された内容を、別タブで確認させたいが、単にsubmitで送信するのではなく、一度プログラムを通して加工する必要がある、という面倒な案件があったので、メモとして残しておきます。

javascript

function sample(url){

  // フォームの入力内容を取得し、クエリ文字列に変換
  var form = $('#form_id');
  var query_str = form.serialize();

  var postData = {
    'query_str' : query_str,
  };

  $.ajax({
    async: false,       // ajax を同期処理にする
    url: './act.php',   // 送信先ファイル名
    type : 'POST',
    data : postData,
    timeout: 10000,

  }).done(function(getData){
    // 前回追加したフォームを削除
    var old = document.getElementById('append_data');
    if (old) {
      document.form_id.removeChild(old);
    }

    // ajaxで取得したデータをフォームに追加
    var appendData = document.createElement('input');
    appendData.type = 'hidden';
    appendData.id = 'append_data';
    appendData.name = 'append_data';
    appendData.value = getData;

    document.form_id.appendChild(appendData);
  });

  // 指定 URL に submit
  document.form_id.action = url;
  document.form_id.enctype = 'application/x-www-form-urlencoded';
  document.form_id.target = '_blank';
  document.form_id.submit();
}

 

処理内容は、以下の流れになってます。

1.フォームにデータを入力する
 

2.ボタンを押された際に「sample」関数を呼び出す

<input type="button" value="確認" onclick="sample('http://hoge.hoge/disp.html');">

 

3.フォームの入力内容を「serialize()」を使い、クエリ形式で取得

// クエリ形式
category=1&title=sample

 

4.act.php に ajax でPOST送信

act.php の例

// クエリ文字列の取得例
$input_data = '';

if (isset($_POST['query_str'])) {
    $query_str = $_POST['query_str'];

    // クエリ文字列として送られてきたフォームの値を、input_data に格納する
    parse_str($query_str, $input_data);

	// こんな感じで取得できる
    // $input_data['category'] = 1;
    // $input_data['title'] = 'sample';
}

// 適当に加工

// 出力例
// 配列などにも対応させるため、シリアル化している
echo serialize($output_data);

 

5.act.php の出力内容をフォームにhiddenで追加する
2回め以降は、前回追加したフォームデータが残っているので、まずは削除してから追加しています。
 

6.別タブに submit
action の URL を書き換えているので、必要であれば書き換え前のURLを保存し、書き戻してください。
同様に、enctype や target も。
 

7.submit されたデータを受け取って表示
PHP での受け取り例

// POSTデータの取得
$post_data = $_POST;

// 追加データの取得
$append_data = array();
if (isset($_POST['append_data'])) {
    $append_data = unserialize($_POST['append_data']);
}

// POSTデータに、追加データをセット
if (is_array($append_data)) {
    foreach ($append_data as $key => $val) {
        if (isset($val)) {
            if (isset($post_data[$key])) {
                $post_data[$key] += $val;
            } else {
                $post_data[$key] = $val;
            }
        }
    }
}

 

最初は ajax 完了後に submit したいということで ajaxの「always」で行けないか?と試したのですが、何故か「always」の中に「document.form_id.submit();」を書くと動きませんでした。
そこで、仕方なく ajax を「async: false」で同期処理にしています。

それなら「submit()」を辞めればいいんじゃないか?とも思いましたが、テキストエリアの入力に使っている CKEditor が、エディタの入力内容を textarea の value にセットするタイミングが submit の時だったようで、これを submit 以外の時にも対応させるのは時間が掛かりそうなため断念しました。

この辺は改良すれば、もっとスマートに行けそうです。