-2

Here's my issue:

When a user clicks "submit", I need the form serialized, the JSON data displayed in the class="debug", including the list item data if a user has been added.

Currently, the only data that I see is what's currently in the input fields when I hit "submit" and not the list items if I add users. I need the list items (if i add users) in addition to what gets submitted in the input fields.

How do I do this with my current Javascript?

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

Thanks & Happy New Year from America!

HTML

<div class="builder">
    <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 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(inputs.target.querySelector('form'));
    inputs.forEach(input => {
        data[input.name] = input.value;
    });
spidey677
  • 317
  • 1
  • 10
  • 27
  • You have no HTML class `debug`, so your `go()` function won't do anything. – Obsidian Age Jan 01 '17 at 03:20
  • Hey @obsidian Age forgot to fully copy and paste my html. Just updated the HTML portion. Please let me know what you think. I'm left scratching my head on this one. I don't know what I'm missing. – spidey677 Jan 01 '17 at 03:22
  • Hey @ObsidianAge forgot to fully copy and paste my html. Just updated the HTML portion. Please let me know what you think. I'm left scratching my head on this one. I don't know what I'm missing. All i need is my dynamic list item values submitted in addition to what's in the form field when the user hits submit. – spidey677 Jan 01 '17 at 03:25

1 Answers1

1

JavaScript by nature cannot post dynamic form elements through a typical HTML 'submit' button. It would be fairly straightforward with jQuery, but you say you cannot use that. Also, your HTML structure makes dealing with form submission through raw JavaScript rather clunky, as you can't edit it to attach a function to the form submission (nor change the HTML).

You also need to serialize the form before submission, which is clunky without jQuery. There's plenty of libraries to do that, but you may need a particular one based on your code structure. Plenty of examples on how to do that can be found here.

// Sample serialization function structure
function serialize(form) {
    // Serialize
}

You would then need to create a JavaScript element from the form, attach an event listener manually, prevent the form submission, serialize the data, and re-submit manually.

const element = document.querySelector('form');
 element.addEventListener('submit', event => {
   event.preventDefault();
   serialize(element);
   element.submit();
 });

A complex process, and you may want to look into an alternative approach to the process as a whole. However, I hope this is able to solve your problem :)

Community
  • 1
  • 1
Obsidian Age
  • 41,205
  • 10
  • 48
  • 71
  • Cool. Thanks for the info. I'm used to do all this jQuery way too, just not sure how to do the Javascript route since I'm more of a mix between design/dev. Happy New Year! – spidey677 Jan 01 '17 at 20:52
  • Happy New Year to you too, and good luck with your project :) – Obsidian Age Jan 01 '17 at 21:24