1

I have used the struts json plugin and tried to convert the form data to json format to submit by ajax.

I have two cases in the HTML

<form>
     <input type="text" name="user.name" value="Tom"></p>
     <input type="text" name="user.location" value="China"></p>
     <input type="text" name="user.data[0].id" value="993"></p>
     <input type="text" name="user.data[0].accountId" value="123"></p>
     <input type="text" name="user.data[1].id" value="222"></p>
     <input type="text" name="user.data[1].accountId" value="333"></p>
</form>

What I expected is to convert it to the json structure:

{
   user : {
      name: "Tom",
      location : "China",
      data: [
         {
            id : 993,
            accountId : 123
         },
         {
            id : 222,
            accountId : 333
         }
      ]
   }
}

I know how to declare the json data and declare the attributes one by one.

I would like to have the better way to make each form to be in json format using simple way rather than declaring the parameter one by one in json format.

Appreciate for any suggestion or advice. Thank you.

Long Ranger
  • 5,888
  • 8
  • 43
  • 72

2 Answers2

1

Provided your form is exactly like that

Using a plain JS approach

<form class="userform">
 <input type="text" class="username" value="Tom"></p>
 <input type="text" class="userlocation" value="China"></p>
 <input type="text" class="userid" value="993"></p>
 <input type="text" class="useraccountid" value="123"></p>
 <input type="text" class="userid2" value="222"></p>
 <input type="text" class="useraccountid2" value="333"></p>
</form>

Then assign the values to the object

var frm = document.getElementsByClassName('userform');

//initialize blank object and keys
var user = {},
  user.name = "",
  user.location = "",
  user.data = [];

//get all child input elements
for(var i = 0; i < frm.length; i++){
   var uname = frm[i].getElementsByClassName('username')[0];
   var uloc = frm[i].getElementsByClassName('userlocation')[0];
   var uid = frm[i].getElementsByClassName('userid')[0];
   var uaccid = frm[i].getElementsByClassName('useraccountid')[0];
   var uid = frm[i].getElementsByClassName('userid2')[0];
   var uaccid = frm[i].getElementsByClassName('useraccountid2')[0];

  //assign values to object here
  user[name] = {};    //assigning a parent property here, the name for example.
  user[name].name = uname.value;
  user[name].location = uloc.value;
  user[name].data.push({
    'id': uid.value
    'accountId': uaccid.value
  });
  user[name].data.push({
    'id': uid2.value
    'accountId': uaccid2.value
  });
}

JSON.stringify(user); //convert to JSON (or ignore if you want a plain object)

Output would be this in JSON format

{
   user :{
      Tom: {
            name: "Tom",
            data: [
               {
                 id : 993,
                 accountId : 123
               },
               {
                 id : 222,
                 accountId : 333
               }
            ]
      },

      Jerry: {
      //more data
      },

      Courage: {
      //more data
      }
   }
}

Hope this helps

If your input fields are many, like id3, accountid3, 4, 5, 6. You have to loop through the classes that you assign to these two repetitive fields

Abana Clara
  • 4,602
  • 3
  • 18
  • 31
  • Thanks for help, I am trying to convert the whole form to be in json format. It would be a big cost to do it one by one. Do you have better idea? – Long Ranger Aug 25 '17 at 03:30
  • Can you give a clearer image of what you are trying to achieve? How big is it exactly and are all the fields unique or just a repetition of few? If the fields are many, I doubt there is a better way of achieving this without setting unique keys, properties and values for each input element. You can't loop through multiple unique fields and expect that you can divide each one of them into their own respective object properties – Abana Clara Aug 25 '17 at 03:31
  • Question updated. Expected all the fields unique, only few fields in each form, but I have many form like this. It would be a big trouble for me to do this. – Long Ranger Aug 25 '17 at 03:40
  • If you have many forms but only that few fields, you can loop through each form, giving each form a class and each input a class. I will try to updated my answer but I'm only browsing on stackoverflow stealthily at work. Give me some time – Abana Clara Aug 25 '17 at 03:41
  • @LongRanger Updated, see if that'll help. – Abana Clara Aug 25 '17 at 03:55
  • That's not I expected, declaring attributes in json one by one would be a big cost for me. Anyway, thanks for your help. – Long Ranger Aug 25 '17 at 04:00
  • Sorry, but we use shit tonnes of JSON properties at work too, we use this approach and I see this kind of approach everywhere. I don't know if there is any native way to create one liners if you have multiple unique fields. – Abana Clara Aug 25 '17 at 04:01
0

Here you go with a solution using jQuery https://jsfiddle.net/pnz8zrLx/2/

var json = {};

$('button').click(function(){
    $('form').each(function(i){
    json["user" + i] = {};
    json["user" + i].data = [];
    var tempJSON = {};
    $('form:nth-child(' + (i+1) + ') input[type="text"]').each(function(){
      if($(this).attr('name') === 'name' || $(this).attr('name') === 'location'){
        json["user" + i][$(this).attr('name')] = $(this).val();
      } else {

        tempJSON[$(this).attr('name')] = $(this).val();

        if(tempJSON != {} && $(this).attr('name') === 'accountId'){
          json["user" + i].data.push(tempJSON);
          tempJSON = {};
        }
      }
    });
  });

  console.log(json);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form>
     <input type="text" name="name" value="Tom">
     <input type="text" name="location" value="China">
     <input type="text" name="id" value="993">
     <input type="text" name="accountId" value="123">
     <input type="text" name="id" value="222">
     <input type="text" name="accountId" value="333">
</form>

<form>
     <input type="text" name="name" value="Test">
     <input type="text" name="location" value="Test112">
     <input type="text" name="id" value="22">
     <input type="text" name="accountId" value="78">
     <input type="text" name="id" value="00">
     <input type="text" name="accountId" value="44">
</form>
<button>
Submit
</button>

Hope this will help you.

Shiladitya
  • 12,003
  • 15
  • 25
  • 38