Como Adicionar Linhas em uma Tabela com jQuery

No post anterior, vimos como remover as linhas dinâmicas de uma tabela sem usar os seletores do jQuery. Caso você queira ver, o link é esse.

Agora, neste tutorial, vamos aprender uma forma de adicionar linhas dinamicamente nessa mesma tabela, utilizando também o jQuery. Para isso, vamos adicionar um botão no footer da tabela.

Deve ficar assim:

jquery-add-rable-row

DEMO

Vamos começar com a marcação da nossa tabela…


Definindo a Tabela

A marcação da nossa tabela vai mudar um pouco. Ela deve possuir agora um <tbody> e um <tfooter> que é onde vai ficar o botão que adicionar linhas. Veja como deve ficar a marcação:

O <tbody> é essencial para tornar mais fácil adicionar as linhas através do jQuery. Essa tag auxilia o agrupamento das linhas, e também na contagem delas, caso seja necessário para o seu projeto.

Já o <tfooter> vai manter o botão de adicionar novas linhas separado do corpo da tabela. E isso também facilita na inserção de linhas e protege o nosso botão de ser colocado entre as linhas, por exemplo.

Observe a função AddTableRow( ), no evento onclick do botão.

É nessa função que vamos implementar para adicionar as linhas.


Criando a Função AddTableRow com JavaScript e jQuery

No tutorial anterior, criamos um arquivo chamado functions.js, para conter as nossas funções em um arquivo javascript externo. Vamos manter esse formato e adicionar, agora, a função AddTableRow.

Essa função deve estar com o formato de funções do jQuery, para que seja possível utilizarmos as funções dele.

Então, a função AddTableRow fica assim:

A variável cols vai conter toda a marcação das colunas da linha. É nela que você irá colocar os inputs, ou qualquer outra coisa que a sua linha deve ter.

E, na última coluna colocamos o botão de remover a linha.

Essa nova linha, que fica guardada na variável newRow, vai ser  anexada no final do corpo da tabela, usando o append(). Por isso a importância do tbody na marcação da tabela. [hr]


Pronto!

Agora temos um botão que adiciona linhas dinâmicas em uma tabela.

Eu usei esta solução para criar uma tela de vendas de produtos, e o usuário pode adicionar mais itens na lista (tabela) e digitar o código e a quantidade, por exemplo. Agora, é só adaptar para o seu projeto.

