16/09/2011

Formulário dinâmico com jQuery

Bom galera , é o primeiro post aqui :P e venho trazer a vocês uma forma de otimizar as páginas de cadastro com um formulário dinâmico através do jQuery.

Qual a ideia ?

A princípio a ideia é inserir o formulário de acordo com a demanda, não sobrecarregando a página com elementos que possivelmente não iram ser usados e identificar cada campo com o atributo name diferente para recuperá-los mais tarde. Bom, acho que consegui me expressar … então vamos botar a mão na massa!

HTML

Primeiramente precisamos de nosso formulário

    <form method="get" action="processa.php">
    <table>
        <thead>
            <tr>
                <th>Item</th>
                <th>Quantidade</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td><input type="text" name="item1" size="60" /></td>
                <td><input type="text" name="quantidade1" size="10" /></td>
            </tr>
        </tbody>
    </table>
    <!--Irá armazenar a quantidade de linhas-->
    <input type="hidden" value="1" name="quantidade_itens" />
    </form>

Agora precisamos de dois elementos que posteriormente irão disparar o envio do formulário e a inserção de novos inputs.

    <a href="#" id="enviar">Enviar lista de compras</a>
    <a href="#" id="mais">Add Item</a>

jQuery

Para enviar o formulário, iremos associar o seu método .submit() ao evento .click() de um dos elementos que criamos para este fim. Aqui utilizaremos o link com id enviar.

// JavaScript Document
$('#enviar').click(function(){
	$('form').submit();
});

E Agora o X da questão!

Dentro do evento .click() do link com id mais vamos:

  1. Armazenar numa variável a quantidade de linhas de nossa tabela.
  2. Inserir o código html da linha que contém os inputs com a propriedade name concatenada com o número da linha a ser inserida que armazenamos na variável next.
  3. E por fim atualizar o valor do elemento :hidden que usamos para armazenar a quantidade de linhas.
	$('#mais').click(function(){

		//recuperando o próximo numero da linha
		var next = $('#lista tbody').children('tr').length + 1;

		//inserindo formulário
		$('#lista tbody').append('<tr>' +
        	'<td><input type="text" name="item' + next + '" /></td>' +
            '<td><input type="text" name="quantidade' + next + '" /></td>' +
        '</tr>');

		//armazenando a quantidade de linhas ou registros no elemento hidden
		$(':hidden').val(next);

		return false;
	});

Mas pra que serve saber a quantidade de linhas de registros neste formulário ?

É simples, como criamos o formulário dinâmico, devemos informar à página que irá receber os dados qual a quantidade de registros que ela irá receber.

Pronto, o script já está funcionando. Mas para um melhor entendimento mostraremos como a página irá receber estes dados.

PHP

A pagina deverá conter uma variável para recuperar a quantidade de itens, (lembra aquela que comentamos ?) e um loop que terá como limite nossa variável.

Dentro dele basta recuperar os valores concatenando a propriedade name do campo com o número da repetição.

<?php

	$quantidade_itens = $_GET['quantidade_itens'];

	for ( $x = 1; $x <= $quantidade_itens ; $x++ ){

		$item = $_GET["item$x"];
		$quantidade = $_GET["quantidade$x"];

		//aqui seu código com o uso dos valores capturados

	}
?>

Veja a

Demo

O que fizemos basicamente ?

Inserimos através do método .append() os inputs com o atributo name concatenado com a quantidade de linhas mais 1, que atribuímos à variável quantidade. Sendo assim somente o final da propriedade name irá mudar , facilitando a recepção dos dados por outra página. Implementando então uma inserção dinâmica onde todos os valores poderão ser capturados.

Obs:. É bom lembra que essa é “uma” das formas de se fazer … cada um pode implementar da maneira que quiser mas o conceito , como já mencionei, é sempre o mesmo.

Atenção para a dica:

Aqui não foi associado nenhum evento aos inputs, mas se necessário, é preciso utilizar o método .live() para que este evento se estenda a todos os inputs.

Um abraço e até o próximo post!


Comentários

  • Gardiego 16 de setembro de 2011

    Muito bacana o post, parabéns!

  • Tiago A. 7 de outubro de 2011

    Eu já passei por isso uma vez: tinha um grupo de campos que tinha que ser duplicado. Ao passar do tempo esse grupo crescia, e o HTML era alterado. Ou seja, dois HTML iguais deveriam ser alterados.
    Aplicando essa teoria no exemplo postado, eu faria da seguinte forma:
    Ao invés de ter o HTML que será duplicado numa string, eu pegaria este HTML do próprio HTML. E depois, alterar os numeros da quantidade por expressão regular.

    • Fagner Valente 7 de outubro de 2011

      Thiago também funcionaria perfeitamente …!

  • paulo 25 de outubro de 2011

    nao podeira passar o codigo completo

  • Paulo Precht 4 de novembro de 2011

    Bom dia, muito bom o exemplo, parabéns :)

    Estou estudando o exemplo citado, porem gostaria que os dados (items), fossem selecionados de um banco de dados mysql, e não digitados, no caso criei um chamado produtos, com as tabelas “codigo” e “item”.

    Alguma ideia da forma mais pratica de fazer?

    Abraço.

  • Leandro 9 de março de 2012

    Bom dia, estou usando jsp mas seguindo seu tutorial, provavelmente estou me perdendo na hora de recuperar os valores pois so consigo retornar o ultimo. Teria como me mandar o fonte do processa.php apenas pra ver como voce recebe ?

    Abraço

  • Rafael 23 de abril de 2012

    Galera, estou enfrentando uma dificuldade e nao sei como resolver!!!

    estou duplicando dois campos até ai blz o problema é que esses dois campos sao carregados a partir dos dados de uma tabela.

    eu tenho o
    campo 1 estados e campo 2 cidades ao selecionar o campo 1 ele alimenta o campo 2 com as informaçoes relacionadas com os estados selecionado.
    na primeira vez que os campos aparecem funciona porem ao duplicar nao funciona nenhum controle.
    ALguem teria algum exemplo de como fazer isso?

    • Fagner Valente 3 de maio de 2012

      Rafael , não sei como está o seu código mas pelo que disse o problema está na delegação de evento que tem que ser feita por um método que permita a replicação deste evento para o novo html que você está inserindo após o carregamento da página via jQuery …
      Cheguei a comentar sobre isso no post falando sobre o método “live” que por sinal foi substituido pelo método “on” nas novas versões da biblioteca …. Te aconselho então a ler este artigo aqui do Ruan que aborda este assunto…
      http://jquerybrasil.org/lancado-jquery-1-7/

      qualquer dúvida estamos a disposição

  • Gustavo 13 de maio de 2012

    Ola, Eu Fiz tudo Direitinho só que não entendi por que a ID #lista no Codigo de JQuery..
    E a minha Contagem deu Errado.. Aonde que está a ID=”lista”? Grato..

    • Fagner Valente 14 de maio de 2012

      Gustavo , você identificou um descuido meu ^^ …

      como você disse no código não tem nenhum elemento com ID “#lista” , mas ele se refere a tabela “table” ok ?

      irei revisar o código …

Deixe seu Comentário