Will Ashley Will Ashley - 2 months ago 8
Javascript Question

Dynamically create HTML forms not working

I am trying to create several forms for the options page of a Chrome extension, but when I click 'add', the forms do not appear.

options.html


<!DOCTYPE html>
<html>
<head><title>My Test Extension Options</title></head>
<body>
<header>
<h1>My Tabs</h1>
</header>
<form id='fields'>
<button id="createNew">Add...</button>
</form>

<div id="status"></div>
<button id="save">Save</button>

</body>
<script src="./js/options.js"></script>
</html>


options.js


function render_form() {
let counter = 0;
let newdiv = document.createElement('div');
newdiv.innerHTML = "Entry " + (counter + 1) + " <br><input type='text' name='myInputs[]'>";
document.getElementById('fields').appendChild(newdiv);
counter++;
}

document.getElementById('createNew').addEventListener('click', render_form());


When I take out the invocation from the very last line (ie saying
render_form
instead of
render_form()
), the input field will not be there at all, but when I do invoke, the initial field will be there, but nothing will happen upon clicking the
Add...
button.

Answer

If your code is using only non-Chrome API basic HTML + JavaScript (which yours is) and it does not work in a regular browser page environment, then it is not going to work in a Chrome extension options page or popup.

Your code, as it is, does not function because you are trying to assign the return value from render_form() as your event listener with:

addEventListener('click', render_form());

If you change that to actually assign the render_form function as the event listener:

addEventListener('click', render_form);

it will actually add the <input> elements. It probably isn't exactly what you are wanting (i.e. counter is always 0).

Your question implies that you want one entry field to be there by default. Thus, I have added an invocation of the render_form() function after adding it as a listener. I have also moved counter to be global so that your counting works as I believe you desire.

var counter = 0;
function render_form() {
  let newdiv = document.createElement('div');
  newdiv.innerHTML="Entry "+(counter + 1)+" <br><input type='text' name='myInputs[]'/>";
  document.getElementById('fields').appendChild(newdiv);
  counter++;
}

document.getElementById('createNew').addEventListener('click', render_form);
render_form();
<!DOCTYPE html>
<html>
<head><title>My Test Extension Options</title></head>
<body>
  <header>
    <h1>My Tabs</h1>
  </header>
  <form id='fields'>
    <button id="createNew" type='button'>Add...</button>
  </form>

  <div id="status"></div>
  <button id="save" type='button'>Save</button>

</body>
  <!-- Comment out the external script which is required in a Chrome popup,
       but which does not work in a Stack Overflow snippet.
  <script src="./js/options.js"></script>
  -->
</html>

NOTE: In addition to this snippet, I have tested the above code in Google Chrome as the options page for an extension. It works fine in that context.

Comments