javascript - 非同期 - jquery post 遷移




jQueryを使用してフォームデータをJavaScriptオブジェクトに変換する (20)

フォームのすべての要素をJavaScriptオブジェクトに変換するにはどうすればよいですか?

私はフォームから自動的にJavaScriptオブジェクトを構築するいくつかの方法を持っていますが、各要素をループする必要はありません。 $('#formid').serialize();によって返される文字列は必要ありません$('#formid').serialize(); また、 $('#formid').serializeArray();によって返されたマップを返すこともできません$('#formid').serializeArray();


すべてのGiven Answerとそこに問題があります...

name[key]ような配列として名前を入力すると、このように生成されます

 name:{
   key : value
 }

例:私はこのような形をしています。

    <form>
        <input name="name" value="value" >
        <input name="name1[key1]" value="value1" >
        <input name="name2[key2]" value="value2" >
        <input name="name3[key3]" value="value3" >
    </form>

それからすべての与えられた答えでこれのようなオブジェクトを生成します。

Object {
    name : 'value',
    name1[key1] : 'value1',
    name2[key2] : 'value2',
    name3[key3] : 'value3', 
}

しかし、以下のように生成する必要があります。

Object {
    name : 'value',
    name1 : {
        key1 : 'value1'
    },
    name2 : {
        key2 : 'value2'
    },
    name3 : {
        key2 : 'value2'
    }
}

次にjsコードの下で試してください。

(function($){
    $.fn.getForm2obj = function(){
        var _ = {},_t=this;
        this.c = function(k,v){ eval("c = typeof "+k+";"); if(c == 'undefined') _t.b(k,v);}
        this.b = function(k,v,a = 0){ if(a) eval(k+".push("+v+");"); else eval(k+"="+v+";"); };
        $.map(this.serializeArray(),function(n){
            if(n.name.indexOf('[') > -1 ){
                var keys = n.name.match(/[a-zA-Z0-9_]+|(?=\[\])/g),le = Object.keys(keys).length,tmp = '_';
                $.map(keys,function(key,i){
                    if(key == ''){
                        eval("ale = Object.keys("+tmp+").length;");
                        if(!ale) _t.b(tmp,'[]');
                        if(le == (i+1)) _t.b(tmp,"'"+n['value']+"'",1);
                        else _t.b(tmp += "["+ale+"]",'{}');
                    }else{
                        _t.c(tmp += "['"+key+"']",'{}');
                        if(le == (i+1)) _t.b(tmp,"'"+n['value']+"'");
                    }
                });
            }else _t.b("_['"+n['name']+"']","'"+n['value']+"'");
        });
        return _;
    }
})(jQuery);
console.log($('form').getForm2obj());
<!DOCTYPE html><html><head>
    <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
    <title>Convert form data to JavaScript object with jQuery</title>
</head>
<body>
    <form>
        <input name="name" value="value" >
        <input name="name1[key1]" value="value1" >
        <input name="name2[key2]" value="value2" >
        <input name="name3[key3]" value="value3" >
        <input type="checkbox" name="name4[]" value="1" checked="checked">
        <input type="checkbox" name="name4[]" value="2">
        <input type="checkbox" name="name4[]" value="3">
    </form>
</body></html>


フォームをJSON LIKE A BOSSに変換する

現在のソースはGitHubとbowerにあります。

$ bower install jquery-serialize-object

次のコードは廃止予定です

次のコードは、あらゆる種類の入力名で動作します。 期待どおりにそれらを処理します。

例えば:

<!-- all of these will work! -->
<input name="honey[badger]" value="a">
<input name="wombat[]" value="b">
<input name="hello[panda][]" value="c">
<input name="animals[0][name]" value="d">
<input name="animals[0][breed]" value="e">
<input name="crazy[1][][wonky]" value="f">
<input name="dream[as][vividly][as][you][can]" value="g">
// output
{
  "honey":{
    "badger":"a"
  },
  "wombat":["b"],
  "hello":{
    "panda":["c"]
  },
  "animals":[
    {
      "name":"d",
      "breed":"e"
    }
  ],
  "crazy":[
    null,
    [
      {"wonky":"f"}
    ]
  ],
  "dream":{
    "as":{
      "vividly":{
        "as":{
          "you":{
            "can":"g"
          }
        }
      }
    }
  }
}

