Como posso obter dados do formulário com JavaScript / jQuery?

404

Existe uma maneira simples, de uma linha, de obter os dados de um formulário como seria se fosse submetido da maneira clássica somente em HTML?

Por exemplo:

<form>
    <input type="radio" name="foo" value="1" checked="checked" />
    <input type="radio" name="foo" value="0" />
    <input name="bar" value="xxx" />
    <select name="this">
        <option value="hi" selected="selected">Hi</option>
        <option value="ho">Ho</option>
</form>

Resultado:

{
    "foo": "1",
    "bar": "xxx",
    "this": "hi"
}

Algo assim é muito simples, pois não inclui (corretamente) áreas de texto, seleções, botões de opção e caixas de seleção:

$("#form input").each(function () {
    data[theFieldName] = theFieldValue;
});
Bart van Heukelom
fonte
3
Outra pergunta semelhante a este: stackoverflow.com/questions/169506/...
Marcelo Rodovalho

Respostas:

431
$('form').serialize() //this produces: "foo=1&bar=xxx&this=hi"

demonstração

chelmertz
fonte
15
Feche, mas talvez algo que retorne uma matriz com pares de valores-chave em vez de uma única string?
Bart van Heukelom
80
Nvm, encontrei nos comentários para a função serialize (). É chamado serializeArray. Ele retorna uma matriz de matrizes (que contêm uma entrada "nome" e "valor"), mas isso deve ser fácil o suficiente para transformar.
Bart van Heukelom
22
E o uso da biblioteca de sublinhado pode ser transformado usando:_.object($("#myform").serializeArray().map(function(v) {return [v.name, v.value];} ))
MhdSyrwan
8
@BartvanHeukelom Eu sei que isso é 4 anos depois, mas .serializeArray () retornará uma matriz.
TJ WealthEngine API Evangelist
6
Certifique-se de que cada tag de entrada inclua o atributo name, caso contrário não retornará nada.
Eugene Kulabuhov
505

Use $('form').serializeArray(), que retorna uma matriz :

[
  {"name":"foo","value":"1"},
  {"name":"bar","value":"xxx"},
  {"name":"this","value":"hi"}
]

Outra opção é $('form').serialize(), que retorna uma string :

"foo=1&bar=xxx&this=hi"

Dê uma olhada nesta demonstração do jsfiddle

Paulo
fonte
91
serializeArrayseria muito mais útil se voltou um objeto com pares chave-valor
GetFree
8
Concordo que um objeto seria o ideal. No entanto, há um problema - uma chave pode ter vários valores. Você retornaria um objeto chave - "matriz de valores", ou chave - "primeiro valor" ou algo mais? Eu acho que jQuery caras nenhum dos :) acima escolheu
Paul
Esteja ciente de um problema com vários valores (como @Paul mencionado acima), caixas de seleção e várias entradas com name="multiple[]"não funcionam. A solução para o método POST é a mesma, basta usar $ ('form'). Serialize (). Além disso, o método POST não possui limite de 2000 caracteres, como o GET na maioria dos navegadores, portanto, pode ser usado mesmo para dados muito grandes.
Artru 17/09/16
Lembre-se também de que, para registrar um valor de qualquer entrada de formulário, a entrada deve ter um nameatributo.
Chris - Jr
@ GetFree, por que não usar apenas a função de mapa do jQuery? função getFormData (formulário) {var rawJson = form.serializeArray (); modelo var = {}; $ .map (rawJson, função (n, i) {model [n ['nome']] = n ['valor'];}); modelo de retorno; }
Tom McDonough
196

Resposta atualizada para 2014: o HTML5 FormData faz isso

var formData = new FormData(document.querySelector('form'))

Você pode postar formData exatamente como está - ele contém todos os nomes e valores usados ​​no formulário.

