2

Pretty straight forward.

When a user clicks "submit", I need the form serialized and the JSON data displayed in the class"debug".

How do I do this with my current Javascript?

Cannot use jQuery. Cannot edit HTML. Only pure Javascript.

Thanks!

HTML

<ol class="household"></ol>
    <form>
        <div>
            <label>Age
                <input type="text" name="age">
            </label>
        </div>
        <div>
            <label>Relationship
                <select name="rel">
                    <option value="">---</option>
                    <option value="self">Self</option>
                    <option value="spouse">Spouse</option>
                    <option value="child">Child</option>
                    <option value="parent">Parent</option>
                    <option value="grandparent">Grandparent</option>
                    <option value="other">Other</option>
                </select>
            </label>
        </div>
        <div>
            <label>Smoker?
                <input type="checkbox" name="smoker">
            </label>
        </div>
        <div>
            <button class="add">add</button>
        </div>
        <div>
            <button type="submit">submit</button>
        </div>
    </form>
</div>
<pre class="debug"></pre>

JS

function validate(form) {
        fail = validateAge(form.age.value)
        fail += validateRel(form.rel.value)

        if (fail == "") return true
        else {
            alert(fail);
            return false
        }
    }

    function validateAge(field) {
        if (isNaN(field)) return "No age was entered. \n"
        else if (field < 1 || field > 200)
            return "Age must be greater than 0. \n"
        return ""
    }

    function validateRel(field) {
        if (field == "") return "Please select a relationship \n"
        return ""
    }

    document.querySelector("form").onsubmit = function() {
        return validate(this)
    }

    document.querySelector(".add").onclick = function(event) {
        event.preventDefault();
        createinput()
    }

    count = 0;
    function createinput() {
        field_area = document.querySelector('.household')
        var li = document.createElement("li");
        var p1 = document.createElement("p");
        var p2 = document.createElement("p");
        var p3 = document.createElement("p");
        var x = document.getElementsByName("age")[0].value;
        var y = document.getElementsByName("rel")[0].value;
        var z = document.getElementsByName("smoker")[0].checked;
        if (!z) {
            z = "Non smoker \n";
        } else {
            z = "Smoker \n";
        }
        p1.innerHTML = x;
        p2.innerHTML = y;
        p3.innerHTML = z;
        li.appendChild(p1);
        li.appendChild(p2);
        li.appendChild(p3);
        field_area.appendChild(li);
        //removal link
        var removalLink = document.createElement('a');
        removalLink.onclick = function() {
            this.parentNode.parentNode.removeChild(this.parentNode)
        }
        var removalText = document.createTextNode('Remove Field');
        removalLink.appendChild(removalText);
        li.appendChild(removalLink);
        count++
    }

    // serialize form
    var data = {};
    var inputs = [].slice.call(e.target.querySelector('form'));
    inputs.forEach(input => {
        data[input.name] = input.value;
    });
1

3 Answers 3

3

The shortest possible solution (pure javascript):

var form = document.querySelector('form');
var data = new FormData(form);

docs: https://developer.mozilla.org/en-US/docs/Web/API/FormData

Sign up to request clarification or add additional context in comments.

Comments

2

I know this form very well as I applied for same job position.It is an interesting task. Here is your answer with pure js!

var peopleList = [];
var addButton = document.querySelector('button.add');
var submitButton = document.querySelector('button[type=submit]');
var debug = document.querySelector('pre.debug');
var mainForm = document.forms[0];
var ageFormField = mainForm.age;
var relationshipFormField = mainForm.rel;
var smokerFormField = mainForm.smoker;
var positionFormField=mainForm.position;

//Taken from https://www.inventpartners.com/open-source/free-web-software/javascript_is_int
function is_int(value) {
    if ((parseFloat(value) == parseInt(value)) && !isNaN(value)) {
        return true;
    } else {
        return false;
    }
}

function formIsValid() {
    return ageFormField.value != '' && is_int(ageFormField.value) && relationshipFormField.selectedIndex != 0 && positionFormField.value !='';
}

function updateDebug() {
    if (peopleList.length != 0) {
        debug.innerText = JSON.stringify(peopleList);
        debug.setAttribute('style', 'display: block');
        submitButton.disabled = false;
    } else {
        debug.innerText = '';
        debug.removeAttribute('style');
        submitButton.disabled = true;
    }
}