使用法

$('#my-form').serializeObject();

ソーサリー(JavaScript)

(function($){
    $.fn.serializeObject = function(){

        var self = this,
            json = {},
            push_counters = {},
            patterns = {
                "validate": /^[a-zA-Z][a-zA-Z0-9_]*(?:\[(?:\d*|[a-zA-Z0-9_]+)\])*$/,
                "key":      /[a-zA-Z0-9_]+|(?=\[\])/g,
                "push":     /^$/,
                "fixed":    /^\d+$/,
                "named":    /^[a-zA-Z0-9_]+$/
            };


        this.build = function(base, key, value){
            base[key] = value;
            return base;
        };

        this.push_counter = function(key){
            if(push_counters[key] === undefined){
                push_counters[key] = 0;
            }
            return push_counters[key]++;
        };

        $.each($(this).serializeArray(), function(){

            // skip invalid keys
            if(!patterns.validate.test(this.name)){
                return;
            }

            var k,
                keys = this.name.match(patterns.key),
                merge = this.value,
                reverse_key = this.name;

            while((k = keys.pop()) !== undefined){

                // adjust reverse_key
                reverse_key = reverse_key.replace(new RegExp("\\[" + k + "\\]$"), '');

                // push
                if(k.match(patterns.push)){
                    merge = self.build([], self.push_counter(reverse_key), merge);
                }

                // fixed
                else if(k.match(patterns.fixed)){
                    merge = self.build([], k, merge);
                }

                // named
                else if(k.match(patterns.named)){
                    merge = self.build({}, k, merge);
                }
            }

            json = $.extend(true, json, merge);
        });

        return json;
    };
})(jQuery);

Tobias Cohenの解決策の固定版です。 これは0''ような偽の値を正しく扱います。

jQuery.fn.serializeObject = function() {
  var arrayData, objectData;
  arrayData = this.serializeArray();
  objectData = {};

  $.each(arrayData, function() {
    var value;

    if (this.value != null) {
      value = this.value;
    } else {
      value = '';
    }

    if (objectData[this.name] != null) {
      if (!objectData[this.name].push) {
        objectData[this.name] = [objectData[this.name]];
      }

      objectData[this.name].push(value);
    } else {
      objectData[this.name] = value;
    }
  });

  return objectData;
};

コーディングの便宜のためにCoffeeScriptのバージョン:

jQuery.fn.serializeObject = ->
  arrayData = @serializeArray()
  objectData = {}

  $.each arrayData, ->
    if @value?
      value = @value
    else
      value = ''

    if objectData[@name]?
      unless objectData[@name].push
        objectData[@name] = [objectData[@name]]

      objectData[@name].push value
    else
      objectData[@name] = value

  return objectData


serializeArrayすでにそれを正確に行います。 必要なフォーマットにデータをマッサージするだけです。

function objectifyForm(formArray) {//serialize data function

  var returnArray = {};
  for (var i = 0; i < formArray.length; i++){
    returnArray[formArray[i]['name']] = formArray[i]['value'];
  }
  return returnArray;
}

実際の入力と同じ名前の隠しフィールドが上書きされるのを見てください。


Underscore.jsを使用している場合は、比較的簡潔なものを使用できます:

_.object(_.map($('#myform').serializeArray(), _.values))

あなたはこれを行うことができます:

var frm = $(document.myform);
var data = JSON.stringify(frm.serializeArray());

JSON参照してください。


いくつかのolder答えから:

$('form input,select').toArray().reduce(function(m,e){m[e.name] = $(e).val(); return m;},{})

これらの答えはすべて私にとってはトップのように見えました。 単純化のために何か言われることがあります。 すべてのフォーム入力にname属性が設定されている限り、これはjim dandyだけで動作します。

$('form.myform').submit(function () {
  var $this = $(this)
    , viewArr = $this.serializeArray()
    , view = {};

  for (var i in viewArr) {
    view[viewArr[i].name] = viewArr[i].value;
  }

  //Do stuff with view object here (e.g. JSON.stringify?)
});