mikemaccana
fonte
13
Além disso, um como FormData é bom e útil, mas vale a pena notar que, se você quiser ler os dados no FormData, não é tão fácil (consulte stackoverflow.com/questions/7752188/… )
StackExchange What The Heck
11
Tenha em mente FormData faz parte dos XMLHttpRequest recursos avançados (anteriormente conhecido como XMLHttpRequest Nível 2) para que você deve confiar em um polyfill para o Internet Explorer <10. caniuse.com/#feat=xhr2
Pier-Luc Gendreau
3
@yochannah, não é assim. Claro, não se pode simplesmente acessar e editar os dados como um objeto normal, mas ainda é trivial obter os dados. Confira o entries()método [página MDN ].
Web and Flow
@Web e Flow, obrigado por apontar isso! Adoro quando os navegadores adicionam recursos novos e úteis :) vezes, eles estão mudando.
StackExchange What The Heck
Estou tentando usar o FormData para enviar um objeto ao meu script Flask-python, mas ele não parece ser um objeto de solicitação normal que posso descompactar. Alguém pode apontar para uma explicação de quaisquer etapas especiais para lidar com isso no lado do servidor? É onde parece vazio para mim.
Manisha
181

Com base em jQuery.serializeArray, retorna pares de valores-chave.

var data = $('#form').serializeArray().reduce(function(obj, item) {
    obj[item.name] = item.value;
    return obj;
}, {});
Neuront
fonte
12
Pares de valor-chave aqui, pessoal, todo mundo, venha aqui! É dourado !!! Obrigado! Se eu quiser o valor de um elemento chamado "varejista", faço isso console.log ($ ('# form'). SerializeArray (). Reduza (função (obj, item) {obj [item.name] = item. value; return obj;}, {}) ['varejista']);
Yevgeniy Afanasyev
Ontem criei um método JQuery com base nessa resposta, mas trabalhando com multiselecionas e matrizes de entrada (com o nome 'exemplo []'). Você pode encontrá-lo na minha resposta abaixo. Enfim, boa abordagem neuront, obrigado! :)
manuman94
Este me serviu mais, de todas as respostas!
VPetrovic 15/05/19
Este IMHO é a melhor resposta!
Rahul
74
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
});

Esta é uma resposta detalhada, mas deixe-me explicar por que essa é uma solução melhor:

  • Estamos lidando adequadamente com o envio de um formulário, em vez de pressionar o botão. Algumas pessoas gostam de pressionar enter nos campos. Algumas pessoas usam dispositivos de entrada alternativos, como entrada de fala ou outros dispositivos de acessibilidade. Manipule o envio do formulário e o resolva corretamente para todos.

  • Estamos investigando os dados do formulário real enviado. Se você alterar o seletor de formulário posteriormente, não precisará alterar os seletores para todos os campos. Além disso, você pode ter vários formulários com os mesmos nomes de entrada. Não há necessidade de desambiguar com IDs excessivos e, caso contrário, basta rastrear as entradas com base no formulário que foi enviado. Isso também permite que você use um único manipulador de eventos para vários formulários, se for apropriado para sua situação.

  • A interface FormData é relativamente nova, mas é bem suportada pelos navegadores. É uma ótima maneira de criar essa coleta de dados para obter os valores reais do que está no formulário. Sem ele, você terá que percorrer todos os elementos (como com form.elements) e descobrir o que está marcado, o que não está, quais são os valores, etc. Totalmente possível se você precisar de suporte antigo ao navegador, mas o FormData interface é mais simples.

  • Estou usando o ES6 aqui ... não é um requisito de forma alguma, portanto, altere-o novamente para ser compatível com o ES5 se você precisar de suporte antigo do navegador.

