Como converter todos os elementos do meu formulário em um objeto JavaScript?
Eu gostaria de ter alguma maneira de criar automaticamente um objeto JavaScript do meu formulário, sem ter que fazer um loop sobre cada elemento. Eu não quero uma string, como retornado por $('#formid').serialize();
, nem o mapa retornado por$('#formid').serializeArray();
javascript
jquery
json
serialization
Yisroel
fonte
fonte
Respostas:
serializeArray
já faz exatamente isso. Você só precisa massagear os dados no formato necessário:Cuidado com os campos ocultos que têm o mesmo nome que as entradas reais, pois eles serão substituídos.
fonte
$.map( $("#container :input"), function(n, i) { /* n.name and $(n).val() */ } );
se você precisar incluir elementos desabilitados.foo[bar]
entradas de tipo conforme o esperado, sem mencionar a maioria das outras variedades de nomes de entrada. Depois de ficar muito frustrado com soluções superficiais para esse problema, acabei escrevendo meu próprio plugin jQuery - detalhes na resposta que forneci a esta pergunta.Converter formulários em JSON como um chefe
A fonte atual está no GitHub e no Bower .
O código a seguir agora está obsoleto .
O código a seguir pode funcionar com todos os tipos de nomes de entrada; e lide com eles exatamente como você esperaria.
Por exemplo:
Uso
A Feitiçaria (JavaScript)
fonte
<select name="foo" multiple="multiple">
não funcionará em nenhum cenário. No entanto, se você usar[]
, como em<select name="bar[]" multiple="multiple">
, ele vai funcionar muito bem :)O que há de errado com:
fonte
.each
vez de.map
??var form = {}; $.each($(this).serializeArray(), function (i, field) { form[field.name] = field.value || ""; });
$(this).serializeArray().reduce(function(m,o){ m[o.name] = o.value; return m;}, {})
Uma versão fixa da solução de Tobias Cohen. Este lida corretamente com valores falsos como
0
e''
.E uma versão do CoffeeScript para sua conveniência de codificação:
fonte
value = @value ? ''
keyMap
e a seguinte linha:key = if keyMap? then keyMap(@name) else @name
. Agora você pode passar a função de mapeamento como(name) -> name.match(/\[([^\]]+)]/)[1]
. E, em seguida, seria preciso mudar tudo subseqüente@name
parakey
, é claropost
, você poderia simplesmente fazer$('form').serializeObject().post
. Não há necessidade de mapeamento sofisticado.if (!objectData[this.name].push)
??objectData[this.name]
o método push (a grosso modo, é uma matriz). Se for uma matriz, ele empurra o valor; se não for uma matriz, o converte em uma matriz, para que vários valores com a mesma chave sejam combinados em uma matriz.Eu gosto de usar
Array.prototype.reduce
porque é uma linha e não depende do Underscore.js ou similar:Isso é semelhante à resposta usada
Array.prototype.map
, mas você não precisa desordenar seu escopo com uma variável de objeto adicional. Balcão único.NOTA IMPORTANTE : Os formulários com entradas com
name
atributos duplicados são HTML válidos e, na verdade, são uma abordagem comum. O uso de qualquer uma das respostas neste tópico será inadequado nesse caso (já que as chaves de objetos devem ser únicas).fonte
array.prototype.reduce()
não está disponível no IE8, pois faz parte da especificação do ECMAScript 5. Portanto, se você precisar do suporte ao IE8, convém usar um polyfill ou outra solução.Todas essas respostas me pareciam exageradas. Há algo a ser dito para simplificar. Contanto que todas as entradas de seu formulário tenham o atributo name definido, isso deve funcionar apenas jim dandy.
fonte
Realmente não há como fazer isso sem examinar cada um dos elementos. O que você realmente quer saber é "alguém já escreveu um método que converte um formulário em um objeto JSON?" Algo como o seguinte deve funcionar - observe que ele fornecerá apenas os elementos do formulário que seriam retornados por meio de um POST (deve ter um nome). Isso não foi testado .
fonte
Se você estiver usando o Underscore.js, poderá usar o relativamente conciso:
fonte
Eu verifiquei que há um problema com todas as outras respostas, que, se o nome da entrada for como uma matriz, como
name[key]
, então, ele deve ser gerado assim:name:{ key : value }
Por exemplo: Se você possui um formulário HTML semelhante ao abaixo:
Mas deve ser gerado exatamente como o JSON abaixo e não se torna um objeto como o seguinte com todas as outras respostas. Portanto, se alguém quiser trazer algo como o seguinte JSON, tente o código JS abaixo.
fonte
eval
não deve ser usado dessa maneira porqueeval
, quando usado dessa maneira, promove práticas terrivelmente não confiáveis, com erros, com desempenho incorreto e potencialmente inseguras.this.c = function(k,v){ eval("c = typeof "+k+";"); if(c == 'undefined') _t.b(k,v);}
é curto e não explicativo. Um desenvolvedor com menos experiência apenas copiará isso sem entender por que e como funciona.eval()
meu código.Ok, eu sei que isso já tem uma resposta altamente votada, mas outra pergunta semelhante foi feita recentemente e eu fui direcionado para essa pergunta também. Também gostaria de oferecer minha solução, porque oferece uma vantagem sobre a solução aceita: você pode incluir elementos de formulário desabilitados (o que às vezes é importante, dependendo de como a interface do usuário funciona)
Aqui está a minha resposta da outra pergunta SO :
Inicialmente, estávamos usando o
serializeArray()
método jQuery , mas isso não inclui elementos de formulário que estão desabilitados. Geralmente, desabilitamos elementos de formulário que são "sincronizados" com outras fontes na página, mas ainda precisamos incluir os dados em nosso objeto serializado. EntãoserializeArray()
está fora. Usamos o:input
seletor para obter todos os elementos de entrada (ativados e desativados) em um determinado contêiner e depois$.map()
criar nosso objeto.Observe que, para que isso funcione, cada uma de suas entradas precisará de um
name
atributo, que será o nome da propriedade do objeto resultante.Na verdade, isso é ligeiramente modificado do que usamos. Precisávamos criar um objeto estruturado como um .NET IDictionary, por isso usamos o seguinte: (eu forneço aqui caso seja útil)
Gosto dessas duas soluções, porque são simples usos da
$.map()
função e você tem controle total sobre o seletor (portanto, quais elementos você acaba incluindo no objeto resultante). Além disso, nenhum plug-in extra é necessário. JQuery antigo simples.fonte
map
assim cria uma matriz de objetos com uma única propriedade, não recolhe as propriedades em um único objeto.Essa função deve manipular matrizes multidimensionais junto com vários elementos com o mesmo nome.
Eu tenho usado por alguns anos até agora:
fonte
Você consegue fazer isso:
Veja JSON .
fonte
O one-liner (sem dependências além do jQuery) usa a ligação de objeto fixo para a função transmitida ao
map
método.O que faz?
adequado para aplicativos da web progressivos (é possível suportar facilmente ações de envio de formulários regulares e solicitações de ajax)
fonte
Usar:
Resultado:
fonte
Simplicidade é melhor aqui. Eu usei uma string simples substituir por uma expressão regular, e eles funcionaram como um encanto até agora. Não sou especialista em expressões regulares, mas aposto que você pode até preencher objetos muito complexos.
fonte
De alguma resposta antiga :
fonte
serializeArray
portanto você tem a liberdade de escolher as entradas que deseja (por exemplo, você pode incluir entradas desativadas), certo? Ou seja, isso não está associado a nenhum formulário ou ao evento de envio, é apenas independente por si só?reduce
retorna o objeto. Isso não é independente, poistoArray
é do jQuery.Encontrei um problema com o código de Tobias Cohen (não tenho pontos suficientes para comentar diretamente), o que de outra forma funciona para mim. Se você tiver duas opções de seleção com o mesmo nome, ambas com value = "", o código original produzirá "name": "" em vez de "name": ["", ""]
Acho que isso pode ser corrigido adicionando "|| o [this.name] == ''" à primeira condição if:
fonte
Usando a solução de maček , modifiquei-a para trabalhar com a maneira como o ASP.NET MVC lida com objetos aninhados / complexos no mesmo formulário. Tudo o que você precisa fazer é modificar a parte de validação para isso:
Isso corresponderá e, em seguida, mapeará corretamente os elementos com nomes como:
E
fonte
a maneira mais simples e mais precisa que eu encontrei para este problema foi usar plug-in churrasco ou este um (que é de cerca de 0,5K tamanho bytes).
Ele também trabalha com matrizes multidimensionais.
fonte
Existe um plugin para fazer exatamente isso no jQuery, jquery.serializeJSON . Eu usei com sucesso em alguns projetos agora. Ele funciona como um encanto.
fonte
fonte
Eu prefiro essa abordagem porque: você não precisa iterar mais de duas coleções, pode obter coisas diferentes de "nome" e "valor", se necessário, e pode limpar seus valores antes de armazená-los no objeto ( se você tiver valores padrão que não deseja armazenar, por exemplo).
Use assim:
Testado apenas no Firefox.
fonte
Transforme qualquer coisa em um objeto (não testado em unidade)
A saída do teste:
em
produzirá:
fonte
Encontrei um problema com a solução selecionada.
Ao usar formulários com nomes baseados em array, a função serializeArray () do jQuery realmente morre.
Eu tenho uma estrutura PHP que usa nomes de campos baseados em matriz para permitir que o mesmo formulário seja colocado na mesma página várias vezes em vários modos de exibição. Isso pode ser útil para adicionar, editar e excluir na mesma página sem modelos de formulário conflitantes.
Como eu queria seralizar os formulários sem precisar remover essa funcionalidade básica absoluta, decidi escrever meu próprio seralizeArray ():
Observação: isso também funciona fora do formulário submit (); portanto, se ocorrer um erro no restante do código, o formulário não será enviado se você inserir um botão de link dizendo "salvar alterações".
Observe também que essa função nunca deve ser usada para validar o formulário apenas para reunir os dados a serem enviados ao servidor para validação. Usar esse código fraco e atribuído em massa causará XSS , etc.
fonte
Eu tive o mesmo problema recentemente e criei este plugin .toJSON jQuery que converte um formulário em um objeto JSON com a mesma estrutura. Isso também é especialmente útil para formulários gerados dinamicamente, nos quais você deseja permitir que o usuário adicione mais campos em locais específicos.
O ponto é que você pode realmente criar um formulário para que ele tenha uma estrutura própria; digamos que você queira criar um formulário no qual o usuário insira seus lugares favoritos na cidade: você pode imaginar esse formulário para representar um
<places>...</places>
elemento XML contendo um lista de locais que o usuário gosta, portanto, uma lista de<place>...</place>
elementos, cada um contendo, por exemplo, um<name>...</name>
elemento, um<type>...</type>
elemento e, em seguida, uma lista de<activity>...</activity>
elementos para representar as atividades que você pode executar em um local como esse. Portanto, sua estrutura XML seria assim:Quão legal seria ter um objeto JSON disso, que representaria essa estrutura exata, para que você seja capaz de:
OK, agora precisamos pensar em como um formulário pode representar um arquivo XML.
É claro que a
<form>
tag é oroot
, mas temos o<place>
elemento que é um contêiner e não o próprio elemento de dados; portanto, não podemos usar uma tag de entrada para ele.Aqui é onde a
<fieldset>
tag é útil! Usaremos<fieldset>
tags para representar todos os elementos do contêiner em nosso formulário / representação XML e, assim, obter um resultado como este:Como você pode ver neste formulário, estamos violando a regra dos nomes exclusivos, mas tudo bem, porque eles serão convertidos em uma matriz de elemento e, portanto, serão referenciados apenas pelo índice dentro da matriz.
Nesse ponto, você pode ver como não existe
name="array[]"
um nome semelhante no formulário e tudo é bonito, simples e semântico.Agora queremos que este formulário seja convertido em um objeto JSON que se parecerá com isso:
Para fazer isso, desenvolvi este plugin jQuery aqui, que alguém ajudou a otimizar neste segmento de Revisão de código e fica assim:
Eu também fiz este post para explicar mais isso.
Isso converte tudo em um formulário para JSON (mesmo caixas de seleção e rádio) e tudo o que você precisa fazer é chamar
Eu sei que há muitas maneiras de formas converter em objetos JSON e seguro
.serialize()
e.serializeArray()
trabalho grande na maioria dos casos e destinam-se principalmente a ser utilizado, mas eu acho que toda essa ideia de escrever um formulário como uma estrutura XML com nomes significativos e convertê-lo em um objeto JSON bem formado vale a pena tentar, também o fato de poder adicionar tags de entrada com o mesmo nome sem se preocupar é muito útil se você precisar recuperar dados de formulários gerados dinamicamente.Espero que isso ajude alguém!
fonte
Eu mesmo codifiquei um formulário para um objeto JavaScript multidimensional para usá-lo na produção. O resultado é https://github.com/serbanghita/formToObject.js .
fonte
Outra resposta
FormData: https://developer.mozilla.org/en-US/docs/Web/API/FormData
fonte
[ATUALIZAÇÃO 2020]
Com um oneliner simples no vanilla js:
fonte
Eu gosto da versão samuels, mas acredito que tenha um pequeno erro. Normalmente JSON é enviado como
NÃO como
então a função IMO deve ler:
e envolvê-lo em uma matriz de dados (como normalmente também é esperado) e, finalmente, enviá-lo como um App.stringify ({data: App.toJson ('#cropform: input')})
Para a stringify, consulte a Pergunta 3593046 para a versão lean, em json2.js para a versão com todas as eventualidades. Isso deve cobrir tudo :)
fonte
Para uma solução rápida e moderna, use o plugin JSONify jQuery. O exemplo abaixo é retirado literalmente do GitHub README. Todo o crédito a Kushal Pandya, autor do plugin.
Dado:
Corrida:
Produz:
Se você deseja executar um jQuery POST com este objeto JSON:
fonte