modulo serializzare javascript (nessun framework)


141

Mi chiedo c'è una funzione in javascript senza jquery o qualsiasi framework che mi permetta di serializzare il modulo e accedere alla versione serializzata?


1
Cosa intendi con "accedi alla versione serializzata"? Ho sviluppato uno script che non ha dipendenze di terze parti che possono convertire il modulo HTML in un oggetto simile a JSON che è multidimensionale: github.com/serbanghita/formToObject - se aiuta a rilasciare una risposta
Șerban Ghiță

Risposte:


39

La libreria miniaturizzata from-serialize non si basa su un framework. A parte qualcosa del genere, dovrai implementare tu stesso la funzione di serializzazione. (anche se con un peso di 1,2 kilobyte, perché non usarlo?)


2
Questo è stato perfetto Ma ho dovuto aggiungere un case 'email':nella sezione di input del codice
aravind

oh, ora vedo, googlecode non funziona senza javascript. That's an error
Sputa

3
Si prega di includere un po 'di codice e non solo un collegamento a una libreria. Se la libreria è open source, dovresti essere in grado di copiare il codice pertinente.
Luca

171

Ecco puro approccio JavaScript:

var form = document.querySelector('form');
var data = new FormData(form);
var req = new XMLHttpRequest();
req.send(data);

Anche se sembra funzionare solo per richieste POST.

https://developer.mozilla.org/en-US/docs/Web/API/FormData


13
Nota, questo invia multipart, che funziona male con alcuni semplici servizi REST (es. Feathers-mongoDB)
Jason McCarrell,

Penso che tu abbia ragione che funziona solo con richieste POST. Ciò non è stato immediatamente chiaro dai documenti.
Manisha,

questo non funziona per me. Il modulo è profondamente nidificato. L'oggetto FormData è vuoto ...
chitzui

Nota, potrebbe essere necessario utilizzare req.open("POST", "<your-url>");prima req.send(data);In caso contrario ho avuto l'errore InvalidStateError: XMLHttpRequest state must be OPENED.su Firefox 66. Dovrebbe funzionare con altre richieste anche come PUT se si sostituisce POST con PUT.
Baptx,

1
Pensaci: come hai potuto inviare un oggetto FormData usando il metodo "GET"? Sì, FormData funziona solo con "POST".
Rex the Strange,

88

Solo per browser moderni

Se scegli come target i browser che supportano l' URLSearchParamsAPI ( i browser più recenti ) e il FormData(formElement)costruttore ( i browser più recenti tranne Edge ), usa questo:

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

Ovunque tranne IE

Per i browser che supportano URLSearchParamsma non il FormData(formElement)costruttore, utilizzare questo polyfill FormData e questo codice (funziona ovunque tranne IE):

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

Esempio

Compatibile con IE 10

Per i browser ancora più vecchi (ad es. IE 10), utilizzare il polyfill FormData , un Array.frompolyfill se necessario e questo codice:

Array.from(
  new FormData(formElement),
  e => e.map(encodeURIComponent).join('=')
).join('&')

È .toString()davvero necessario qui?
Ollie Williams,

1
Se vuoi una stringa e no URLSearchParams, allora sì. La conversione delle stringhe avviene anche implicitamente se si interpola o la si aggiunge a una stringa, nel qual caso la toStringchiamata esplicita non è necessaria.
glebm,

One-liner non ha funzionato per me su iOS Safari a partire da aprile 2018
jchook il

Che errore ricevi e quale versione di Safari è? Forse new FormData(formElement)non è ancora supportato lì?
glebm,

@glebm sì, non è supportato in Safari, hai trovato qualche altra soluzione?
rishiAgar,

34
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("&");
}

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


1
Tale serializzazione non sembra essere compatibile con la serializzazione di moduli standard, in cui gli spazi sono rappresentati da "+". Quanto sopra utilizza solo encodeURIComponent , che codificherà lo spazio come "% 20". Se è richiesta la conformità, è possibile utilizzare un'espressione regolare alla fine per convertire "% 20" in "+" prima della trasmissione.
RobG,