さて、これはすでに非常にアップアップされた答えがあることは分かっていますが、もう一つの同様の質問が最近尋ねられました。この質問にも私は指摘されました。 受け入れられたソリューションよりも利点があるため、私のソリューションも提供したいと思います。無効なフォーム要素を含めることができます(UI機能の仕方によっては重要なこともあります)

ここに私の答えは、 他のSOの質問からです:

最初は、jQueryのserializeArray()メソッドを使用していましたが、無効になっているフォーム要素は含まれていません。 ページ上の他のソースと「同期」しているフォーム要素は、しばしば無効にしますが、データをシリアル化されたオブジェクトに含める必要があります。 したがって、 serializeArray()は出力されています。 :inputセレクタを使用して、指定されたコンテナ内のすべての入力要素(有効と無効の両方)を取得し、次に$.map()を使用してオブジェクトを作成しました。

var inputs = $("#container :input");
var obj = $.map(inputs, function(n, i)
{
    var o = {};
    o[n.name] = $(n).val();
    return o;
});
console.log(obj);

これが機能するには、それぞれの入力にname属性が必要であることに注意してください。これは結果オブジェクトのプロパティの名前になります。

それは実際に私たちが使ったものから少し変更されています。 私たちは.NET IDictionaryとして構造化されたオブジェクトを作成する必要があったので、これを使用しました:(役に立つ場合はここに示します)

var obj = $.map(inputs, function(n, i)
{
    return { Key: n.name, Value: $(n).val() };
});
console.log(obj);

私はこれらのソリューションが両方とも好きです。なぜなら、それらは$.map()関数の単純な使い方であり、セレクタを完全に制御できるからです。 また、余分なプラグインは必要ありません。 プレーンな古いjQuery。


どうしたの:

var data = {};
$(".form-selector").serializeArray().map(function(x){data[x.name] = x.value;}); 

シンプルさはここで最高です。 私は単純な文字列を正規表現に置き換えて使用しましたが、これまでのところ魅力的でした。 私は正規表現のエキスパートではありませんが、非常に複雑なオブジェクトを作成することもできます。

var values = $(this).serialize(),
attributes = {};

values.replace(/([^&]+)=([^&]*)/g, function (match, name, value) {
    attributes[name] = value;
});

実際には、各要素を調べることなくこれを行う方法はありません。 あなたが本当に知りたいのは、 "他の誰かがフォームをJSONオブジェクトに変換するメソッドをすでに書いていますか?"です。 次のようなものが動作するはずです - POST(名前を持っている必要があります)を介して返されるフォーム要素のみを提供することに注意してください。 これはテストされていません

function formToJSON( selector )
{
     var form = {};
     $(selector).find(':input[name]:enabled').each( function() {
         var self = $(this);
         var name = self.attr('name');
         if (form[name]) {
            form[name] = form[name] + ',' + self.val();
         }
         else {
            form[name] = self.val();
         }
     });

     return form;
}

私がこの問題のために見つけた最も簡単で正確な方法は、 bbqプラグインまたはこれ(約0.5Kバイトのサイズ)を使用することでした。

多次元配列でも動作します。

$.fn.serializeObject = function()
{
	return $.deparam(this.serialize());
};


私はTobias Cohenのコードに問題があることを発見しました(私はそれに直接コメントするには十分なポイントがありません)。 同じ名前の2つの選択肢があり、どちらもvalue = ""である場合、元のコードは "name"の代わりに "name": ""を生成します:[""、 ""]

私はこれを "|| o [this.name] == ''"を最初のif条件に追加することで修正できると思います:

$.fn.serializeObject = function()
{
    var o = {};
    var a = this.serializeArray();
    $.each(a, function() {
        if (o[this.name] || o[this.name] == '') {
            if (!o[this.name].push) {
                o[this.name] = [o[this.name]];
            }
            o[this.name].push(this.value || '');
        } else {
            o[this.name] = this.value || '';
        }
    });
    return o;
};

