Question

I think I've searched long enough to warrant asking this, and I hope I'm not missing something obvious, but I'm at my wits' end with this. I'm a complete JavaScript noob, and I'm having difficulty getting a script I found online to work correctly.

The project I was assigned was to make it so this form could be extended by clicking a button, and I thought I'd be able to accomplish it with HTML alone, but that doesn't seem possible. I found this script, and was able to get the duplication part of it to work:

http://www.quirksmode.org/dom/domform.html

However, the part of the script that's supposed to append a counter to the names of the fields isn't working, and therefore when the form is submitted, everything is recorded under the first form's name value. My guess is that that part of the script is trying to get the name of the wrong node, but I really don't know. Here's a shortened version of what I have. Ugly, but hopefully it gets the point across...

http://pastebin.com/nQhnXXKx

Let me know if I can clarify, and any help would be greatly, greatly appreciated!

Was it helpful?

Solution

Reorganizing the code, you could use something like this:

(function () {
    "use strict";

    var counter, init, addWorkshop, renameInputs, removeWorkshop;

    counter = 0;

    init = function () {
        document.getElementById("moreWorkshops").onclick = addWorkshop;
        addWorkshop();
    };

    addWorkshop = function () {
        var clonedWorkshop, targetInsert;

        counter++;

        clonedWorkshop = document.getElementById("readroot").cloneNode(true);
        clonedWorkshop.id = "";
        clonedWorkshop.className = "";
        clonedWorkshop.querySelector(".remover").onclick = removeWorkshop;
        renameInputs(clonedWorkshop);

        targetInsert = document.getElementById("writeroot");
        targetInsert.parentNode.insertBefore(clonedWorkshop, targetInsert);
    };

    renameInputs = function (container) {
        var children, i, j, cur, theName;
        children = container.children;
        for (i = 0, j = children.length; i < j; i++) {
            cur = children[i];
            if (cur.nodeName.toLowerCase() === "input") {
                theName = cur.name;
                if (theName) {
                    cur.name = theName + counter;
                }
            } else {
                renameInputs(cur);
            }
        }
    };

    removeWorkshop = function () {
        this.parentNode.parentNode.removeChild(this.parentNode);
    };

    window.onload = init;
}());

DEMO: http://jsfiddle.net/gAaxS/

Note that this is very structure-specific - for example, the this.parentNode.parentNode means that it has exactly two ancestors that you want to target. If you changed the HTML, you'd have to change the JS (which is usual).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top