Home > database >  Add input field onclick with new name
Add input field onclick with new name

Time:03-09

I want to display a new input field with a new name everytime a button is clicked. how do I achieve that? I found solutions to adding the input but none mentions adding a new name to it.

HTML:

<a href="" onclick="addKeywordFields()">Add a keyword</a>
<div id="fieldContainer"></div>

Javascript:

function addKeywordFields() {
    var mydiv = document.getElementById("fieldContainer");
    mydiv.appendChild(document.createTextNode("<input type='text' name=''>"))
}

CodePudding user response:

You should not use document.createTextNode to create an input. This will only create a text element with content specified inside it.

Instead you should create an input using document.createElement('input') and specify its type and name.

Since you need a dynamic name, you have to integrate a dynamic name generation logic. Here I used (new Date()).toISOString() since this will e unique each time. Instead you have to use your own logic.

Working Fiddle

function addKeywordFields() {
    var mydiv = document.getElementById("fieldContainer");
    const input = document.createElement('input');
    input.type = 'text';
    input.name = (new Date()).toISOString(); // Some dynamic name logic
    mydiv.appendChild(input);
}
<a onclick="addKeywordFields()">Add a keyword</a>
<div id="fieldContainer"></div>

CodePudding user response:

There's a ton of DOM methods designed to create, destroy, move, etc. There's generally three ways to create a DOM element programmatically:

  • clone an element with .cloneNode() and .append()

  • parse a string that represents HTML (aka htmlString) use .insertAdjacentHTML() instead of .innerHTML

  • create an element with .createElement() and .append()

Assigning attributes/properties to an element can be done initially with .setAttribute() once an attribute has been assigned to an element, it is technically a property. This distinction between attribute and property is blurry because methods seem to work 100% as does assigning properties. jQuery is not so flexible in this instance, .attr() and .prop() have silently failed on me when I forget about attribute/property quirks.

I rarely use methods to assign attributes, properties are terse and simple to use, here's a few common ones:

obj.id = "ID", obj.className = "CLASS", obj.name = "NAME"❉, 
obj.type = "TEXT", obj.dataset.* = "*"

❉This is the property you use to set/get name attribute

  • I always add a <form> if there's multiple form controls. There are special features and terse syntax if you use interfaces like HTMLFormElement and HTMLFormControlsCollection. Moreover having a <form> you can use it to listen for events for everything within it and also take advantage of special form events like "input", "change", "submit", etc.

  • HTMLFormElement.elements collects all form controls (listed below)
    <button>, <fieldset>, <input>, <object>, <output>, <select>, <textarea>.
    From the .elements property, any form control can be referenced by #id or [name]. If there is a group of form controls that share a [name] they can be collected into a HTMLCollection.

References

HTMLFormElement

HTMLFormControlsCollection

Events

Event Delegation

Further details are commented in example below

// Reference the form (see HTMLFormElement)
const UI = document.forms.UI;
// Register form to click event
UI.addEventListener('click', makeInput);
// Define a counter outside of function
let dataID = 0;
// Pass Event Object
function makeInput(e) {
  /* 
  "this" is the form
  .elements property is a collection of all form controls 
  (see HTMLFormsCollection)
  */
  const io = this.elements;
  // Event.target points to the tag user clicked
  const clk = e.target;
  /* 
  This is the fieldset containing the inputs it's in bracket notation 
  instead of dot notation because it's a hyphenated property
  */
  const grp = io['form-group'];
  // This is the static input
  const inp = io.data;

  // if the clicked tag is a button...
  if (clk.matches('button')) {
    // ...increment the counter
    dataID  ;
    /*
    This switch() delegates what to do by the clicked button's [name].
    Each case is a different way to create an element and assign a unique 
    [name] by concatenating the "data" with the current number of dataID
    */
    switch (clk.name) {
      case 'clone':
        const copy = inp.cloneNode(true);
        copy.name = 'data'   dataID;
        grp.append(copy);
        break;
      case 'html':
        const htmlStr = `
        <input name="data${dataID}">`;
        grp.insertAdjacentHTML('beforeEnd', htmlStr);
        break;
      case 'create':
        const tag = document.createElement('input');
        tag.name = 'data'   dataID;
        grp.append(tag);
        break;
      default:
        break;
    }
  }
};
form {
  display: flex;
}

fieldset {
  display: inline-flex;
  flex-direction: column;
  justify-content: flex-startd;
  max-width: 90%;
}

input,
button {
  display: inline-block;
  width: 80px;
  margin-bottom: 4px;
}

input {
  width: 150px;
}

button {
  cursor: pointer;
}
<form id='UI'>
  <fieldset name='btn-group'>
    <button name='clone' type='button'>Clone Node</button>
    <button name='html' type='button'>Parse htnlString</button>
    <button name='create' type='button'>Create Element</button>
  </fieldset>
  <fieldset name='form-group'>
    <input name='data'>
  </fieldset>
</form>

  • Related