简体   繁体   中英

HTML/Javascript Form How do I serialize form data as JSON and displayed in a class?

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;
    });

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

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> 

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> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM