form serialize javascript (no framework)

后端 未结 23 1345
一生所求
一生所求 2020-11-22 16:07

Wondering is there a function in javascript without jquery or any framework that allows me to serialize the form and access the serialized version?

相关标签:
23条回答
  • 2020-11-22 16:47
    document.serializeForm = function (selector) {
         var dictionary = {};
         var form = document.querySelector(selector);
         var formdata = new FormData(form);
         var done = false;
         var iterator = formdata.entries();
         do {
             var prop = iterator.next();
             if (prop.done && !prop.value) {
                 done = true;
             }
             else {
                 dictionary[prop.value[0]] = prop.value[1];
             }
    
         } while (!done);
         return dictionary;
    }
    
    0 讨论(0)
  • 2020-11-22 16:48
    function serialize (form) {
        if (!form || form.nodeName !== "FORM") {
                return;
        }
        var i, j, q = [];
        for (i = form.elements.length - 1; i >= 0; i = i - 1) {
            if (form.elements[i].name === "") {
                continue;
            }
            switch (form.elements[i].nodeName) {
                case 'INPUT':
                    switch (form.elements[i].type) {
                        case 'text':
                        case 'tel':
                        case 'email':
                        case 'hidden':
                        case 'password':
                        case 'button':
                        case 'reset':
                        case 'submit':
                            q.push(form.elements[i].name + "=" + encodeURIComponent(form.elements[i].value));
                            break;
                        case 'checkbox':
                        case 'radio':
                            if (form.elements[i].checked) {
                                    q.push(form.elements[i].name + "=" + encodeURIComponent(form.elements[i].value));
                            }                                               
                            break;
                    }
                    break;
                    case 'file':
                    break; 
                case 'TEXTAREA':
                        q.push(form.elements[i].name + "=" + encodeURIComponent(form.elements[i].value));
                        break;
                case 'SELECT':
                    switch (form.elements[i].type) {
                        case 'select-one':
                            q.push(form.elements[i].name + "=" + encodeURIComponent(form.elements[i].value));
                            break;
                        case 'select-multiple':
                            for (j = form.elements[i].options.length - 1; j >= 0; j = j - 1) {
                                if (form.elements[i].options[j].selected) {
                                        q.push(form.elements[i].name + "=" + encodeURIComponent(form.elements[i].options[j].value));
                                }
                            }
                            break;
                    }
                    break;
                case 'BUTTON':
                    switch (form.elements[i].type) {
                        case 'reset':
                        case 'submit':
                        case 'button':
                            q.push(form.elements[i].name + "=" + encodeURIComponent(form.elements[i].value));
                            break;
                    }
                    break;
                }
            }
        return q.join("&");
    }
    

    Source: http://code.google.com/p/form-serialize/source/browse/trunk/serialize-0.1.js

    0 讨论(0)
  • 2020-11-22 16:50

    I started with the answer from Johndave Decano.

    This should fix a few of the issues mentioned in replies to his function.

    1. Replace %20 with a + symbol.
    2. Submit/Button types will only be submitted if they were clicked to submit the form.
    3. Reset buttons will be ignored.
    4. The code seemed redundant to me since it is doing essentially the same thing regardless of the field types. Not to mention incompatibility with HTML5 field types such as 'tel' and 'email', thus I removed most of the specifics with the switch statements.

    Button types will still be ignored if they don't have a name value.

    function serialize(form, evt){
        var evt    = evt || window.event;
        evt.target = evt.target || evt.srcElement || null;
        var field, query='';
        if(typeof form == 'object' && form.nodeName == "FORM"){
            for(i=form.elements.length-1; i>=0; i--){
                field = form.elements[i];
                if(field.name && field.type != 'file' && field.type != 'reset'){
                    if(field.type == 'select-multiple'){
                        for(j=form.elements[i].options.length-1; j>=0; j--){
                            if(field.options[j].selected){
                                query += '&' + field.name + "=" + encodeURIComponent(field.options[j].value).replace(/%20/g,'+');
                            }
                        }
                    }
                    else{
                        if((field.type != 'submit' && field.type != 'button') || evt.target == field){
                            if((field.type != 'checkbox' && field.type != 'radio') || field.checked){
                                query += '&' + field.name + "=" + encodeURIComponent(field.value).replace(/%20/g,'+');
                            }   
                        }
                    }
                }
            }
        }
        return query.substr(1);
    }
    

    This is how I am currently using this function.

    <form onsubmit="myAjax('http://example.com/services/email.php', 'POST', serialize(this, event))">
    
    0 讨论(0)
  • 2020-11-22 16:51
    HTMLElement.prototype.serialize = function(){
        var obj = {};
        var elements = this.querySelectorAll( "input, select, textarea" );
        for( var i = 0; i < elements.length; ++i ) {
            var element = elements[i];
            var name = element.name;
            var value = element.value;
    
            if( name ) {
                obj[ name ] = value;
            }
        }
        return JSON.stringify( obj );
    }
    

    To use like this:

    var dataToSend = document.querySelector("form").serialize();
    

    I hope I have helped.

    0 讨论(0)
  • 2020-11-22 16:52

    The miniature from-serialize library doesn't rely on a framework. Other than something like that, you'll need to implement the serialization function yourself. (though at a weight of 1.2 kilobytes, why not use it?)

    0 讨论(0)
  • 2020-11-22 16:55

    For modern browsers only

    If you target browsers that support the URLSearchParams API (most recent browsers) and FormData(formElement) constructor (most recent browsers), use this:

    new URLSearchParams(new FormData(formElement)).toString()
    

    Everywhere except IE

    For browsers that support URLSearchParams but not the FormData(formElement) constructor, use this FormData polyfill and this code (works everywhere except IE):

    new URLSearchParams(Array.from(new FormData(formElement))).toString()
    

    Example

    var form = document.querySelector('form');
    var out = document.querySelector('output');
    
    function updateResult() {
      try {
        out.textContent = new URLSearchParams(Array.from(new FormData(form)));
        out.className = '';
      } catch (e) {
        out.textContent = e;
        out.className = 'error';
      }
    }
    
    updateResult();
    form.addEventListener('input', updateResult);
    body { font-family: Arial, sans-serif; display: flex; flex-wrap: wrap; }
    input[type="text"] { margin-left: 6px; max-width: 30px; }
    label + label { margin-left: 10px; }
    output { font-family: monospace; }
    .error { color: #c00; }
    div { margin-right: 30px; }
    <!-- FormData polyfill for older browsers -->
    <script src="https://unpkg.com/formdata-polyfill@3.0.17/formdata.min.js"></script>
    <div>
      <h3>Form</h3>
      <form id="form">
        <label>x:<input type="text" name="x" value="1"></label>
        <label>y:<input type="text" name="y" value="2"></label>
        <label>
        z:
        <select name="z">
          <option value="a" selected>a</option>
          <option value="b" selected>b</option>
        </select>
      </label>
      </form>
    </div>
    <div>
      <h3>Query string</h3>
      <output for="form"></output>
    </div>

    Compatible with IE 10

    For even older browsers (e.g. IE 10), use the FormData polyfill, an Array.from polyfill if necessary and this code:

    Array.from(
      new FormData(formElement),
      e => e.map(encodeURIComponent).join('=')
    ).join('&')
    
    0 讨论(0)
提交回复
热议问题