Brad
fonte
fyi, os objetos FormData não expõem seus valores. Para obter um objeto simples a partir dele, consulte stackoverflow.com/questions/41431322/…
phil294
2
@Blauhirn Bobagem, é claro que eles expõem os valores. O código na minha resposta funciona. Você deveria tentar. Aqui, criei um violino para você: jsfiddle.net/zv9s1xq5 Se você deseja um iterador, use formData.entries().
Brad Brad
Eu sei que funciona, mas as propriedades não são acessíveis por chave. Por exemplo, formData.foo é indefinido. Como visto na sua resposta, .get() precisa ser chamado para aquilo que considero inconveniente. Talvez "não exponha" veio do outro lado. Portanto, para gerar algo parecido { foo: 'bar' }com um submitevento, você precisa iterá-lo manualmente. Daí o . To get a plain object from it, see [link].
phil294
11
@Blauhirn Você está errado sobre isso. XMLHttpRequest suporta FormData diretamente. xhr.send(formData);
Brad Brad
11
@Blauhirn JSON.stringify([...formData]) Ou, se você quer suas chaves / valores separar ... [...formData].reduce((prev, cur) => { prev[cur[0]] = cur[1]; return prev;}, {})
Brad
25

use .serializeArray () para obter os dados no formato de matriz e depois convertê-los em um objeto:

function getFormObj(formId) {
    var formObj = {};
    var inputs = $('#'+formId).serializeArray();
    $.each(inputs, function (i, input) {
        formObj[input.name] = input.value;
    });
    return formObj;
}
Nils
fonte
Isso substitui minhas caixas de seleção se eu tiver algo parecido <input type="checkbox" name="someList" value="one" /> <input type="checkbox" name="someList" value="two" />. Se ambos estiverem marcados, o objeto conterá apenas o segundo valor da caixa de seleção.
dmathisen
2
Não é este o caso onde someListdeveria estar type="radio"?
precisa saber é o seguinte
upvote porque a resposta aceita não retorna um objeto com as chaves como:name:value
Matt-the-marxista
24

Aqui está um solução realmente simples e curta que nem sequer requer 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;
Clox
fonte
11
Isso não funciona com os botões de opção: a última opção é sempre aquela armazenada postData.
Kyle Falconer
3
Obrigado por nos dar uma resposta não-jquery.
Glen Pierce
24

É 2019 e há uma maneira melhor de fazer isso:

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

ou se você quiser um objeto simples

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

embora observe que isso não funcionará com chaves duplicadas, como você obtém nas caixas de seleção com várias seleções e duplicadas com o mesmo nome.

fringd
fonte
Totalmente. Embora, eu não obter uma matriz para uma lista de entradas que todos têm o mesmo nome que significava que eu tinha que usar document.getElementsByClassNamee um loop for, mas hey, ainda mais agradável do que exigindo jQuery etc
alphanumeric0101
11
Esta resposta é a minha favorita. Mas deve ler em document.querySelectorvez de apenas querySelector.
adabru
Observação "FormData usará apenas campos de entrada que usam o atributo name" - do MDN
binaryfunt
16
$('#myform').serialize();
Andy Baird
fonte
13

Eu uso isso:

Plugin jQuery

(function($){
  $.fn.getFormData = function(){
    var data = {};
    var dataArray = $(this).serializeArray();
    for(var i=0;i<dataArray.length;i++){
      data[dataArray[i].name] = dataArray[i].value;
    }
    return data;
  }
})(jQuery);

Formulário HTML

<form id='myform'>
  <input name='myVar1' />
  <input name='myVar2' />
</form>

Obtenha os dados

var myData = $("#myForm").getFormData();
Dustin Poissant
fonte
Observe que esse plug-in não funciona nos casos em que várias entradas de entrada de formulário com o mesmo nome estão presentes. A última entrada iria substituir o anterior enquanto que o comportamento esperado seria para obter todos os valores como umArray
Milli
11
Apenas uma observação de que, um ano depois, agora acho que essa é uma resposta terrível e ninguém deve usá-la. Como o comentário anterior diz, coisas como botões de opção não funcionariam. Há respostas melhores acima, use uma delas.
Dustin Poissant 26/09
12
$("#form input, #form select, #form textarea").each(function() {
 data[theFieldName] = theFieldValue;
});

além disso, você pode querer olhar para serialize () ;

