3

I am currently working on a project where I need to be able to handle storing and viewing HTML strings (from a database, but from the page itself for testing) which have input elements in them. I also need to store the current input values (what the user has placed in them while the user is viewing the page) of the elements, preferably within the HTML string.

Here is an example of what I looking for help with:

I have the following HTML displaying:

<p id="pullfrom">
Character Name: <input><br>
Character Level: <input type="number">
</p>
<button onclick="algorithm('pullfrom')">Save</button>

The user then enters a character name of "Garrus Vakarian" into the text box and "5" into the number box. Then the user presses the save button which calls the algorithm.

The algorithm then returns:

<p id="pullfrom">
Character Name: <input value="Garrus Vakarian"><br>
Character Level: <input type="number" value="5">
</p>
cyborgdragon
  • 109
  • 6
  • Start here - https://stackoverflow.com/questions/11563638/how-do-i-get-the-value-of-text-input-field-using-javascript . Aside, typically programmers want structured data like json from their web forms. Your returned html looks unlikely. – ThisClark Jul 14 '17 at 01:48
  • The reason that we are doing what we are doing with HTML is that we don't know the form that we are going to have. So, one user creates a form (refereed to as a template) and then another user creates an instance of it (refereed to as a journal entry or character sheet). We can then take both and shove them into an x.innerHTML and they instantly display as the original creator wanted the template to with the values in the journal entry or character sheet. – cyborgdragon Jul 16 '17 at 22:23

1 Answers1

3

Using setAttribute( "value", npt.value )

Sets the value of an attribute on the specified element. If the attribute already exists, the value is updated; otherwise a new attribute is added with the specified name and value.

forEach <input> in the element being parsed, we can set the HTML value attribute to the value supplied, then get the outerHTML toString().

function algorithm( id ) {
  const e = document.getElementById( id ),
        npts = e.querySelectorAll( "input" );
  npts?.forEach( npt => npt.setAttribute( "value", npt.value ) );
  console.log( e.outerHTML.toString() );
}
<p id="pullfrom">
Character Name: <input><br>
Character Level: <input type="number">
</p>
<button onclick="algorithm('pullfrom')">Save</button>

Note: this is a terrible way of gathering form data and torturing the DOM like this should probably be a crime. However...

For more complex and standard <form>s

Although the following example isn't a very complex <form>, it should demonstrate how this method might be expanded to handle different types of form data.

const frm = document.getElementById( "demo" );
frm.submit.addEventListener( "click", () => {
  // grab all desired inputs by tag
  const npts = frm.querySelectorAll( 'input:not([type="button"]), select, textarea' );
  npts?.forEach( npt => {
    switch ( npt.tagName.toLowerCase() ) {
      case "input": {
        switch ( npt.type ) {
          case "radio":
          case "checkbox": {
            npt.removeAttribute( "checked" ); // remove prior selections
            npt.setAttribute( "checked", npt.checked );
            break;
          }
          default: npt.setAttribute( "value", npt.value );
        }
        break;
      }
      case "textarea": npt.textContent = npt.value; break;
      case "select":
        const optns = npt.querySelectorAll( "option" ),
              pre_slctd = npt.querySelector( "[selected]" );
        if ( pre_slctd ) {
          pre_slctd.removeAttribute( "selected" ); // remove prior selections
        }
        optns[ npt.selectedIndex ].setAttribute( "selected", "selected" );
        break;
    }
  } );
  console.log( frm.outerHTML.toString() );
}, { passive: true } );
label {
  display: block;
  margin-bottom: .3em;
}
<form id="demo">
  <label>Character name: <input name="char_name" type="text"></label>
  <label>Character level: <input name="char_level" type="number"></label>
  <label>Character species: <select name="char_species">
    <option value="imagination">Human</option>
    <option value="cuddly" selected>Anthro</option>
    <option value="target_practice">Undead</option>
    <option value="caffeine_sponge">Developer</option>
  </select></label>
  <fieldset>
    <legend>Character's favourite radio station</legend>
    <label>Electro: <input type="radio" name="char_radio" value="electro" checked></label>
    <label>Black metal: <input type="radio" name="char_radio" value="black_metal"></label>
    <label>Opera: <input type="radio" name="char_radio" value="opera"></label>
  </fieldset>
  <label>Character has character: <input name="char_char" type="checkbox"></label>
  <label for="bio">Bio:</label>
  <textarea name="char_bio" id="bio"></textarea>
  <label>I do not understand the Terms of Service because I have not read them: <input name="tos" type="checkbox" required></label>
  <input name="submit" type="button" value="Submit">
</form>
Fred Gandt
  • 4,217
  • 2
  • 33
  • 41
  • That was exactly what I asked for, but would there be a edit to the npts line that allows the loop to handle any form element? – cyborgdragon Jul 14 '17 at 13:22
  • Anything that's not an `` will be copied like the `
    ` and `

    ` tags (and content). Other than the `` `value`s, what might change that the HTML won't record? `class` and `style` changes will be recorded by the HTML, so will be copied. Ah! Like `

    – Fred Gandt Jul 14 '17 at 13:47
  • Yes, like "updating" the values of the – cyborgdragon Jul 14 '17 at 14:03
  • 1
    Updated with example. Please tell me if this helps or doesn't. – Fred Gandt Jul 14 '17 at 14:11
  • That does help, but what would I need to do to make it also work with – cyborgdragon Jul 15 '17 at 22:53
  • 1
    @cyborgdragon - Updated second example rather than adding another; added ` – Fred Gandt Jul 16 '17 at 02:56
  • Is it any way for that to work with input type checkbox and radio, because now it doesnt? – Даяна Димитрова Dec 14 '21 at 09:37
  • I have updated the answer to include some radio and checkbox handling, but looking back at this code, I highly recommend not using it as a method of gathering form data at all. – Fred Gandt Dec 14 '21 at 14:01