function addEventClick(event) {
    event.preventDefault();
    if (formIsValid()) {
        peopleList.push({
            'age': ageFormField.value,
            'position':positionFormField.value,
            'relationship': relationshipFormField.options[relationshipFormField.selectedIndex].value,
            'isSmoker': smokerFormField.checked,
           
        });
        updateDebug();
        ageFormField.value = '';
        positionFormField.value='';
        relationshipFormField.selectedIndex = 0;
        smokerFormField.checked = false;
      
    } else {
        var errors = '';
        if (ageFormField.value == '') {
            errors += 'Please enter your age!';
        } else if (!is_int(ageFormField.value)) {
            errors += 'Age must be a numeric value!';
        }
        if (relationshipFormField.selectedIndex == 0) {
            if (errors != '') {
                errors += '\n';
            }
            errors += 'Please select your relationship status!';
        }

        if (positionFormField.value == '') {
            if (errors != '') {
                errors += '\n';
            }
            errors += 'Please enter your position!';
        }
        if (errors != '') {
            alert(errors);
            errors = '';
        }
         else if (
            errors != '') {
                alert(errors);
                errors = '';
        }
    }
}

function submitEventClick(event) {
    event.preventDefault();
    if (peopleList.length != 0) {
        var http = new XMLHttpRequest();
        var url = "savePeopleList.php";
        http.open('POST', url, true);
        http.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
        http.onreadystatechange = function() {
            if (http.readyState == 4) {
                if (http.status == 200) {
                    peopleList = [];
                    updateDebug();
                    alert('All of the changes were saved to the server!');
                } else {
                    alert('An error occured while sending the data to the server!');
                }
            }
        };
        http.send(JSON.stringify(peopleList));
    }
}

addButton.addEventListener('click', addEventClick, false);
submitButton.addEventListener('click', submitEventClick, false);
updateDebug();
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>Household builder</title>
        <style>
            .debug {
                font-family: monospace;
                border: 1px solid black;
                padding: 10px;
                display: none;
            }
        </style>
    </head>
    <body>
        <h1>Household builder</h1>
        <div class="builder">
            <ol class="household"></ol>
            <form>
                <div>
                    <label>Age
                        <input type="text" name="age">
                    </label>
                </div>
                <div>
                    <label>Position
                        <input type="text" name="position">
                    </label>
                </div>
                <div>
                    <label>Relationship
                        <select name="rel">
                            <option value="">---</option>
                            <option value="self">Self</option>
                            <option value="spouse">Spouse</option>
                            <option value="child">Child</option>
                            <option value="parent">Parent</option>
                            <option value="grandparent">Grandparent</option>
                            <option value="other">Other</option>
                        </select>
                    </label>
                </div>
                <div>
                    <label>Smoker?
                        <input type="checkbox" name="smoker">
                    </label>
                </div>
                <div>
                    <button class="add">add</button>
                </div>
                <div>
                    <button type="submit">submit</button>
                </div>
            </form>
        </div>
        <pre class="debug"></pre>
        <script type="text/javascript" src="./index.js"></script>
    </body>
</html>

Comments

2

Iterate through the form, grabbing the various elements and creating new objects for each one, then setting the properties for each object and pushing to the final array would solve your problem fairly easily.

Then you can simply use querySelectorAll to match .debug and use JSON.stringify() to convert your array to a string and innerText to set the contents.

Example:

function go() {
  var debug_class = document.querySelectorAll(".debug");
  for (var i = 0; i < debug_class.length; i++) {
    var element = debug_class[i];
    element.innerText = JSON.stringify(serializeArray(document.querySelector("form")));
  }

}

function serializeArray(form) {
  var field, l, s = [];
  if (typeof form == 'object' && form.nodeName == "FORM") {
    var len = form.elements.length;
    for (i = 0; i < len; i++) {
      field = form.elements[i];
      if (field.name && !field.disabled && field.type != 'file' && field.type != 'reset' && field.type != 'submit' && field.type != 'button') {
        if (field.type == 'select-multiple') {
          l = form.elements[i].options.length;
          for (j = 0; j < l; j++) {
            if (field.options[j].selected)
              s[s.length] = {
                name: field.name,
                value: field.options[j].value
              };
          }
        } else if ((field.type != 'checkbox' && field.type != 'radio') || field.checked) {
          s[s.length] = {
            name: field.name,
            value: field.value
          };
        }
      }
    }
  }
  return s;
}
<form id="blah">
  <input type="text" name="input1" value="a"></input>
  <input type="text" name="input2" value="b"></input>
  <input type="text" name="input3" value="c"></input>
  <input type="text" name="input4" value="d"></input>

