简体   繁体   中英

Dynamically adding fields to form using javascript

I'm trying to write a form where the user can add additional fields themselves. They will be able to add up to 5 new "options". within each option section I'd like them to be able to add up to 50 "variants".

An example of an option would be "size", with the variants being "small, medium, large". they can then add a second option for "colour", with the variants "red, blue, yellow"

it looks like this: 表格范例

here's the form script

<form method="POST" action="./form.php">
    <div id="static input">
    <p>Store Name: <input name="store" id="store" required></input></p>
    </div>

<div id="optionInput">
    <p>Option Name: <input name="option" id="option" required></input></p>
    <div><div class="col">Variant Name</div><div class="col">Price Modifier</div><div>Swatch Url</div></div>
        <div id="variantInput">
            <input type="text" name="myInputs[]"><input type="number" step="any" name="mods[]"><input type="text" step="any" name="urls[]">
        </div>
        <input type="button" value="+" onClick="addInput('variantInput');">
        <hr>
</div>
<p><input type="button" value="new option" onClick="addOption('optionInput');"></p>

<br><p><input type="submit"></input></p>
</form>

So Clicking the + button should add a new set of varibles, clicking the add option button should create a new option

here's the JavaScript to add new options and add new variables within an option.

var counter = 1;
var counter2 = 1;
var limit = 50;
var limit2 = 5;

function addInput(divName) {
    if (counter === limit) {
          alert("You have reached the limit of adding " + counter + " inputs");
    } else {
        var newdiv = document.createElement("div");
        newdiv.innerHTML = "<input type='text' name='myInputs[]'><input type='number' step='any' name='mods[]'><input type='text' step='any' name='urls[]'>";
        document.getElementById(divName).appendChild(newdiv);
        counter++;
    }
}

function addOption(divName) {
    if (counter2 === limit2) {
          alert("You have reached the limit of adding " + counter2 + " options");
    } else {
        var newdiv = document.createElement("div");
        newdiv.innerHTML = "<p>Option Name: <input name='option"+counter2+"' id='option"+counter2+"' required></input></p><div><div class='col'>Variant Name</div><div class='col'>Price Modifier</div><div>Swatch Url</div></div><div id='variantInput"+counter2+"'><input type='text' name='myInputs"+counter2+"[]'><input type='number' step='any' name='mods"+counter2+"[]'><input type='text' step='any' name='urls"+counter2+"[]'></div><input type='button' value='+' onClick='addInput('variantInput"+counter2+"');'><hr>";
        document.getElementById(divName).appendChild(newdiv);
        counter2++;
    }
}

At the moment the addOption apears to work, it adds new sets of options up to a maximum of 5. clicking the + button on under the first option (the one written into the form) works adding new variants.

the plus button under the dynamically added options does not work. console shows error "Uncaught SyntaxError: Unexpected token }"

Could someone please point out where i'm going wrong?

You are using triple nested quotations in your addOption function. You have to escape one of those, like this:

newdiv.innerHTML = "[...] onClick='addInput(\"variantInput" + counter2 + "\");'><hr>";

Little further explanation: you start opening the HTML string with double quotation marks " , then you use single quotation marks ' for the HTML attributes. Then you want to call a javascript function, which needs a string to be passed INSIDE of an attribute, which already uses ' . Now you have to escape the last quotation marks of that string with a backlash \\ to not break the nesting.

I agree with this code

newdiv.innerHTML = "[...] onClick='addInput(\\"variantInput" + counter2 + "\\");'><hr>";

But some problem was remaining overall clone system.

example your input limit 2. You can added 2 input in 1st option then 2nd option you can not add more then one input. because already 2 input added.

Full clone solution bellow code : please follow bellow function counter = 1

function addOption(divName) {
    if (counter2 === limit2) {
          alert("You have reached the limit of adding " + counter2 + " options");
    } else {
        var newdiv = document.createElement("div");
        newdiv.innerHTML = "<p>Option Name: <input name='option"+counter2+"' id='option"+counter2+"' required></input></p><div><div class='col'>Variant Name</div><div class='col'>Price Modifier</div><div>Swatch Url</div></div><div id='variantInput"+counter2+"'><input type='text' name='myInputs"+counter2+"[]'><input type='number' step='any' name='mods"+counter2+"[]'><input type='text' step='any' name='urls"+counter2+"[]'></div><input type='button' value='+' onClick='addInput(\"variantInput" + counter2 + "\");'><hr>";
        document.getElementById(divName).appendChild(newdiv);
        counter2++;
    }
    counter = 1;
}

I have just again initialize counter = 1 in function addOption(divName)

@Jamie Moffat now you can clone smoothly.

Thanks

The @user2415266's answer is quite perfect, explaining what was your error .

In the other hand it may be useful to examine how to avoid this kind of error , and at the same time make your code more readable (which is, in fact, the best way to avoid a lot of errors!).

So the first point is to break long long lines in order to clearly distinguish the content structure (even if at a first glance it seems more complicated).
For the part where the error lied, it might look like this (here I didn't correct the error, and it's hopefully clearly appearing in the involved line):

function addOption(divName) {
    if (counter2 === limit2) {
          alert("You have reached the limit of adding " + counter2 + " options");
    } else {
        var newdiv = document.createElement("div");
        newdiv.innerHTML = 
            "<p>Option Name: "
            + "<input name='option" + counter2 + "' id='option" + counter2 + "'"
            + "required></input>"
          + "</p>"
          + "<div>"
            + "<div class='col'>Variant Name</div>"
            + "<div class='col'>Price Modifier</div>"
            + "<div>Swatch Url</div>"
          + "</div>"
          + "<div id='variantInput" + counter2 + "'>"
            + "<input type='text' name='myInputs" + counter2 + "[]'>"
            + "<input type='number' step='any' name='mods" + counter2 + "[]'>"
            + "<input type='text' step='any' name='urls" + counter2 + "[]'>"
          + "</div>"
          + "<input type='button' value='+' "
            + "onClick='addInput('variantInput" + counter2 + "');'>"
          + "<hr>";
        document.getElementById(divName).appendChild(newdiv);
        counter2++;
    }
}

A more advanced way is to use the template literals notation, like this:

function addOption(divName) {
    if (counter2 === limit2) {
          alert("You have reached the limit of adding " + counter2 + " options");
    } else {
        var newdiv = document.createElement("div");
        newdiv.innerHTML = "
<p>
  Option Name:
  <input name='option${counter2}' id='option${counter2}' required></input>
</p>
<div>
  <div class='col'>Variant Name</div>
  <div class='col'>Price Modifier</div>
  <div>Swatch Url</div>
</div>
  <div id='variantInput" + counter2 + "'>
    <input type='text' name='myInputs${counter2}[]'>
    <input type='number' step='any' name='mods${counter2}[]'>
    <input type='text' step='any' name='urls${counter2}[]'>
  </div>
  <input type='button' value='+' onClick='addInput('variantInput${counter2}');'>
  <hr>
        ";
        document.getElementById(divName).appendChild(newdiv);
        counter2++;
    }
}

Not only it totally avoids to face an occasion to have the error, but it also increases the readability, allowing to make the HTML part appear someway "independent", like if it was the current language.

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