How can I get form data with JavaScript/jQuery?

前端 未结 28 1899
不知归路
不知归路 2020-11-22 12:39

Is there a simple, one-line way to get the data of a form as it would be if it was to be submitted in the classic HTML-only way?

For example:



        
相关标签:
28条回答
  • 2020-11-22 13:32
    document.querySelector('form').addEventListener('submit', (e) => {
      const formData = new FormData(e.target);
      // Now you can use formData.get('foo'), for example.
      // Don't forget e.preventDefault() if you want to stop normal form .submission
    });
    

    This is a nitpicky answer, but let me explain why this is a better solution:

    • We're properly handling a form submit rather than a button press. Some people like to push enter on fields. Some people use alternative input devices such as speech input or other accessibility devices. Handle the form submit and you correctly solve it for everyone.

    • We're digging into the form data for the actual form that was submitted. If you change your form selector later, you don't have to change the selectors for all the fields. Furthermore, you might have several forms with the same input names. No need to disambiguate with excessive IDs and what not, just track the inputs based on the form that was submitted. This also enables you to use a single event handler for multiple forms if that is appropriate for your situation.

    • The FormData interface is fairly new, but is well supported by browsers. It's a great way to build that data collection to get the real values of what's in the form. Without it, you're going to have to loop through all the elements (such as with form.elements) and figure out what's checked, what isn't, what the values are, etc. Totally possible if you need old browser support, but the FormData interface is simpler.

    • I'm using ES6 here... not a requirement by any means, so change it back to be ES5 compatible if you need old browser support.

    0 讨论(0)
  • 2020-11-22 13:32

    It is 2019 and there's a better way to do this:

    const form = document.querySelector('form');
    const data = new URLSearchParams(new FormData(form).entries());
    

    or if you want a plain Object instead

    const form = document.querySelector('form');
    const data = Object.fromEntries(new FormData(form).entries());
    

    although note that this won't work with duplicate keys like you get from multi-select and duplicate checkboxes with the same name.

    0 讨论(0)
  • 2020-11-22 13:32

    Here's a really simple and short soluton that even doesn't require Jquery.

    var formElements=document.getElementById("myForm").elements;    
    var postData={};
    for (var i=0; i<formElements.length; i++)
        if (formElements[i].type!="submit")//we dont want to include the submit-buttom
            postData[formElements[i].name]=formElements[i].value;
    
    0 讨论(0)
  • 2020-11-22 13:33

    Here is a working JavaScript only implementation which correctly handles checkboxes, radio buttons, and sliders (probably other input types as well, but I've only tested these).

    function setOrPush(target, val) {
        var result = val;
        if (target) {
            result = [target];
            result.push(val);
        }
        return result;
    }
    
    function getFormResults(formElement) {
        var formElements = formElement.elements;
        var formParams = {};
        var i = 0;
        var elem = null;
        for (i = 0; i < formElements.length; i += 1) {
            elem = formElements[i];
            switch (elem.type) {
                case 'submit':
                    break;
                case 'radio':
                    if (elem.checked) {
                        formParams[elem.name] = elem.value;
                    }
                    break;
                case 'checkbox':
                    if (elem.checked) {
                        formParams[elem.name] = setOrPush(formParams[elem.name], elem.value);
                    }
                    break;
                default:
                    formParams[elem.name] = setOrPush(formParams[elem.name], elem.value);
            }
        }
        return formParams;
    }
    

    Working example:

        function setOrPush(target, val) {
          var result = val;
          if (target) {
            result = [target];
            result.push(val);
          }
          return result;
        }
    
        function getFormResults(formElement) {
          var formElements = formElement.elements;
          var formParams = {};
          var i = 0;
          var elem = null;
          for (i = 0; i < formElements.length; i += 1) {
            elem = formElements[i];
            switch (elem.type) {
              case 'submit':
                break;
              case 'radio':
                if (elem.checked) {
                  formParams[elem.name] = elem.value;
                }
                break;
              case 'checkbox':
                if (elem.checked) {
                  formParams[elem.name] = setOrPush(formParams[elem.name], elem.value);
                }
                break;
              default:
                formParams[elem.name] = setOrPush(formParams[elem.name], elem.value);
            }
          }
          return formParams;
        }
    
        //
        // Boilerplate for running the snippet/form
        //
    
        function ok() {
          var params = getFormResults(document.getElementById('main_form'));
          document.getElementById('results_wrapper').innerHTML = JSON.stringify(params, null, ' ');
        }
    
        (function() {
          var main_form = document.getElementById('main_form');
          main_form.addEventListener('submit', function(event) {
            event.preventDefault();
            ok();
          }, false);
        })();
    <form id="main_form">
      <div id="questions_wrapper">
        <p>what is a?</p>
        <div>
          <input type="radio" required="" name="q_0" value="a" id="a_0">
          <label for="a_0">a</label>
          <input type="radio" required="" name="q_0" value="b" id="a_1">
          <label for="a_1">b</label>
          <input type="radio" required="" name="q_0" value="c" id="a_2">
          <label for="a_2">c</label>
          <input type="radio" required="" name="q_0" value="d" id="a_3">
          <label for="a_3">d</label>
        </div>
        <div class="question range">
          <label for="a_13">A?</label>
          <input type="range" required="" name="q_3" id="a_13" min="0" max="10" step="1" list="q_3_dl">
          <datalist id="q_3_dl">
            <option value="0"></option>
            <option value="1"></option>
            <option value="2"></option>
            <option value="3"></option>
            <option value="4"></option>
            <option value="5"></option>
            <option value="6"></option>
            <option value="7"></option>
            <option value="8"></option>
            <option value="9"></option>
            <option value="10"></option>
          </datalist>
        </div>
        <p>A and/or B?</p>
        <div>
          <input type="checkbox" name="q_4" value="A" id="a_14">
          <label for="a_14">A</label>
          <input type="checkbox" name="q_4" value="B" id="a_15">
          <label for="a_15">B</label>
        </div>
      </div>
      <button id="btn" type="submit">OK</button>
    </form>
    <div id="results_wrapper"></div>

    edit:

    If you're looking for a more complete implementation, then take a look at this section of the project I made this for. I'll update this question eventually with the complete solution I came up with, but maybe this will be helpful to someone.

    0 讨论(0)
提交回复
热议问题