3
Ho aggiunto una versione così modificata a gist.github.com/brettz9/7147458 (con alcuni altri miglioramenti)
Brett Zamir

3
I pulsanti di invio non devono essere necessariamente inviati, i pulsanti di ripristino non devono mai essere inviati e i pulsanti solo dove vengono utilizzati per l'invio e in questo caso vengono trattati come pulsanti di invio. Vedi HTML5 4.10.22 Invio modulo .
RobG

non serializzare il tipo di email di input.
Ivan

25

Ecco una versione leggermente modificata di TibTibs:

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

I campi disabilitati vengono eliminati e anche i nomi sono codificati nell'URL. La sostituzione Regex di% 20 caratteri viene eseguita una sola volta, prima di restituire la stringa.

La stringa di query ha la stessa forma del risultato del metodo $ .serialize () di jQuery.


6
+1 per il tempo dedicato a migliorare il codice. Mi piace quando le persone trovano i miei difetti, poiché è una buona opportunità di apprendimento. +1 per mantenerlo bello. -1 perché non posso dare +2 = (
TibTibs

1
potresti aggiungere form.nodeName.toLowerCase() == "form"inveceform.nodeName == "FORM"
StefanNch il

12

Ho iniziato con la risposta di Johndave Decano.

Ciò dovrebbe risolvere alcuni dei problemi menzionati nelle risposte alla sua funzione.

  1. Sostituisci% 20 con un simbolo +.
  2. I tipi di pulsante / invio verranno inviati solo se si fa clic per inviare il modulo.
  3. I pulsanti di ripristino verranno ignorati.
  4. Il codice mi è sembrato ridondante poiché sta essenzialmente facendo la stessa cosa indipendentemente dai tipi di campo. Per non parlare dell'incompatibilità con i tipi di campo HTML5 come 'tel' ed 'email', quindi ho rimosso la maggior parte delle specifiche con le istruzioni switch.

I tipi di pulsante verranno comunque ignorati se non hanno un valore per il nome.

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);
}

Ecco come sto attualmente usando questa funzione.

<form onsubmit="myAjax('http://example.com/services/email.php', 'POST', serialize(this, event))">

6
+1 per il codice ben refactored. -1 per ignorare i campi disabilitati, che non dovrebbero apparire nella stringa della query. +1 per la dichiarazione molto elegante per, che evita il conteggio ripetuto degli elementi del modulo. Totale: +1 :-) Grazie!
Simon Steinberger,

Una buona nota sui campi disabilitati, mi sono imbattuto recentemente in una nuova funzione che stavo scrivendo. +1 per entrambi, perché mi piace leggere commenti divertenti. :)
TibTibs,

11

Se devi inviare il modulo "myForm" usando POST in formato json puoi fare:

const formEntries = new FormData(myForm).entries();
const json = Object.assign(...Array.from(formEntries, ([x,y]) => ({[x]:y})));
fetch('/api/foo', {
  method: 'POST',
  body: JSON.stringify(json)
});

La seconda riga viene convertita da un array come:

[["firstProp", "firstValue"], ["secondProp", "secondValue"], ...and so on... ]

... in un oggetto normale, come:

{"firstProp": "firstValue", "secondProp": "secondValue", ...and so on ... }

