Mach3.laBlog

細かすぎて伝わらないjQuery拡張 (19) “$.fn.extract” – Advent Calendar 2016

この記事は賞味期限切れです。(更新から1年が経過しています)

$.fn.extract() は、非Form要素の内容をシリアライズする関数です。

$.fn.extract(asArray)

使い方

<div id="demo">
    <input type="text" name="name" value="john">
    <input type="text" name="age" value="23">
</div>

<script>

$("#demo").extract();
/* => {
    name: "john",
    age: 23
} */

// 引数にtrueを渡すと配列で返します
$("#demo").extract(true);
/* => [
    { key: "name", value: "john" },
    { key: "age", value: "23" }
] */

</script>

基本的な挙動は先に紹介した $.fn.serializeObject と同じです。 オブジェクトではなく配列で受け取りたい場合は引数に true を渡します。

ちなみに、$.fn.serialize()$.fn.serializeArray() は、非Form要素で使用しても空の文字列・配列を返します。 (後述にもありますが、それが正しいと思います)

コード

$.fn.extract = function(asArray){
    var list = [], data = {};
    this.find("input[name], select[name], textarea[name]").each(function(){
        var name = this.name;
        if(["radio", "checkbox"].indexOf(this.type) >= 0){
            return ! this.checked ? null : list.push({
                name: name,
                value: this.value
            });
        }
        if(this.nodeName === "SELECT"){
            return $(this).find("option:selected").each(function(){
                list.push({
                    name: name,
                    value: this.value
                });
            });
        }
        list.push({
            name: name,
            value: this.value
        });
    });
    if(asArray){
        return list;
    }
    list.forEach(function(item){
        if(data[item.name] !== void 0){
            if($.type(data[item.name]) !== "array"){
                data[item.name] = [data[item.name]];
            }
            data[item.name].push(item.value);
            return;
        }
        data[item.name] = item.value;
    });
    return data;
};

オブジェクトで返すのをデフォルトとしている理由は、 わたし自身が基本的にオブジェクトで受け取りたいと思っているからです。

存在意義

なお、この関数の存在意義はあまりありません。 form でマークアップすれば済む話ですし、そうすべきでしょう。 どうしてもレイアウトの都合で form の外に input を置かなければいけない場合は、 HTML5の form 属性で親となる form を指定してやれば対応可能です。

<form action="/" id="demo-form"></form>
<input type="text" name="name" value="john" form="demo-form">

<script>

$("#demo-form").serialize(); // => "name=john"

</script>

こうすれば、$.fn.serialize/serializeArray() でもシリアライズする事ができ、仕様にも則っていますね。

コメント

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

*