0

I could not think of a better title, but the problem is: I have a form for Users and the user can have one or many phone numbers. More phone fields is added via a js script, so the number of phone fields is arbitrary. I want to group these fields into a unique list of objects.

Example (check it here):

<form method="post" action="#" class="container">
  <div class="form-group row">
    <label for="name" class="control-label">Name</label>
    <input type=text name="name" class="form-control" />
  </div>

  <fieldset id="phones" name="phones" class="form-row">
    <div class="form-group col-sm-2 clonable">
      <label for="label" class="control-label">Label</label>
      <input type=text name="label" class="form-control" />
    </div>

    <div class="form-group col-sm-2 clonable">
      <label for="number" class="control-label">Phone</label>
      <input type=text name="number" class="form-control" />
    </div>

    <div class"form-group col-sm-1">
      <input id="btnaddphone" type="button" value="Add" class="btn btn-primary" />
    </div>
  </fieldset>

  <div class="form-group row">
    <input type="submit" value="Submit" class="btn btn-success col-sm-2" />
  </div>
</form>

What I want is submit this form structured like the following json

{
    {name: "name", value: "..."},
    {name: "phones", value: [
        {name: "label", value: "..."}, {name: "number", value: "..."},
        {name: "label", value: "..."}, {name: "number", value: "..."}, ...
    ]}
}

And not like the default:

{
    {name: "name", value: "..."},
    {name: "label", value: "..."}, {name: "number", value: "..."},
    {name: "label", value: "..."}, {name: "number", value: "..."}, ...
}

Is there a simple way to do this with just HTML/JS?

If not, is there a way to configure it in a razor page for ASP.NET MVC?

2 Answers2

1

In case you were talking about Form Data, this could be a solution:

<form method="post" action="http://foobar.com" class="container">
  <div class="form-group row">
    <label for="name" class="control-label">Name</label>
    <input type=text name="name" class="form-control" />
  </div>

  <fieldset id="phones" class="form-row">
    <div class="form-group col-sm-2 clonable">
      <label class="control-label">Label</label>
      <input type=text name="phones[0][label]" class="form-control" />
    </div>

    <div class="form-group col-sm-2 clonable">
      <label class="control-label">Phone</label>
      <input type=text name="phones[0][number]" class="form-control" />
    </div>

    <div class"form-group col-sm-1">
      <input id="btnaddphone" type="button" value="Add" class="btn btn-primary" />
    </div>
  </fieldset>

  <div class="form-group row">
    <input type="submit" value="Submit" class="btn btn-success col-sm-2" />
  </div>
</form>

Notice <input name="phones[...][...] /> - you need to index your current group (phone label & number) and use that index in the name. You need to end up with pretty much the following in your DOM, where N is the current index of phone added:

    <div class="form-group col-sm-2 clonable">
      <label class="control-label">Label</label>
      <input type=text name="phones[0][label]" class="form-control" />
    </div>

    <div class="form-group col-sm-2 clonable">
      <label class="control-label">Phone</label>
      <input type=text name="phones[0][number]" class="form-control" />
    </div>

    <!-- N-1 repetitions ... -->

    <div class="form-group col-sm-2 clonable">
      <label class="control-label">Label</label>
      <input type=text name="phones[N][label]" class="form-control" />
    </div>

    <div class="form-group col-sm-2 clonable">
      <label class="control-label">Phone</label>
      <input type=text name="phones[N][number]" class="form-control" />
    </div>

This is based on this answer.

Amit Beckenstein
  • 1,220
  • 12
  • 20
0

Try this script, it should give the JSON structure.

<script>
    function toObject(arr){
        var rv = {};
        for(var i=0; i<arr.length; ++i){
            if(i % 2 == 0){
                rv['name'] = arr[i];
            }else{
                rv['value'] = arr[i];
            }
        }
        return rv;
    }
    $("form").on("submit", function(event){
        event.preventDefault();
        var textInputs = document.body.querySelectorAll('input[type="text"]'),
        nameArr = [],
        phonesArr = [],
        phonesvalArr = [];
        for(i=0; i<textInputs.length; i++){     
            var entry = [],
            inputnameVal = textInputs[i].name,
            inputvalueVal = textInputs[i].value;        
            if(i == 0){
                nameArr.push(inputnameVal);
                nameArr.push(inputvalueVal);    
                nameArr = toObject(nameArr);
                phonesArr.push('phones');           
            }else{
                entry.push(inputnameVal);
                entry.push(inputvalueVal);
                entry = toObject(entry);            
                phonesvalArr.push(entry);           
            }       
            if(textInputs.length == i+1){
                phonesArr.push(phonesvalArr);
                phonesArr = toObject(phonesArr);
                var output = "{"+JSON.stringify(nameArr)+","+JSON.stringify(phonesArr)+"}";
                console.log(output);
            }   
        }

    });

</script>
Cunlay
  • 12
  • 2