pixeline
fonte
11

Aqui está uma implementação de JavaScript que funciona corretamente e que lida corretamente com caixas de seleção, botões de opção e controles deslizantes (provavelmente outros tipos de entrada também, mas eu os testei apenas).

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

Exemplo de trabalho:

    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>

editar:

Se você está procurando uma implementação mais completa, dê uma olhada nesta seção do projeto para a qual eu fiz isso . Eventualmente, atualizarei esta pergunta com a solução completa que me foi apresentada, mas talvez isso seja útil para alguém.

Kyle Falconer
fonte
11
Solução agradável :) No entanto, encontrei um bug com a função setOrPush. Ele não inclui uma verificação para ver se o destino já é uma matriz, causando a criação de uma matriz aninhada profunda no caso de várias caixas de seleção marcadas com o mesmo nome.
Wouter van Dam
@KyleFalconer Nice! Por que você não mesclou os casos de opção para rádio e caixa de seleção - eles funcionarão corretamente (eu acho).
Ethan
@ Ethan É porque uma caixa de seleção pode ter vários valores selecionados e um rádio pode ter apenas um valor selecionado, então a maneira como armazeno o valor muda.
Kyle Falconer
@KyleFalconer Sim, eu entendo isso. O código para manipular 'checkbox' também cuida da única opção possível para 'radio', em virtude da rotina 'SetOrPush'.
Ethan
@ Ethan Oh, eu acho que sei o que você está dizendo. Poderia ser feito de qualquer maneira, mas acho que fiz dessa maneira só porque queria apenas um valor, não uma matriz de valores.
Kyle Falconer
9

Se você estiver usando jQuery, aqui está uma pequena função que fará o que você está procurando.

Primeiro, adicione um ID ao seu formulário (a menos que seja o único formulário na página, você poderá usar apenas 'form' como a consulta dom)

<form id="some-form">
 <input type="radio" name="foo" value="1" checked="checked" />
 <input type="radio" name="foo" value="0" />
 <input name="bar" value="xxx" />
 <select name="this">
  <option value="hi" selected="selected">Hi</option>
  <option value="ho">Ho</option>
</form>

<script>
//read in a form's data and convert it to a key:value object
function getFormData(dom_query){
    var out = {};
    var s_data = $(dom_query).serializeArray();
    //transform into simple data/value object
    for(var i = 0; i<s_data.length; i++){
        var record = s_data[i];
        out[record.name] = record.value;
    }
    return out;
}

console.log(getFormData('#some-form'));
</script>

A saída seria semelhante a:

{
 "foo": "1",
 "bar": "xxx",
 "this": "hi"
}
RobKohr
fonte
7

Você também pode usar os objetos FormData ; O objeto FormData permite compilar um conjunto de pares de chave / valor para enviar usando XMLHttpRequest. Destina-se principalmente ao uso no envio de dados de formulários, mas pode ser usado independentemente dos formulários para transmitir dados codificados.

        var formElement = document.getElementById("myform_id");
        var formData = new FormData(formElement);
        console.log(formData);