DEMO

  • Elias

    Muito bom. Rodei muito mais encontrei este tutorial.
    Costumo mostrar um formulário que adiciona itens em banco dados. Gostaria que este após inclusão no bd também adiciona-se a linha como no tutor acima. Seria possível?

  • Elias

    Consegui resolver minha dúvida. Adicionei a linha com os dados puxando o id do banco e mostrando junto com os dados inseridos. Agora, toda vez que incluo uma linha a barra de scroll lateral some. Uso o bootstrap no meu layout.

    • Não entendi muito bem, mas talvez precise da classe .table-responsive na sua tabela.

    • Ótima dica, parabéns!
      Elias, como vc fez para adicionar do banco?
      Obrigado!

  • Francisco

    E como eu recupero os valores dos inputs? Pois nesse caso posso adicionar 10 linhas e ele sempre resgata o valor da ultima somente. Poderia me auxiliar?

    • Quando você criar os inputs, deve dar um nome único pra cada um, assim consegue recuperar os dados.

      Eu uso, por exemplo:
      input name=”dados[‘Produto’][0][‘Nome’]” …
      input name=”dados[‘Produto’][1][‘Nome’]” …

      assim, quando o form é enviado, fica possível usar um foreach no array ‘dados’ e pegar os valores.

      • Poderia dar um exemplo de como fica a function com esse método n to conseguindo implementar…

  • thiago

    Olá! Sou iniciante e gostaria de saber como faço pra prender os dados? pois quando a página é recarregada, ele volta as configurações originais. Obrigado

    • Pra fazer isso, Thiago, você vai precisar guardar os dados em um banco de dados ou em local storage.

      É necessário um script no servidor para receber esses dados, em PHP por exemplo.

  • Douglas

    Boa tarde Ruan

    Por favor, poderia me ajudar e dizer o porque não está funcionando nessa página.

    http://www.sinistrack.com/teste2/

    É só exibir o código fonte que deixei tudo junto na index.

    Obrigado.

    • Você não referenciou o jQuery, então ele não encontra as funções.

      Use o debugger do browser (pela tecla F12), e a parte console vai dizer o que pode estar errado.

      • Douglas

        Obrigado Ruan, ainda sou novato haha

        Referenciei as bibliotecas mas agora surge o seguinte erro:

        Uncaught TypeError: “#products-table”.append is not a function

        • Douglas

          Ruan! Mil desculpas haha
          Vi que é o id da tabela… Agora funcionou certinho!

          Obrigado!

  • Gabriel Alves

    Excelente Tutorial. Sou iniciante em javascripts. Como seria a função para remover as linhas. Poderia postar por favor.

    Obrigado.

  • Charlles

    Estou com esse mesmo erro: Uncaught TypeError: “#products-table”.append is not a function
    E a tabela está com o id correto:

    E essa é a function
    (function($) {
    AddTableRow = function() {

    var newRow = $(“”);
    var cols = “”;

    cols += ‘ ‘;
    cols += ‘ ‘;
    cols += ‘ ‘;
    cols += ‘ ‘;
    cols += ”;
    cols += ‘Remover’;
    cols += ”;

    newRow.append(cols);
    (“#products-table”).append(newRow);

    return false;
    };
    })(jQuery);

    • Charlles, parece-me que está faltando o seletor do jQuery no começo da linha.
      O certo é assim:
      $(“#products-table”).append(newRow);

      Vou corrigir aqui no tutorial, também. Obrigado!

  • Charlles

    Valeu Ruan. Show cara. Agora funcionou, também não atentei pra isso…
    Continue fazendo esses tutoriais, muito bom.

  • Jurian Batista

    Olá gostaria de saber se tem como você me ajudar em projeto PHP+mysql sobre futebol, que queria adicionar uma página com a formação dos times o número dos jogadores e tals aquela formação com o campo de baixo dos números e nome do jogador e suas posições, usando select sql, e também como fazer transferências usando os jogadores do banco pegando preço e diminuindo a quantia do financeiro do clube a cada jogador adiquirido. o Site é Neotech Futebol Digital uso pra jogar com a galera aqui e ao mesmo pra aprender mais sobre PHP.

  • Caro Ruan,

    Quando eu for enviar pro BD os dados. Como vou fazer pra cada tr ter uma id diferente, sendo que no BD a ID já está como AUTO_INCREMENT.

    • Oi Alessandro.

      Você não precisa colocar id em cada tr. Quem cria o ID deles é o BD, usando o AUTO_INCREMENT.

      O que você pode precisar fazer é colocar o id de relacionamento (chave estrangeira, se tiver) nelas. Nesse caso, no server side, insere-se primeiro o item principal no BD (conhecido como master), guarda o ID dele (que o BD retornar) e coloca no campo específico de cada item dependente (conhecido como details, as tr’s). Mas, isso acontece só quando o usuário mandar salvar tudo.

      Esse tipo de cadastro se chama master/detail.

      Consegui esclarecer?!

  • emerson

    Uma dúvida e no caso de colocar um total no fim da grid, eu fiz está somando, mas ao apagar uma linha, não estou conseguindo subtrair a linha retirada do valor total da grid.

    • Você pode ter uma função que atualiza o valor total, tanto quando adiciona uma linha e quando remove.

      E aí na função de remoção da linha, logo no começo você chama essa função de atualização do total.

      Ela deve usar jQuery para pegar o valor a ser subtraído e para atualizar a exibição do total.

  • emerson

    Então Ruan, eu cheguei a inserir esta função abaixo, mas não funcionou.

    $d = jQuery.noConflict();
    $d(‘#tabela-zebrada’).find(‘tbody’).append(tr);
    var soma = 0;
    $d(“#vltotal”).each(function() {
    soma += parseFloat($(this).text());
    });
    $d(‘#resultado’).html(soma);

    };

    • Agora complicou.

      Bom, quando eu fiz essa função usei o .each também.
      A minha função ficou assim, vê se te auxilia em alguma coisa:

      {
      var sum = 0, discount = 0;

      $(‘.item-total’).each(function() {
      var num = parseFloat(this.value) || 0;
      sum += num;
      });

      $(‘#OrderSubtotal’).val(parseFloat(sum).toFixed(2));
      }

      Nessa última linha, usei um .val() porque era um input disabled. Mas, se for texto você pode usar .html().

      Espero que ajude. (Não esquece de mudar os seletores para os que tu usou)

      Abs.
      Ruan

  • Deyvid Lopes

    Ruan Carvalho, muito obrigado pelo post, muito bom e tudo funcionou direito de primeira. Estava usando um código ja existente aqui no meu estágio, mas estava muito complicado. O teu método eh bem mais simples e direto. Obrigado e sucesso.

    • Valeu, Deyvid!

      Fico muito feliz que tenha sido útil.

      Abs!
      Ruan

  • Weyder Ferreira

    Ruan blz?
    Aqui não apareceu as linhas da tabela, ficou apenas com 1 linha e as 4 colunas dos títulos.

    A função de remover a linha funcionou a de adicionar não.
    Tem ideia do que possa vir ser?

  • Anselmo

    Primeiramente, parabéns pelo tutorial!

    Consegui executar esse exemplo, mas nele há um problema…

    Adicionei duas tabelas na mesma página e na hora de adicionar uma linha na tabela1 por exemplo, a linha é inserida na tabela2.
    Não há um controle de em qual tabela inserir a linha!

    Teria como me ajudar com isso?

    Grande abraço.

    • Obrigado, Anselmo!

      Sobre esse caso, você tem que colocar os IDs diferentes nas tabelas, e usar o .append() do jQuery no ID correto.
      Nesse tutorial, o ID está fixo (na linha antes do return) mas você pode mudá-lo.

      Então… você pode ter duas abordagens:

      1. Criar/copiar uma outra função AddTableRow2(), por exemplo, e colocar o ID da segunda tabela na linha do .append(newRow);

      ou

      2. Alterar a função, e passar por parâmetro o this e encontrar o ID da tabela que deve receber a nova linha. (essa é a forma mais complexa, porém é a mais correta).

      Espero que ajude…

      Abs.
      Ruan

      • Anselmo

        Ajudou sim! Muitíssimo obrigado pelo tutorial e também por ter me respondido.
        Abraço.

  • Bia

    Perfeito.

    Uma dúvida o que deveria fazer para a linha ser adicionada como a primeira da tabela?

    • Você pode usar o .prepend()

      Ficaria assim:
      $(“#products-table”).prepend(newRow);

      • Bia

        Cara perfeito. Funcionou.
        Passarei a seguir seu blog. Parabéns.

  • Marcos Silva

    Tem como inserir uma quantidade de linhas digitadas pelo usuario? Tipo terei um campo “Qtde_Parcelas” e quando o usuario clicar em um botao “Gerar_Parcelas” ja inserir dinamicamente esta quantidade de linhas.

  • Boa tarde, eu estou com uma dúvida aqui.
    Vamos supor que eu queira selecionar uma das linhas da tabela com os respectivos campos preenchidos (
    Produto, Código, Quantidade, Preço) e adiciona-lo a um formulário vazio com os campos referentes conforme a linha da tabela. Tem como fazer isso?
    Estou pesquisando aqui e ainda não não encontrei uma solução.
    Aguardo respostas,
    Parabéns pelo conteúdo, muito bom!

    • Obrigado, Maickon.

      É possível fazer isso sim, mas você vai precisar escrever um script personalizado, que copia cada valor da tabela para um campo referente no formulário.

      Não existe nenhuma forma genérica, ou automática, de fazer isso. E deve usar bastante ID’s, classes e eventos Javascript.

      Abs.
      Ruan

  • Cleomar Dias

    Achei ótimo a dica, gostaria de uma ajuda para a seguinte questão.

    a primeira linha da tabela sera preenchida pelo usuário, ao clicar no botão ADD o função vai fazer copiar todo conteúdo input e colar na tabela indicada.

    não estou conseguindo pegar essa parâmetros e repassar na função. poderia me ajudar.?

    meu objetivo é criar um formulário onde o usuário vai informa vários intervalos para gravação no banco.

  • Alex Silva

    Boa tarde.

    Muito bom!!!

    Utilizei em um sistema e gostaria de esclarecer uma dúvida.
    Esse sistema é para orçamentos de viagens, em cada linha que incluir digito o prefixo do ônibus e 3 campos são preenchidos (Poltronas, Toalete, Ano do Veículo) obtendo essas informações com JSON do BD, está funcionando perfeitamente, porém só na primeira linha.
    Como posso capturar/mudar o nome de cada input antes de submeter o formulário?

    Desde já obrigado.

  • Lucas Silva

    Muito Legal me ajudo bastante.
    Mas, há algo que estou procurando e não encontrei, eu queria que o botão add product estivesse sempre na ultima linha da tabela ao lado do Remove. Tem como fazer isso? alguém poderia me ajudar?

  • Olá, Ruan Carvalho…
    Gostei muito do seu blog, e estava procurando soluções assim pra um projeto q estou batendo cabeça.
    Minha tabela precisa ter a quantidade de campos de acordo com um grupo de registro que vou pesquisar.
    Tenho registrso assim
    —————————————-
    c01— c02— c03— c04—c05
    —————————————-
    c47 wky bya xxx
    c48 wky bya xx2
    c51 xyz wky bya bab
    c62 xyz wky bya bab

    qdo pesquisar por like ‘c4’
    ele deveria montar a tabela apenas com o cabeçalho de C01 ate C04
    e registrar os dois registros dessas busca, no caso:

    ———————————-
    C01 C03 C04 C05
    ———————————-
    c47 wky bya xxx
    c48 wky bya xx2

    Me ajuda a montar isso dinamicamente?

  • Amigo, funcionou perfeitamente,

    Mas como faço para adicionar uma linha abaixo de outra linha que eu cliquei ?

    Quero que o usuário clique em um determinado item na tabela, e logo abaixo, apareça os detalhes daquele item selecionado.

    Obrigado

  • Marcos A. Silva

    Perfeito, só gostaria de fazer também a validação do campo no onBlur. Ao sair do campo validar se o usuario nao preencheu pra não correr o risco do usuário inserir uma nova linha e fazer o POST do formulário com esta linha vazia.

  • Gian

    Muito bom o tutorial, parabéns.
    Surgiu uma dúvida, no meu projeto tenho a mesma “tabela1” do seu tutorial, porém com um campo de busca, que faz a busca na tabela de produtos cadastrados no banco. Gostaria de que quando listo e seleciono os produtos desejados eles fossem parar nas linhas dessa “tabela1” inicial.
    Estou iniciando em js, suas dicas estão sendo de grande ajuda.
    Obrigado

  • Luan

    Olá, poderia me dar um auxilio se possível?

    Estou utilizando as orientações acima para criar dinamicamente minhas linhas da tabela.

    Todavia quando eu clico em algum botão que submete a página para o codebehinde os dados são permitidos.

    Tem alguma maneira de após o submite ele permanecer com os dados da tabela criada?

    • Oi Luan…

      Se você tiver, realmente, que submeter o formulário, você vai ter que montar toda a tabela com os dados persistidos, usando o codebehind, ao recarregar a página.

      Uma outra forma, seria usar AJAX para enviar os dados dos campos. Porém, o código fica um pouco mais complicado, mas você conseguiria manter os dados sem recarregar a página.

      Só com o HTML, não é possível.

      Abs.
      Ruan

      • Luan

        Ruan, obrigado pelo seu retorno!

        Vou deixar aqui minha solução para caso alguém necessite assim como eu precisei!

        Estou usando a linguagem asp.net e precisei submeter a página, quando isso era feito eu perdia o que estava sendo preenchido nos campos da tabela.

        Primeiramente eu criei uma classe ManterTabela(List listitem) /*Passei uma entidade com os valores preenchidos do grid, caso não esteja preenchido ele retorna apenas uma lista com uma linha no GRID sem valores.*/

        Após isso, dentro do meu botão “Adicionar” no evento Click no servidor eu fiz um list eu passei nesta lista os valores existente em todos os meus campos do GRID é possível recuperar os valores usando request

        Segue exemplo:

        if (!string.IsNullOrEmpty(Request[“txtQtd_” + cont]) &&
        !string.IsNullOrEmpty(Request[“txtDescricao_” + cont]) &&
        !string.IsNullOrEmpty(Request[“txtValorUnitario_” + cont]) &&
        !string.IsNullOrEmpty(Request[“txtValorTotal_” + cont])
        )
        {
        contador_itens++;
        itse = new Entidade.Itens_Servico();
        itse.itse_quantidade = int.Parse(Request[“txtQtd_” + cont].ToString());
        itse.itse_descricao = Request[“txtDescricao_” + cont].ToString();
        itse.itse_vlUnitario = double.Parse(Request[“txtValorUnitario_” + cont].ToString().Replace(“,”,”.”));
        itse.itse_vlTotal = double.Parse(Request[“txtValorTotal_” + cont].ToString().Replace(“,”, “.”));
        listaItems.Add(itse);
        }

        Na minha classe manter tabela eu verifico se minha lista é nula se não for cria a tabela com os parametros existentes:

        public string ManterTabela(List listitem)
        {
        int cont = 0;

        StringBuilder html = new StringBuilder();
        html.Append(“”);
        html.Append(” Qtd Descrição V.U V.T “);
        html.Append(“”);

        if (listitem != null)
        {
        foreach (var item in listitem)
        {
        html.Append(“”);
        html.Append(“”);
        html.Append(” “);
        html.Append(“”);
        html.Append(“”);
        html.Append(“”);
        html.Append(“”);
        html.Append(“”);
        html.Append(“”);
        html.Append(“”);
        html.Append(” “);
        html.Append(“”);
        html.Append(“”);
        html.Append(“”);
        html.Append(“”);
        html.Append(“”);
        cont++;
        }
        }
        else
        {
        html.Append(“”);
        html.Append(“”);
        html.Append(” “);
        html.Append(“”);
        html.Append(“”);
        html.Append(“”);
        html.Append(“”);
        html.Append(“”);
        html.Append(“”);
        html.Append(“”);
        html.Append(” “);
        html.Append(“”);
        html.Append(“”);
        html.Append(“”);
        html.Append(“”);
        html.Append(“”);

        }
        html.Append(“”);
        html.Append(“”);

        Depois basta chamar o método onde vc quiser, no meu caso usei no load da página e no submit do botão.

        Espero ter ajudado!

        Atenciosamente,

        Luan Neres

  • Luan

    Por alguma razão, minha publicação acima retirou o código com o html montado através do stringbuilder.
    Talvez seja uma proteção do fórum.

    Se alguém precisar de auxilio neste quisito, basta me enviar um e-mail então rs.

    [email protected]

    Um abraço.

    Atenciosamente,

    • Valeu, Luan!
      Fico feliz que deu certo.

      O site tem um mecanismo de segurança que filtra códigos, por isso sumiu alguns trechos.

      Você pode usar o gist.github.com, numa próxima oportunidade. Assim, os códigos não somem.

      Abs.
      Ruan

  • Excelente Ruan, parabéns.

    Adaptei ao meu projeto e me proporcionou ter uma solução sem maiores rodeios e com muito menos código.

    Muito obrigado,

  • Cleomar

    Boa Dia!!

    Gostaria da ajuda de vocês para um problema, conseguir fazer essa estrutura acima, porém preciso enviar esse conjunto de informações via ajax para o PHP, qual melhor forma de se fazer, alguém tem a solucção.

  • wellington oliveira

    O código ficou ótimo gostei muito, uma pequena e simples questão do tutorial, caso eu esteja errado…
    Se aplicarmos um cols += ”; logo abaixo do td a tabela não ficaria linha finalizada e correta…?
    Ex:
    cols += ”;
    cols += ”;

    Obrigado Valeu.

    • Nesse exemplo, não é necessário, Wellington.

      Na linha 4, a TR está sendo criada pelo jQuery. E assim ele já cria a tag que fecha a linha.
      Por isso, não precisamos fechar a TR no final.

      Se a TR fosse criada “na mão”, como foram as TD (colunas), aí sim precisaria fechar no final, como você colocou.

      Espero ter tirado a dúvida.
      Abs.
      Ruan

  • wellington oliveira

    cols += ‘ / td ‘;
    cols += ‘ / tr ‘;

    Para finalizar a linha da tabela

  • Valeu fera! mto bom!

  • oi eu posso colocar essa tabela dentro de um formulario e enviar para uma pagina php fazer o insert no banco ?
    se posso como eu definiria o nome das variaves dos campos(inputs) incrementados ?

    • Pode. Essa tabela foi feita com essa intenção.

      Nos inputs, você deve criar um nome único para cada um, no formato de array.
      Algo do tipo:
      <input name=”dados[‘Produto’][$i][Nome’] … >

      a variável $i é o número da linha.
      Todos os dados vão ficar em um Array chamado “Produtos”, dentro de “dados”.

      • Ruan obrigado por responder tão prontamente mais poderia dar um exemplo melhor ?

        a minha esta assim mais o nome gostaria que fosse modificado a cada vez que adicionasse uma nova linha

        cols += ”;

        a cada linha mudasse esse nome do input

        • Dá uma estudada esse exemplo:
          https://codepen.io/ruancarvalho/pen/ENBvqx

          • Deu certinho!!!, mais agora tenho outra duvida rs, para que eu faca a quantidade vezes o valor aparecer no campo total eu estou usando pelo id mais nas que adiciono não consigo colocar uma id para cada linha você tem alguma ideia de como fazer isso?

  • Allan Souza

    Boa noite!

    Alguém me poderia ajudar com o código para adicionar colunas dinamicamente, da mesma maneira que fazemos com as linhas da tabela?

    Não estou a conseguir colocar a função a funcionar.

    Por favor!

    Obrigado

  • Ruan, eay cara adorei seu modelo e deu tudo certo quando coloquei uma array como name ex: produto[].

    mais agora queria saber uma outra coisa existe a possibilidade de colocar no lugar de um input um select chamando os produtos da base de dados?
    pois ele não executa o php (conexao e select do banco) dentro do javascrip certo?

    se existe vc tem algum modelo de como fazer esse select chamando os produtos da base?

  • Anderson de Castro

    Nao encontra a function RemoveTableRow ? onde ela e declarada ? Obrigado

    • Anderson de Castro

      RemoveTableRow = function(handler) {
      var tr = $(handler).closest(‘tr’);

      tr.fadeOut(400, function(){
      tr.remove();
      });

      return false;
      };

      Achei nem esta no tutorial a parte deste codigo.

      • Isso mesmo. Esse trecho é do tutorial de remoção.

        Este tutorial aqui é a continuação daquele.

  • Lucas Morais

    Ruan

    Independente de quantas linhas forem adicionadas, poderia me dar um exemplo de como eu enviarei estes dados a um banco?

  • Olá…excelente explicação…!!! esta sendo muito útil para mim.
    Porem eu precisava que essas tabela fosse gerada automaticamente durante o carregamento da página. Até nesse ponto, ok…
    Porem não estou conseguindo preencher um “campo” especifico com um dado salvo em uma variável em .js.

    Estaria ao seu alcance me auxiliar… no mais obrigado

    Att,

    John

Orgulhosamente feito com WordPress | Tema: Baskerville 2 por Anders Noren

Acima ↑