私はXSS攻撃や他の多くの問題のためにライブサイトでこれを使用しませんが、ここではできることの簡単な例があります:

$("#myform").submit(function(){
    var arr = $(this).serializeArray();
    var json = "";
    jQuery.each(arr, function(){
        jQuery.each(this, function(i, val){
            if (i=="name") {
                json += '"' + val + '":';
            } else if (i=="value") {
                json += '"' + val.replace(/"/g, '\\"') + '",';
            }
        });
    });
    json = "{" + json.substring(0, json.length - 1) + "}";
    // do something with json
    return false;
});

私は最近同じ問題を抱えていましたが、同じ構造のJSONオブジェクトにフォームを変換するこの.toJSON jQueryプラグイン付いてきました。 これは、ユーザーが特定の場所でフィールドを追加できるようにするために、動的に生成されるフォームにも便利です。

要は、実際にフォームを構築して構造体そのものを作成したいと思うかもしれないので、ユーザが自分の好きな場所を町に挿入するフォームを作ってみたいとしましょう<places>...</places>このフォームを<places>...</places>を表すと想像できます<places>...</places>ユーザが好きな場所のリストを含むXML要素<place>...</place>要素のリスト<place>...</place>それぞれ<name>...</name>要素、a <type>...</type>要素、次に<activity>...</activity>要素のリストで、そのような場所で実行できるアクティビティを表します。 したがって、XML構造は次のようになります。

<places>

    <place>

        <name>Home</name>
        <type>dwelling</type>

        <activity>sleep</activity>
        <activity>eat</activity>
        <activity>watch TV</activity>

    </place>

    <place>...</place>

    <place>...</place>

</places>

この正確な構造を表すJSONオブジェクトをどれくらい持っているといいでしょうか。次のいずれかを行うことができます:

  • このオブジェクトをそのままCouchDBようなデータベースに格納する
  • あなたの$ _POST []サーバ側からそれを読んで、正しくネストされた配列を取得すれば、意味的に操作できます
  • いくつかのサーバーサイドスクリプトを使用して、整形式のXMLファイルに変換します(たとえその構造が事前にわかっていなくても)
  • Node.jsようなサーバスクリプトと同じように何とか使う

これでフォームがXMLファイルをどのように表現できるか考える必要があります。

もちろん<form>タグはrootですが、データ要素ではなくコンテナである<place>要素があるため、入力タグを使用することはできません。

ここで<fieldset>タグが便利な場所です! <fieldset>タグを使用してフォーム/ XML表現のすべてのコンテナ要素を表現するので、次のような結果になります。

<form name="places">

    <fieldset name="place">

        <input type="text" name="name"/>
        <select name="type">
            <option value="dwelling">Dwelling</option>
            <option value="restoration">Restoration</option>
            <option value="sport">Sport</option>
            <option value="administrative">Administrative</option>
        </select>

        <input type="text" name="activity"/>
        <input type="text" name="activity"/>
        <input type="text" name="activity"/>

    </fieldset>

</form>

この形式でわかるように、一意の名前の規則が破られていますが、要素の配列に変換され、配列内のインデックスによってのみ参照されるため、これは問題ありません。

この時点でname="array[]"、フォームの中にどのように名前が似ていないかを見ることができ、すべてがきれいでシンプルでセマンティックです。

このフォームを次のようなJSONオブジェクトに変換します。

{'places':{

    'place':[

        {

            'name': 'Home',
            'type': 'dwelling',

            'activity':[

                 'sleep',
                 'eat',
                 'watch TV'

            ]

        },

        {...},

        {...}

    ]

}}

これを行うために、私はこのjQueryプラグインをここで開発しました。誰かがこのコードレビュースレッドで最適化を手助けし、次のようになりました。

$.fn.toJSO = function () {
    var obj = {},
        $kids = $(this).children('[name]');
    if (!$kids.length) {
        return $(this).val();
    }
    $kids.each(function () {
        var $el = $(this),
            name = $el.attr('name');
        if ($el.siblings("[name=" + name + "]").length) {
            if (!/radio|checkbox/i.test($el.attr('type')) || $el.prop('checked')) {
                obj[name] = obj[name] || [];
                obj[name].push($el.toJSO());
            }
        } else {
            obj[name] = $el.toJSO();
        }
    });
    return obj;
};

私もこの1つのブログ記事をこれ以上説明するようにしました。

これはフォームのすべてをJSON(ラジオやチェックボックスまで)に変換します。残す必要があるのは、呼び出し

$.post('script.php',('form').toJSO(), ...);

私は、JSONオブジェクトと確かにフォームを変換する方法はたくさんあります知っている.serialize().serializeArray()、ほとんどの場合で素晴らしい仕事と主に使用されることが意図されているが、私は、この全体的なアイデアだと思う意味の名前を持つXML構造としてフォームを書き、に変換しますうまく作成されたJSONオブジェクトは試してみる価値があります。同じ名前の入力タグを気にせずに追加できるという事実は、動的に生成されたフォームデータを取得する必要がある場合に非常に便利です。

これが誰かを助けることを願っています


選択したソリューションに問題が見つかりました。

配列ベースの名前を持つフォームを使用する場合、jQueryのserializeArray()関数は実際には機能しません。

配列ベースのフィールド名を使用するPHPフレームワークを使用して、同じフォームを複数のビューで複数回同じページに配置できるようにしました。 これは、矛盾するフォームモデルを使わずに、同じページに追加、編集、削除の両方を行うことができます。

この絶対的な基盤機能を使わなくても、フォームをseralizeしたいので、私は自分のseralizeArray()を書くことにしました:

        var $vals = {};

        $("#video_edit_form input").each(function(i){
            var name = $(this).attr("name").replace(/editSingleForm\[/i, '');

            name = name.replace(/\]/i, '');

            switch($(this).attr("type")){
                case "text":
                    $vals[name] = $(this).val();
                    break;
                case "checkbox":
                    if($(this).attr("checked")){
                        $vals[name] = $(this).val();
                    }
                    break;
                case "radio":
                    if($(this).attr("checked")){
                        $vals[name] = $(this).val();
                    }
                    break;
                default:
                    break;
            }
        });

注意:これはフォームsubmit()の外部でも機能しますので、コードの残りの部分でエラーが発生した場合、リンクボタンに「変更を保存」と書いてもフォームは送信されません。

また、検証のためにサーバー側に送信するデータを収集するためにのみ、この関数をフォームの検証に使用しないでください。 そのような弱く大量に割り当てられたコードを使用すると、 XSSなどが発生します。


すばやく現代的な解決策を得るには、JSONify jQueryプラグインを使用してJSONify。以下の例は、GitHub READMEからそのまま引用しています。プラグインの作者、Kushal Pandyaへのすべての信用。

与えられた:

<form id="myform">
    <label>Name:</label>
    <input type="text" name="name"/>
    <label>Email</label>
    <input type="text" name="email"/>
    <label>Password</label>
    <input type="password" name="password"/>
</form>

ランニング:

$('#myform').jsonify();

プロデュース:

{"name":"Joe User","email":"[email protected]","password":"mypass"}

このJSONオブジェクトを使用してjQuery POSTを実行する場合は、次のようにします。

$('#mybutton').click(function() {
    $.post('/api/user', JSON.stringify($('#myform').jsonify()));
}

私はサミュエルバージョンが好きですが、小さなエラーがあると思います。通常、JSONは次のように送信されます。

{"coreSKU": "PCGUYJS"、 "name_de": "何でも"、...

そうではない

[{"coreSKU": "PCGUYJS"}、{"name_de": "whatever"}、...

関数IMOは以下のように読まなければなりません:

App.toJson = function( selector ) {
    var o = {};
    $.map( $( selector ), function( n,i )
    {
        o[n.name] = $(n).val();
    });     
    return o;
}

(一般的に期待されるように)データ配列にラップし、最後にそれをapp.stringify({data:App.toJson( '#cropform:input')})として送信します。

リーン版の質問3593046のストリンジェライザの外観については、すべてのjson2.jsでカバーされたバージョンのjson2.jsjson2.jsしてください。それはすべてをカバーする必要があります:)





serialization