2017-02-18 3 views
0

次の関数を使用してフォームをjsonオブジェクトとしてシリアル化します。JavascriptはJSONとしてフォームをシリアライズ

$.fn.serializeObject = function() 
    { 
     var o = {}; 
     var a = this.serializeArray(); 
     $.each(a, function() { 
      if (o[this.name] !== undefined) { 
       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; 
    }; 

これは、次のようになり、私を返します。

{ 
"address": "aaaa", 
"organization": "66", 
"region": "44", 
"nodeType": "HANGING", 
"description": "asdasdasdasd", 
"longitude": "45.8888", 
"latitude": "45.8888" 
} 

しかし、私は少し異なる結果にする必要があります。私はID値を含むオブジェクトとして私の選択したオプションを送る必要があります。どのように私はそれをjavascriptの関数か他の方法で行うことができますか?

{ 
    "address": "", 
    "description": "aaa", 
    "nodeType": { 
     "idNodeType": "WELL" 
    }, 
    "region": { 
     "idRegion": "56" 
    }, 
    "organization": { 
     "idOrganization": "66" 
    }, 
    "location": { 
     "latitude": "46.234234", 
     "longitude": "45.23423" 
    } 
} 

答えて

2

これを達成するには、いくつかの方法があります。私は3つを組み合わせたコードをいくつか表示しますので、好きなものを選ぶことができます。 すべての場合、値がserializeObjectメソッドに適用される前に、オブジェクト内にパスを作成しています。そのために、再帰的なプライベートメソッドを追加しました。

  1. はのように、所望の経路で入力された名前を書く:

    <input name="some.path" /> 
    
  2. それが解決すると、唯一の問題は、私は3つの異なる方法を見つけるところそれはです、あなたの価値の最終的なパスを決定する方法であります
  3. オブジェクト内の属性を使用してパスを作成します。私の例ではdata- *属性を使用しましたが、idを使用するように簡単に変更できます。例えば、これは、JSONオブジェクト内領域 - > idRegionのマッピングをもたらすであろう。

    <select name="region" data-form-path="idRegion"> 
    
  4. このような、オブジェクトのパスに入力名をマップする方法を決定するマッピング・オブジェの作成:

    var mapping = { 
        "country" : "location.country", 
        "isForeignCountry" : "location.isForeignCountry" 
    } 
    

ので、ここでは、この作品の様々な方法を示すために使用できるサンプルフォームです:

 <form> 
     <input type="text" name="name" value="1"/> 
     <input type="text" name="lasntame" value="2"/> 
     <input type="text" name="photos.total" value="2"/> 
     <input type="text" name="photo.items" value="face.jpg" id="b"/> 
     <input type="text" name="photo.items" value="landscape.jpg" id="b"/>    
     <textarea name="userData.comments" data-form-path="1355998"></textarea> 
     <select name="region" data-form-path="idRegion"> 
      <option value="5" selected="selected">5</option> 
      <option value="6">6</option> 
      <option value="7">7</option> 
     </select> 
     <select name="country" > 
      <option value="5" selected="selected">5</option> 
      <option value="6">6</option> 
      <option value="7">7</option> 
     </select> 
     <input type="checkbox" checked="checked" name="isForeignCountry" value="8" id="f"> 
     <input type="submit" name="check" value="Submit" id="g"> 
    </form> 

ご覧のとおり、「photos.total」と「photos.items」という名前の入力があります。 2つの 'items'があるので、複数の値を持つフィールドが適切に変換されていることがわかります。これらは、最初のメソッドを使用して最終的な値のパスにマップされます。

data-form-path属性(HTML5有効なdata- *属性)を持つ2つのアイテムもあります。これらのメソッドは2番目のメソッドを使用し、ボーナスポイントの場合はテキストエリアに名前のパスがあるため、最初のメソッドも使用されます。

次のように魔法を行います変更されたコードは次のとおりです。

$.fn.serializeObject = function(mapping) 
    { 
      var o = {}; 
      var a = this.serializeArray(); 
      var that = this; 
      $.each(a, function() { 
       var name = this.name; 
       // We store current reference in a variable because when a nested path 
       // is created, the value is set on the last element of the path, 
       // instead of the JSON root 
       var currentRef = o; 

       if(!mapping) { 
        // 1st way: using names with path, like 'inputname="location.latitude" ' 
        if(name.indexOf('.') != -1) { 
        var path = name.split('.'); 
        currentRef = createPath(o, path); 
        name = name.split('.').splice(-1,1); 
        } 

        // Second way: adding metadata (this could be simply the id instead) 
        // Bonus! supports also paths with dots 
        var idData = $("*[name='" + this.name + "']",that).data("form-path"); 
        if(idData){ 
        currentRef = createPath(currentRef, [name,idData]); 
        name = idData; 
        } 
       } 
       else { 
        // Final way: simply use a mapping between form inputs and json path 
        if(mapping[name]){     
        var path = mapping[name].split('.'); 
        currentRef = createPath(o, path);     
        name = name.split('.').splice(-1,1); 
        } 
       } 

       if (currentRef[name] !== undefined) { 
        if (!currentRef[name].push) { 
         currentRef[name] = [currentRef[name]]; 
        } 
        currentRef[name].push(this.value || ''); 
       } else { 
        currentRef[name] = this.value || ''; 
       } 
      }); 

      // Recursively create a path in the obj item and return 
      // the last created object reference 
      function createPath(obj, pathArray) { 
       var item = pathArray.splice(0,1); 
       var returnObj; 

       if(pathArray.length === 0) { 
        returnObj = obj; 
       } 
       else if(!obj[item]) { 
        obj[item] = {}; 
        returnObj = createPath(obj[item], pathArray); 
       } 
       else returnObj = createPath(obj[item], pathArray); 

       return returnObj; 
      } 

      return o; 
    }; 

、我々はマッピングせずに電話をかける場合は、このフォームの結果は次のとおりです。

{ 
     "name":"1", 
     "lasntame":"2", 
     "photo":{ 
      "total":"2", 
      "items":[ 
       "face.jpg", 
       "landscape.jpg"] 
     } 
     ,"userData":{ 
      "comments":{ 
       "1355998":"" 
      } 
     }, 
     "region":{ 
      "idRegion":"5" 
     }, 
     "country":"5", 
     "isForeignCountry":"8" 
    } 

入力「写真。*」という名前の名前は、その名前に対応するパスに入れられています。また、data-form-path属性の入力も正しくインデントされます。

HTMLを変更することはできません(尋ねるときにさらに具体的に説明する必要があります)。入力マッピングオブジェクトを使用できます。私はこのように呼び出すのであれば:

var mapping = { 
     "country" : "location.country", 
     "isForeignCountry" : "location.isForeignCountry" 
    } 
    console.log($("form").serializeObject(mapping)); 

オブジェクトマッピングは、その結果、代わりに他のルールで使用されます。

{ 
     "name":"1", 
     "lasntame":"2", 
     "photo.total":"2", 
     "photo.items":[ 
      "face.jpg", 
      "landscape.jpg"], 
     "userData.comments":"", 
     "region":"5", 
     "location":{ 
      "country":"5", 
      "isForeignCountry":"8" 
     } 
    } 

私はこれがあなたのニーズをカバーする必要がありますね。 HTMLを表示したり、変更することができないこと、変更できないことを説明するなど、より詳細な質問をしていただきたいと思います。これがあなたを助けてくれたら教えてください。乾杯!

+0

ご注意ください。あなたの答えは本当にすごい、ひどいです! ;) –

関連する問題