... esegue questa conversione passando un mapFn in Array.from (). Questo mapFn viene applicato a ciascuna coppia ["a", "b"] e li converte in {"a": "b"} in modo che l'array contenga molti oggetti con una sola proprietà in ciascuno. MapFn sta usando "destructuring" per ottenere i nomi della prima e della seconda parte della coppia, e sta anche usando un "ComputedPropertyName" ES6 per impostare il nome della proprietà nell'oggetto restituito da mapFn (ecco perché dice "[ x]: qualcosa "piuttosto che solo" x: qualcosa ".

Tutti questi oggetti a proprietà singola vengono quindi passati agli argomenti della funzione Object.assign () che unisce tutti gli oggetti a proprietà singola in un singolo oggetto con tutte le proprietà.

Array.from (): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from

Ristrutturazione dei parametri: https://simonsmith.io/destructuring-objects-as-function-parameters-in-es6/

Altro sui nomi di proprietà calcolati qui: variabile come il nome della proprietà in un oggetto JavaScript letterale?


Funziona per me anche se non capisco la seconda riga, puoi darmi maggiori informazioni per favore ??
Espoir Murhabazi,

Bella risposta utilizzando l'operatore di diffusione e metodi nativi di oggetti e array.
Vinny Fonseca,

Nota che questo approccio non è supportato in IE (.entries ())
amico

La pagina MDN per Object.entries () ha un breve polyfill che puoi usare per IE: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… ma IE non supporta anche l'operatore spread.
Molsson,

puoi serializzare il modulo usando il nuovo metodo Object.fromEntries (new FormData (myFormElement)).
miguel savignano

10

Funziona in tutti i browser.

const formSerialize = formElement => {
  const values = {};
  const inputs = formElement.elements;

  for (let i = 0; i < inputs.length; i++) {
    values[inputs[i].name] = inputs[i].value;
  }
  return values;
}

const dumpValues = form => () => {
  
  const r = formSerialize(form);
  console.log(r);
  console.log(JSON.stringify(r));
}

const form = document.querySelector('form');

dumpValues(form)();

form.addEventListener('change',dumpValues(form));
<form action="/my-handling-form-page" method="post">
  <div>
    <label for="name">Name:</label>
    <input type="text" id="name" name="user_name" value="John">
  </div>
  <div>
    <label for="mail">E-mail:</label>
    <input type="email" id="mail" name="user_mail" value="john@jonhson.j">
  </div>
  <div>
    <label for="interests">Interest:</label>
    <select required=""  id="interests" name="interests">
      <option value="" selected="selected">- None -</option>
      <option value="drums">Drums</option>
      <option value="js">Javascript</option>
      <option value="sports">Sports</option>
      <option value="trekking">Trekking</option>
    </select>
  </div>
  <div>
    <label for="msg">Message:</label>
    <textarea id="msg" name="user_message">Hello My Friend</textarea>
  </div>
</form>


questo fa json, presumo che l'autore chiedesse di serializzare l'URI.
Jaskmar,

mi piacerebbe vederlo funzionare per più moduli di opzioni di selezione.
Zach Smith,

@ZachSmith Funzionava già, ma ho aggiunto un esempio per te per verificarlo
David Lemon,

8
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 );
}

Per usare così:

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

Spero di aver aiutato.


3
Non funziona con le caselle di controllo. Qui, è necessario verificare esplicitamente il tipo di input.
Adrian Preuss,

5

Se stai cercando di serializzare gli input su un evento. Ecco un puro approccio JavaScript che uso.

// serialize form
var data = {};
var inputs = [].slice.call(e.target.getElementsByTagName('input'));
inputs.forEach(input => {
  data[input.name] = input.value;
});

I dati saranno un oggetto JavaScript degli input.


2
Questo dovrebbe funzionare sulla maggior parte degli elementi. Sicuramente non textarea / select, però
jaggedsoft

che slice.call è uguale a Array.from?
user1040495,

5