numediaweb
fonte
Obrigado, mas e se você não tiver um ID? E se você tiver um formulário como objeto JQuery? var form = $ (this) .closest ('form'); ? Deve var formElement = document.getElementById (form [0]); trabalhar em vez de sua linha de abetos? Infelizmente, não está funcionando, infelizmente. Você sabe por quê?
Yevgeniy Afanasyev
Na verdade, o FormData não é suportado por todos os navegadores :( então é melhor usar uma abordagem diferente
numediaweb
Obrigado. Eu usei o Chrome mais recente e ainda não estava funcionando. Então eu fui com a resposta #neuront lá de cima.
Yevgeniy Afanasyev
6

Isso anexará todos os campos do formulário ao objeto JavaScript "res":

var res = {};
$("#form input, #form select, #form textarea").each(function(i, obj) {
    res[obj.name] = $(obj).val();
})
gamliela
fonte
Provavelmente porque essa mesma resposta exata já foi publicada em 2010. #
nathanvda
Eu não sabia disso. Para uma resposta tão curta, isso não é surpreendente. E mesmo assim, onde está a referência?
gamliela
A sério? Você não acredita no meu comentário sem a referência e não pode nem olhar a lista de respostas para ver se são iguais? stackoverflow.com/a/2276469/216513
nathanvda
Eu pensei que você quis dizer uma resposta em outra pergunta. Não me lembro agora dos detalhes e das minhas razões; talvez porque não é exatamente o mesmo
gamliela
11
Resposta perfeita para alguém que deseja que ele trabalhe para entrada, selecione múltiplas e área de texto. Porque, usando serialize, você não obterá todos os itens selecionados na tag select. Mas, usando .val (), você obterá exatamente o que deseja como uma matriz. Resposta simples e direta.
Sailesh Kotha
6

Incluí a resposta para também devolver o objeto necessário.

function getFormData(form) {
var rawJson = form.serializeArray();
var model = {};

$.map(rawJson, function (n, i) {
    model[n['name']] = n['value'];
});

return model;
}
Tom McDonough
fonte
Isso não vai lidar com matrizes; foo[bar][] = 'qux'deve serializar para { foo: { bar: [ 'qux' ] } }.
Amphetamachine
6

Com base na resposta da neuront, criei um método JQuery simples que obtém os dados do formulário em pares de chave-valor, mas funciona para seleções múltiplas e entradas de matriz com nome = 'exemplo []'.

É assim que é usado:

var form_data = $("#form").getFormObject();

Você pode encontrar um exemplo abaixo de sua definição e como ele funciona.

// Function start
$.fn.getFormObject = function() {
    var object = $(this).serializeArray().reduce(function(obj, item) {
        var name = item.name.replace("[]", "");
        if ( typeof obj[name] !== "undefined" ) {
            if ( !Array.isArray(obj[name]) ) {
                obj[name] = [ obj[name], item.value ];
            } else {
               obj[name].push(item.value);
            }
        } else {
            obj[name] = item.value;
        }
        return obj;
    }, {});
    return object;
}
// Function ends

// This is how it's used
$("#getObject").click( function() {
  var form_data = $("#form").getFormObject();
  console.log(form_data);
});
/* Only to make view better ;) */
#getObject {
  padding: 10px;
  cursor:pointer;
  background:#0098EE;
  color:white;
  display:inline-block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<form id="form">
  <input type="text" name="text" value="Hola amigo" /> 
  
  <input type="text" name="text_array[]" value="Array 1" /> 
  <input type="text" name="text_array[]" value="Array 2" /> 
  <input type="text" name="text_array[]" value="Array 3" /> 
  
  <select name="multiselect" multiple>
    <option name="option1" selected> option 1 </option>
    <option name="option2" selected> option 2 </option>
  </select>
  
  <input type="checkbox" name="checkbox" value="checkbox1" checked/>
  <input type="checkbox" name="checkbox" value="checkbox2" checked/>
  
  <input type="radio" name="radio" value="radio1" checked/>
  <input type="radio" name="radio" value="radio2"/>

</form>

<div id="getObject"> Get object (check the console!) </div>

manuman94
fonte
5
var formData = new FormData($('#form-id'));
params   = $('#form-id').serializeArray();

$.each(params, function(i, val) {
    formData.append(val.name, val.value);
});
George John
fonte
4
function getFormData($form){
    var unindexed_array = $form.serializeArray();
    var indexed_array = {};

    $.map(unindexed_array, function(n, i){
        if(indexed_array[n['name']] == undefined){
            indexed_array[n['name']] = [n['value']];
        }else{
            indexed_array[n['name']].push(n['value']);
        }
    });

    return indexed_array;
}
郭润民
fonte
4

você pode usar esta função para ter um objeto ou um JSON do formulário.

para usá-lo:

var object = formService.getObjectFormFields("#idform");

 function  getObjectFormFields(formSelector)
        {
            /// <summary>Função que retorna objeto com base nas propriedades name dos elementos do formulário.</summary>
            /// <param name="formSelector" type="String">Seletor do formulário</param>

            var form = $(formSelector);

            var result = {};
            var arrayAuxiliar = [];
            form.find(":input:text").each(function (index, element)
            {
                var name = $(element).attr('name');

                var value = $(element).val();
                result[name] = value;
            });

            form.find(":input[type=hidden]").each(function (index, element)
            {
                var name = $(element).attr('name');
                var value = $(element).val();
                result[name] = value;
            });


            form.find(":input:checked").each(function (index, element)
            {
                var name;
                var value;
                if ($(this).attr("type") == "radio")
                {
                    name = $(element).attr('name');
                    value = $(element).val();
                    result[name] = value;
                }
                else if ($(this).attr("type") == "checkbox")
                {
                    name = $(element).attr('name');
                    value = $(element).val();
                    if (result[name])
                    {
                        if (Array.isArray(result[name]))
                        {
                            result[name].push(value);
                        } else
                        {
                            var aux = result[name];
                            result[name] = [];
                            result[name].push(aux);
                            result[name].push(value);
                        }

                    } else
                    {
                        result[name] = [];
                        result[name].push(value);
                    }
                }

            });

            form.find("select option:selected").each(function (index, element)
            {
                var name = $(element).parent().attr('name');
                var value = $(element).val();
                result[name] = value;

            });

            arrayAuxiliar = [];
            form.find("checkbox:checked").each(function (index, element)
            {
                var name = $(element).attr('name');
                var value = $(element).val();
                result[name] = arrayAuxiliar.push(value);
            });

            form.find("textarea").each(function (index, element)
            {
                var name = $(element).attr('name');
                var value = $(element).val();
                result[name] = value;
            });

            return result;
        }

Marcos Costa
fonte
2
Embora esse link possa responder à pergunta, é melhor incluir aqui as partes essenciais da resposta e fornecer o link para referência. As respostas somente para links podem se tornar inválidas se a página vinculada for alterada. - Da avaliação
Wahyu Kristianto 07/07
Mas esse link tem uma função para ajudar a ele (eu acho). Mas vou colocar o código na próxima vez.
Marcos Costa
3

Eu escrevi uma biblioteca para resolver esse problema: JSONForms . Ele assume um formulário, passa por cada entrada e cria um objeto JSON que você pode ler facilmente.

Digamos que você tenha o seguinte formulário:

<form enctype='application/json'>
  <input name='places[0][city]' value='New York City'>
  <input type='number' name='places[0][population]' value='8175133'>
  <input name='places[1][city]' value='Los Angeles'>
  <input type='number' name='places[1][population]' value='3792621'>
  <input name='places[2][city]' value='Chicago'>
  <input type='number' name='places[2][population]' value='2695598'>
</form>

Passar o formulário para o método de codificação JSONForms retorna o seguinte objeto:

{
  "places": [
    {
      "city": "New York City",
      "population": 8175133
    },
    {
      "city": "Los Angeles",
      "population": 3792621
    },
    {
      "city": "Chicago",
      "population": 2695598
    }
  ]
}

Aqui está uma demonstração com seu formulário.

Cezary Wojtkowski
fonte
Parece e funciona bem, obrigado. Apenas uma coisa, a versão reduzida chama um arquivo de mapa, deve ser opcional.
precisa saber é
2

$( "form" ).bind( "submit", function(e) {
    e.preventDefault();
    
    console.log(  $(this).serializeObject() );    

    //console.log(  $(this).serialize() );
    //console.log(  $(this).serializeArray() );

});


$.fn.serializeObject = function() {
    var o = {};
    var a = this.serializeArray();

    $.each( a, function() {
        if ( o[this.name] !== undefined) 
        {
            if ( ! o[this.name].push ) 
            {
                o[this.name] = [o[this.name]];
            }
            o[this.name].push(this.value || '');
        }
        else 
        {
            o[this.name] = this.value || '';
        }
    });

    return o;
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>

<form>

    <input type="radio" name="foo" value="1" checked="checked" />
    <input type="radio" name="foo" value="0" />
    <input name="bar" value="xxx" />

    <select name="this">
        <option value="hi" selected="selected">Hi</option>
        <option value="ho">Ho</option>
    </select>

    <input type="submit" value="Submit" />

</form>

Codepen

antelove
fonte
2

Para aqueles de vocês que preferem uma Objectstring serializada, ao contrário de uma sequência serializada (como a retornada por $(form).serialize(), e uma ligeira melhoria $(form).serializeArray()), fique à vontade para usar o código abaixo:

var Form = {
    _form: null,
    _validate: function(){
        if(!this._form || this._form.tagName.toLowerCase() !== "form") return false;
        if(!this._form.elements.length) return false;
    }, _loopFields: function(callback){
        var elements = this._form.elements;
        for(var i = 0; i < elements.length; i++){
            var element = form.elements[i];
            if(name !== ""){
                callback(this._valueOfField(element));
            }
        }
    }, _valueOfField: function(element){
        var type = element.type;
        var name = element.name.trim();
        var nodeName = element.nodeName.toLowerCase();
        switch(nodeName){
            case "input":
                if(type === "radio" || type === "checkbox"){
                    if(element.checked){
                        return element.value;
                    }
                }
                return element.value;
                break;
            case "select":
                if(type === "select-multiple"){
                    for(var i = 0; i < element.options.length; i++){
                        if(options[i].selected){
                            return element.value;
                        }
                    }
                }
                return element.value;
                break;
            case "button":
                switch(type){
                    case "reset": 
                    case "submit": 
                    case "button":
                        return element.value;
                        break;
                }
                break;
        } 
    }, serialize: function(form){
        var data = {};
        this._form = form;

        if(this._validate()){
            this._loopFields(function(value){
                if(value !== null) data[name] = value;
            });
        }
        return data;
    }
};

Para executá-lo, basta usar Form.serialize(form)e a função retornará um Objectsemelhante a este:

<!-- { username: "username", password: "password" } !-->
<input type="text" value="username">
<input type="password" value="password">

Como bônus, significa que você não precisa instalar o pacote inteiro do jQuery apenas para uma função de serialização.

GROVER.
fonte
1

Eu escrevi uma função que cuida de várias caixas de seleção e várias seleções. Nesses casos, ele retorna uma matriz.

function getFormData(formId) {
    return $('#' + formId).serializeArray().reduce(function (obj, item) {
        var name = item.name,
            value = item.value;

        if (obj.hasOwnProperty(name)) {
            if (typeof obj[name] == "string") {
                obj[name] = [obj[name]];
                obj[name].push(value);
            } else {
                obj[name].push(value);
            }
        } else {
            obj[name] = value;
        }
        return obj;
    }, {});
}
István
fonte
1

mostrando os campos do elemento de entrada do formulário e o arquivo de entrada para enviar seu formulário sem atualização da página e pegar todos os valores com o arquivo incluído aqui

<form id="imageUploadForm"   action="" method="post" enctype="multipart/form-data">
<input type="text" class="form-control" id="fname" name='fname' placeholder="First Name" >
<input type="text" class="form-control" name='lname' id="lname" placeholder="Last Name">
<input type="number" name='phoneno'  class="form-control" id="phoneno" placeholder="Phone Number">
<textarea class="form-control" name='address' id="address" rows="5" cols="5" placeholder="Your Address"></textarea>
<input type="file" name="file" id="file" >
<input type="submit" id="sub" value="Registration">					   
</form>
na página do botão Submit enviará uma solicitação de ajax para o seu arquivo php.
$('#imageUploadForm').on('submit',(function(e) 
{
     fname = $('#fname').val();
     lname =  $('#lname').val();
     address =  $('#address').val();
     phoneno =  $('#phoneno').val();
     file =  $('#file').val();
     e.preventDefault();
     var formData = new FormData(this);
     formData.append('file', $('#file')[0]);
     formData.append('fname',$('#fname').val());
     formData.append('lname',$('#lname').val());
     formData.append('phoneno',$('#phoneno').val());
     formData.append('address',$('#address').val());
     $.ajax({
		type:'POST',
                url: "test.php",
                //url: '<?php echo base_url().'edit_profile/edit_profile2';?>',

                data:formData,
                cache:false,
                contentType: false,
                processData: false,
                success:function(data)
                {
                     alert('Data with file are submitted !');

                }

     });

}))

Mohsin Shoukat
fonte
Qual é a necessidade do novo FormData aqui?
Sahu V Kumar
11
@VishalKumarSahu estou carregando o arquivo e é por isso que uso o formData para isso.
Mohsin Shoukat 28/09
1
$(form).serializeArray().reduce(function (obj, item) {
      if (obj[item.name]) {
           if ($.isArray(obj[item.name])) {
               obj[item.name].push(item.value);
           } else {
                var previousValue = obj[item.name];
                obj[item.name] = [previousValue, item.value];
           }
      } else {
           obj[item.name] = item.value;
      }

     return obj;
}, {});

Isso corrigirá o problema: não foi possível trabalhar com várias seleções.

ke ke
fonte
0

Você não está totalmente correto. Você não pode escrever:

formObj[input.name] = input.value;

Porque dessa forma, se você tiver uma lista de seleção múltipla - seus valores serão substituídos pelo último, pois é transmitido como: "param1": "value1", "param1": "value2".

Portanto, a abordagem correta é:

if (formData[input.name] === undefined) {
    formData[input.name] = input.value;
}
else {
    var inputFieldArray = $.merge([], $.isArray(formData[input.name]) ? formData[input.name] : [formData[input.name]]);
    $.merge(inputFieldArray, [input.value]);
    formData[input.name] = $.merge([], inputFieldArray);
}
Alexander
fonte
0

Este método deve fazer isso. Ele serializa os dados do formulário e os converte em um objeto. Também cuida de grupos de caixas de seleção.

function getFormObj(formId) {
  var formParams = {};
  $('#' + formId)
    .serializeArray()
    .forEach(function(item) {
      if (formParams[item.name]) {
        formParams[item.name] = [formParams[item.name]];
        formParams[item.name].push(item.value)
      } else {
        formParams[item.name] = item.value
      }
    });
  return formParams;
}
user1101791
fonte
Funciona para caixas de seleção, mas não para botões de opção em que os controles compartilham o nameatributo.
Kyle Falconer
0

Aqui está uma boa função de baunilha JS que escrevi para extrair dados do formulário como um objeto. Ele também possui opções para inserir adições no objeto e para limpar os campos de entrada do formulário.

const extractFormData = ({ form, clear, add }) => {
  return [].slice.call(form.children).filter(node => node.nodeName === 'INPUT')
  .reduce((formData, input) => {
    const value = input.value
    if (clear) { input.value = '' }
    return {
      ...formData,
      [input.name]: value
    }
  }, add)
}

Aqui está um exemplo de seu uso com uma solicitação de postagem:

submitGrudge(e) {
  e.preventDefault()

  const form = e.target
  const add = { id: Date.now(), forgiven: false }
  const grudge = extractFormData({ form, add, clear: true })

  // grudge = {
  //  "name": "Example name",
  //  "offense": "Example string",
  //  "date": "2017-02-16",
  //  "id": 1487877281983,
  //  "forgiven": false
  // }

  fetch('http://localhost:3001/api/grudge', {
    method: 'post',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(grudge)
  })
    .then(response => response.json())
    .then(grudges => this.setState({ grudges }))
    .catch(err => console.log('error: ', err))
}
IanLancaster
fonte