</form>
<button onclick="go()">Serialize!</button>

<div class="debug"></div>

EDIT

In your particular case, after including the above code, you would have to call go() at some point to generate the serialized data.

Here's how to do it after clicking on add

 document.querySelector(".add").onclick = function(event) {
        go();   // display in .debug
        event.preventDefault();
        createinput()
    }

FULL SNIPPET

function go() {
  var debug_class = document.querySelectorAll(".debug");
  for (var i = 0; i < debug_class.length; i++) {
    var element = debug_class[i];
    element.innerText = JSON.stringify(serializeArray(document.querySelector("form")));
  }

}

function serializeArray(form) {
  var field, l, s = [];
  if (typeof form == 'object' && form.nodeName == "FORM") {
    var len = form.elements.length;
    for (i = 0; i < len; i++) {
      field = form.elements[i];
      if (field.name && !field.disabled && field.type != 'file' && field.type != 'reset' && field.type != 'submit' && field.type != 'button') {
        if (field.type == 'select-multiple') {
          l = form.elements[i].options.length;
          for (j = 0; j < l; j++) {
            if (field.options[j].selected)
              s[s.length] = {
                name: field.name,
                value: field.options[j].value
              };
          }
        } else if ((field.type != 'checkbox' && field.type != 'radio') || field.checked) {
          s[s.length] = {
            name: field.name,
            value: field.value
          };
        }
      }
    }
  }
  return s;
}


function validate(form) {
  fail = validateAge(form.age.value)
  fail += validateRel(form.rel.value)

  if (fail == "") return true
  else {
    alert(fail);
    return false
  }
  go();
}

function validateAge(field) {
  if (isNaN(field)) return "No age was entered. \n"
  else if (field < 1 || field > 200)
    return "Age must be greater than 0. \n"
  return ""
}

function validateRel(field) {
  if (field == "") return "Please select a relationship \n"
  return ""
}

document.querySelector("form").onsubmit = function() {
  return validate(this)
}

document.querySelector(".add").onclick = function(event) {
  go();
  event.preventDefault();
  createinput()
}

count = 0;

function createinput() {
  field_area = document.querySelector('.household')
  var li = document.createElement("li");
  var p1 = document.createElement("p");
  var p2 = document.createElement("p");
  var p3 = document.createElement("p");
  var x = document.getElementsByName("age")[0].value;
  var y = document.getElementsByName("rel")[0].value;
  var z = document.getElementsByName("smoker")[0].checked;
  if (!z) {
    z = "Non smoker \n";
  } else {
    z = "Smoker \n";
  }
  p1.innerHTML = x;
  p2.innerHTML = y;
  p3.innerHTML = z;
  li.appendChild(p1);
  li.appendChild(p2);
  li.appendChild(p3);
  field_area.appendChild(li);
  //removal link
  var removalLink = document.createElement('a');
  removalLink.onclick = function() {
    this.parentNode.parentNode.removeChild(this.parentNode)
  }
  var removalText = document.createTextNode('Remove Field');
  removalLink.appendChild(removalText);
  li.appendChild(removalLink);
  count++
}

// serialize form

var data = {};
var inputs = [].slice.call(e.target.querySelector('form'));
inputs.forEach(input => {
  data[input.name] = input.value;
});
<ol class="household"></ol>
<form>
  <div>
    <label>Age
      <input type="text" name="age">
    </label>
  </div>
  <div>
    <label>Relationship
      <select name="rel">
        <option value="">---</option>
        <option value="self">Self</option>
        <option value="spouse">Spouse</option>
        <option value="child">Child</option>
        <option value="parent">Parent</option>
        <option value="grandparent">Grandparent</option>
        <option value="other">Other</option>
      </select>
    </label>
  </div>

  <div>

    <label>Smoker?
      <input type="checkbox" name="smoker">
    </label>
  </div>

  <div>
    <button class="add">add</button>
  </div>
  <div>
    <button type="submit">submit</button>
  </div>
</form>
</div>
<pre class="debug"></pre>

10 Comments

hey @mike510a thanks for sharing. I added the code and I don't see the values populating in the class="debug". What am I doing wrong?
In my example the form's name is 'blah' -- for your case it would be element.innerText = JSON.stringify(serializeArray(document.querySelector('form')));
Also you have to add the <button onclick="go()">Serialize!</button> part to make it actually work -- specifically the onlick="go()" part
Hey Mike - I can't add any additional HTML. Only pure JS for this. :/
hey @mike510a I'm still not seeing the JSON values in the class="debug". :/
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.