Una versione refactored del codice @ SimonSteinberger usando meno variabili e sfruttando la velocità dei forEachloop (che sono un po 'più veloci di fors)

function serialize(form) {
    var result = [];
    if (typeof form === 'object' && form.nodeName === 'FORM')
        Array.prototype.slice.call(form.elements).forEach(function(control) {
            if (
                control.name && 
                !control.disabled && 
                ['file', 'reset', 'submit', 'button'].indexOf(control.type) === -1
            )
                if (control.type === 'select-multiple')
                    Array.prototype.slice.call(control.options).forEach(function(option) {
                        if (option.selected) 
                            result.push(encodeURIComponent(control.name) + '=' + encodeURIComponent(option.value));
                    });
                else if (
                    ['checkbox', 'radio'].indexOf(control.type) === -1 || 
                    control.checked
                ) result.push(encodeURIComponent(control.name) + '=' + encodeURIComponent(control.value));
        });
        return result.join('&').replace(/%20/g, '+');
}

3

Ho riformulato la risposta di TibTibs in qualcosa di molto più chiaro da leggere. È un po 'più lungo a causa della larghezza di 80 caratteri e di alcuni commenti.

Inoltre, ignora i nomi dei campi vuoti e i valori vuoti.

// Serialize the specified form into a query string.
//
// Returns a blank string if +form+ is not actually a form element.
function $serialize(form, evt) {
  if(typeof(form) !== 'object' && form.nodeName !== "FORM")
    return '';

  var evt    = evt || window.event || { target: null };
  evt.target = evt.target || evt.srcElement || null;
  var field, query = '';

  // Transform a form field into a query-string-friendly
  // serialized form.
  //
  // [NOTE]: Replaces blank spaces from its standard '%20' representation
  //         into the non-standard (though widely used) '+'.
  var encode = function(field, name) {
    if (field.disabled) return '';

    return '&' + (name || field.name) + '=' +
           encodeURIComponent(field.value).replace(/%20/g,'+');
  }

  // Fields without names can't be serialized.
  var hasName = function(el) {
    return (el.name && el.name.length > 0)
  }

  // Ignore the usual suspects: file inputs, reset buttons,
  // buttons that did not submit the form and unchecked
  // radio buttons and checkboxes.
  var ignorableField = function(el, evt) {
    return ((el.type == 'file' || el.type == 'reset')
        || ((el.type == 'submit' || el.type == 'button') && evt.target != el)
        || ((el.type == 'checkbox' || el.type == 'radio') && !el.checked))
  }

  var parseMultiSelect = function(field) {
    var q = '';

    for (var j=field.options.length-1; j>=0; j--) {
      if (field.options[j].selected) {
        q += encode(field.options[j], field.name);
      }
    }

    return q;
  };

  for(i = form.elements.length - 1; i >= 0; i--) {
    field = form.elements[i];

    if (!hasName(field) || field.value == '' || ignorableField(field, evt))
      continue;

    query += (field.type == 'select-multiple') ? parseMultiSelect(field)
                                               : encode(field);
  }

  return (query.length == 0) ? '' : query.substr(1);
}

L'ho copiato direttamente nella mia app e la selezione multipla non sembra funzionare (i valori sono duplicati)
anastymous

@anastymous Grazie per la cattura, è stato corretto.
Brian Edmonds

Ciao Brian, ciò che è EVT per? e cosa dovrei passare per questo? Firefox mi sta dicendo che non è definito.
anastymous

Ciao anastymous, grazie ancora per la cattura, dovrebbe essere risolto cambiando il compito in evt evt = evt || window.event || { target: null };(come ha fatto la modifica) Il punto dietro è passare l'evento che ha innescato la serializzazione, se ce n'è uno, come un modulo evento "submit" o "clic" di un pulsante. Se un modulo ha più pulsanti per l'invio, si desidera solo tenere conto del valore del pulsante che ha attivato l'evento e ignorare gli altri. Ho messo insieme un esempio molto rudimentale di questo comportamento su dump.bedmonds.net/serialize-js
Brian Edmonds

2
  // supports IE8 and IE9 
  function serialize(form) {
    var inputs = form.elements;
    var array = [];
    for(i=0; i < inputs.length; i++) {
      var inputNameValue = inputs[i].name + '=' + inputs[i].value;
      array.push(inputNameValue);
    }
    return array.join('&');
  }
 //using the serialize function written above
 var form = document.getElementById("form");//get the id of your form. i am assuming the id to be named form.
 var form_data = serialize(form);
 var xhr = new XMLHttpRequest();
 xhr.send(form_data);

 //does not work with IE8 AND IE9
 var form = document.querySelector('form');
 var data = new FormData(form);
 var xhr = new XMLHttpRequest();
 xhr.send(data);

2

Ho preso il metodo entry () di formData dalla risposta di @moison e da MDN si dice che:

Il metodo FormData.entries () restituisce un iteratore che consente di esaminare tutte le coppie chiave / valore contenute in questo oggetto. La chiave di ogni coppia è un oggetto USVString; il valore o USVString o BLOB.

ma l'unico problema è che il browser mobile (Android e Safari non sono supportati) e anche IE e Safari desktop

ma sostanzialmente ecco il mio approccio:

let theForm =  document.getElementById("contact"); 

theForm.onsubmit = function(event) {
    event.preventDefault();

    let rawData = new FormData(theForm);
    let data = {};

   for(let pair of rawData.entries()) {
     data[pair[0]] = pair[1]; 
    }
    let contactData = JSON.stringify(data);
    console.warn(contactData);
    //here you can send a post request with content-type :'application.json'

};

il codice può essere trovato qui


2

L'uso della funzione di riduzione JavaScript dovrebbe fare un trucco per tutti i browser, incluso IE9>:

Array.prototype.slice.call(form.elements) // convert form elements to array
    .reduce(function(acc,cur){   // reduce 
        var o = {type : cur.type, name : cur.name, value : cur.value}; // get needed keys
        if(['checkbox','radio'].indexOf(cur.type) !==-1){
            o.checked = cur.checked;
        } else if(cur.type === 'select-multiple'){
            o.value=[];
            for(i=0;i<cur.length;i++){
                o.value.push({
                    value : cur.options[i].value,
                    selected : cur.options[i].selected
                });
            }
        }
        acc.push(o);
        return acc;
 },[]);

Muggito esempio dal vivo.


funziona per la selezione multipla? sembra che quando uso il tuo codice restituisca solo il primo elemento del valore delle opzioni multiple selezionate
Zach Smith,

@ZachSmith Ho aggiornato la mia risposta per includere più elementi di selezione.
crashtestxxx,

0

Spero che funzioni

var serializeForm = (formElement) => {
  const formData = {};
  const inputs = formElement.elements;

  for (let i = 0; i < inputs.length; i++) {
    if(inputs[i].name!=="")
        formData[inputs[i].name] = inputs[i].value;
  }
  return formData;
}

0

Migliorare la risposta di David Lemon.

Ciò converte i dati del modulo in JSON e consente di impostare il modulo da un oggetto dati.

const main = () => {
  const form = document.forms['info'];
  const data = {
    "user_name"       : "John",
    "user_email"      : "john@jonhson.com",
    "user_created"    : "2020-03-24",
    "user_age"        : 42,
    "user_subscribed" : true,
    "user_interests"  : "sports",
    "user_message"    : "Hello My Friend"
  };

  populateForm(form, data);
  updateJsonView(form);
  form.addEventListener('change', (e) => updateJsonView(form));
}

const getFieldValue = (field, opts) => {
  let type = field.getAttribute('type');
  if (type) {
    switch (type) {
      case 'checkbox':
        return field.checked;
      case 'number':
        return field.value.includes('.')
          ? parseFloat(field.value)
          : parseInt(field.value, 10);
    }
  }
  if (opts && opts[field.name] && opts[field.name].type) {
    switch (opts[field.name].type) {
      case 'int':
        return parseInt(field.value, 10);
      case 'float':
        return parseFloat(field.value);
    }
  }
  return field.value;
}

const setFieldValue = (field, value) => {
  let type = field.getAttribute('type');
  if (type) {
    switch (type) {
      case 'checkbox':
        field.checked = value;
        break;
      default:
        field.value = value;
        break;
    }
  } else {
    field.value = value;
  }
}

const extractFormData = (form, opts) => {
  return Array.from(form.elements).reduce((data, element) => {
    return Object.assign(data, { [element.name] : getFieldValue(element, opts) });
  }, {});
};

const populateForm = (form, data) => {
  return Array.from(form.elements).forEach((element) => {
    setFieldValue(element, data[element.name]);
  });
};

const updateJsonView = (form) => {
  let fieldOptions = {};
  let formData = extractFormData(form, fieldOptions);
  let serializedData = JSON.stringify(formData, null, 2);
  document.querySelector('.json-view').textContent = serializedData;
};

main();
.form-field {
  margin-bottom: 0.5em;
}

.form-field label {
  display: inline-block;
  font-weight: bold;
  width: 7em;
  vertical-align: top;
}

.json-view {
  position: absolute;
  top: 0.667em;
  right: 0.667em;
  border: thin solid grey;
  padding: 0.5em;
  white-space: pre;
  font-family: monospace;
  overflow: scroll-y;
  max-height: 100%;
}
<form name="info" action="/my-handling-form-page" method="post">
  <div class="form-field">
    <label for="name">Name:</label>
    <input type="text" id="name" name="user_name">
  </div>
  <div class="form-field">
    <label for="mail">E-mail:</label>
    <input type="email" id="mail" name="user_email">
  </div>
  <div class="form-field">
    <label for="created">Date of Birth:</label>
    <input type="date" id="created" name="user_created">
  </div>
  <div class="form-field">
    <label for="age">Age:</label>
    <input type="number" id="age" name="user_age">
  </div>
  <div class="form-field">
    <label for="subscribe">Subscribe:</label>
    <input type="checkbox" id="subscribe" name="user_subscribed">
  </div>
  <div class="form-field">
    <label for="interests">Interest:</label>
    <select required=""  id="interests" name="user_interests">
      <option value="" selected="selected">- None -</option>
      <option value="drums">Drums</option>
      <option value="js">Javascript</option>
      <option value="sports">Sports</option>
      <option value="trekking">Trekking</option>
    </select>
  </div>
  <div class="form-field">
    <label for="msg">Message:</label>
    <textarea id="msg" name="user_message"></textarea>
  </div>
</form>
<div class="json-view"></div>


0

Questo potrebbe essere fatto con una funzione molto semplice come segue

function serialize(form) {
        let requestArray = [];
        form.querySelectorAll('[name]').forEach((elem) => {
            requestArray.push(elem.name + '=' + elem.value);
        });
        if(requestArray.length > 0)
            return requestArray.join('&');
        else
            return false;
    }

 serialized = serialize(document.querySelector('form'))
  console.log(serialized);
<form>

  <input type='text' name='fname' value='Johne'/>
  <input type='text' name='lname' value='Doe'/>
  <input type='text' name='contact[]' value='99999999'/>
  <input type='text' name='contact[]' value='34423434345'/>

</form>


0

Ecco puro approccio JavaScript:

var form = document.querySelector('form');
var data = new FormData(form);

  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
       console.log(this.responseText);
    }
  };
  xhttp.open("POST", "<YOUR-URL>", true);
  xhttp.send(data);
}

-1
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;
}

Sembra pulito, ma non tiene conto dei pulsanti di opzione o delle caselle di controllo
Yvonne Aburrow

-1

Ai fini del debug questo potrebbe aiutarti:

function print_form_data(form) {
    const form_data = new FormData(form);

    for (const item of form_data.entries()) {
        console.log(item);
    }

    return false;
}

-1

Potrei essere pazzo ma sto trovando queste risposte seriamente gonfie. Ecco la mia soluzione

function serialiseForm(form) {
  var input = form.getElementsByTagName("input");
  var formData = {};
  for (var i = 0; i < input.length; i++) {
    formData[input[i].name] = input[i].value;
  }
  return formData = JSON.stringify(formData);
}

basare il modulo per recuperare elementi in base al tipo di input non funzionerà select, eccetera
Zach Smith
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.