SW Core
SW Core / JavaScript / Tabela avançada

Tabela avançada JavaScript

Pega uma <table> comum e dá a ela busca, ordenar clicando no título da coluna, paginação, exportar para planilha, imprimir e modo celular — só com atributos.

O que é

É a tabela de painel: lista de clientes, pedidos, produtos, inscritos. Você escreve a tabela normal do HTML (<thead> com os títulos e <tbody> com as linhas) e coloca sw-table nela. Ela ganha sozinha um campo de busca, ordenação por coluna, faixas alternadas (zebra), escolha de quantas linhas por página e a paginação embaixo. Outros recursos — exportar CSV, copiar, imprimir, marcar linhas, esconder colunas, modo celular — você liga com mais atributos.

Precisa do JavaScript do SW Core. O script lê as linhas que já estão no HTML e faz busca, ordem e paginação no navegador, sem recarregar a página. A ordenação entende número e texto em português (acentos contam como a letra sem acento). Os botões de busca, exportar e imprimir usam ícones swi-*, que vêm no pacote complementar. Para milhares de linhas, existe o modo servidor (sw-table-url), que pede cada página ao seu back-end.

Quando usar

  • Lista em painel administrativo (clientes, pedidos, estoque) com até algumas centenas de linhas: <table sw-table>.
  • Relatório que o cliente leva para o Excel: acrescente sw-table-export="csv".
  • Ações em lote (excluir vários, enviar e-mail para vários): sw-table-select.
  • Tabela que precisa caber no celular sem arrastar para o lado: sw-table-collapse.
  • Milhares de registros no banco: modo servidor com sw-table-url — a busca e a página vêm do seu back-end.

Comece aqui

  1. 1

    Coloque o SW Core na página. O segundo CSS traz os ícones da busca e dos botões (lupa, planilha, impressora).

    <link rel="stylesheet" href="swcore/swcore.min.css">
    <link rel="stylesheet" href="swcore/swcore.compl.min.css">
    
    <!-- fim do body -->
    <script src="swcore/swcore.min.js"></script>
  2. 2

    Escreva a tabela normal e coloque sw-table. Busca, ordenação e zebra já vêm ligadas. Aqui, 5 linhas por página.

    ClienteCidadeSituaçãoTotal
    Ana SouzaRecifeAtivoR$ 1.240,00
    Bruno LimaOlindaAtivoR$ 380,00
    Carla DiasCaruaruInativoR$ 2.050,00
    Diego AlvesRecifeAtivoR$ 95,00
    Elisa RamosPetrolinaAtivoR$ 710,00
    Fábio TorresGaranhunsInativoR$ 1.480,00
    Gabriela ReisRecifeAtivoR$ 560,00
    Heitor NunesOlindaAtivoR$ 3.200,00
    <table sw-table sw-table-per="5">
      <thead>
        <tr><th>Cliente</th><th>Cidade</th><th>Situação</th><th>Total</th></tr>
      </thead>
      <tbody>
          <tr><td>Ana Souza</td><td>Recife</td><td>Ativo</td><td>R$ 1.240,00</td></tr>
          <tr><td>Bruno Lima</td><td>Olinda</td><td>Ativo</td><td>R$ 380,00</td></tr>
      </tbody>
    </table>

Todas as variações

Cada quadro abaixo é o componente de verdade, rodando. O código embaixo é exatamente o que está no quadro: copie e cole.

1. O que já vem ligado

Só com sw-table: campo de busca (procura em todas as colunas), ordenação clicando no título (clique de novo inverte), zebra, seletor de linhas por página e paginação. Cada um pode ser desligado com ="false"; uma coluna específica pode ficar sem ordenação com sw-table-nosort no <th>.

ClienteCidadeSituaçãoTotal
Ana SouzaRecifeAtivoR$ 1.240,00
Bruno LimaOlindaAtivoR$ 380,00
Carla DiasCaruaruInativoR$ 2.050,00
Diego AlvesRecifeAtivoR$ 95,00
Elisa RamosPetrolinaAtivoR$ 710,00
Fábio TorresGaranhunsInativoR$ 1.480,00
Gabriela ReisRecifeAtivoR$ 560,00
Heitor NunesOlindaAtivoR$ 3.200,00
Padrão — sw-table sozinho (10 por página)
<table sw-table>
  <thead>
    <tr><th>Cliente</th><th>Cidade</th><th>Situação</th><th>Total</th></tr>
  </thead>
  <tbody>
      <tr><td>Ana Souza</td><td>Recife</td><td>Ativo</td><td>R$ 1.240,00</td></tr>
      <tr><td>Bruno Lima</td><td>Olinda</td><td>Ativo</td><td>R$ 380,00</td></tr>
      <tr><td>Carla Dias</td><td>Caruaru</td><td>Inativo</td><td>R$ 2.050,00</td></tr>
      <tr><td>Diego Alves</td><td>Recife</td><td>Ativo</td><td>R$ 95,00</td></tr>
      <tr><td>Elisa Ramos</td><td>Petrolina</td><td>Ativo</td><td>R$ 710,00</td></tr>
      <tr><td>Fábio Torres</td><td>Garanhuns</td><td>Inativo</td><td>R$ 1.480,00</td></tr>
      <tr><td>Gabriela Reis</td><td>Recife</td><td>Ativo</td><td>R$ 560,00</td></tr>
      <tr><td>Heitor Nunes</td><td>Olinda</td><td>Ativo</td><td>R$ 3.200,00</td></tr>
  </tbody>
</table>
ClienteCidadeSituaçãoTotal
Ana SouzaRecifeAtivoR$ 1.240,00
Bruno LimaOlindaAtivoR$ 380,00
Carla DiasCaruaruInativoR$ 2.050,00
Diego AlvesRecifeAtivoR$ 95,00
Elisa RamosPetrolinaAtivoR$ 710,00
Fábio TorresGaranhunsInativoR$ 1.480,00
Gabriela ReisRecifeAtivoR$ 560,00
Heitor NunesOlindaAtivoR$ 3.200,00
sw-table-search="false" — sem campo de busca
<table sw-table sw-table-per="5" sw-table-search="false">
  <thead>
    <tr><th>Cliente</th><th>Cidade</th><th>Situação</th><th>Total</th></tr>
  </thead>
  <tbody>
      <tr><td>Ana Souza</td><td>Recife</td><td>Ativo</td><td>R$ 1.240,00</td></tr>
      <tr><td>Bruno Lima</td><td>Olinda</td><td>Ativo</td><td>R$ 380,00</td></tr>
      <tr><td>Carla Dias</td><td>Caruaru</td><td>Inativo</td><td>R$ 2.050,00</td></tr>
      <tr><td>Diego Alves</td><td>Recife</td><td>Ativo</td><td>R$ 95,00</td></tr>
      <tr><td>Elisa Ramos</td><td>Petrolina</td><td>Ativo</td><td>R$ 710,00</td></tr>
      <tr><td>Fábio Torres</td><td>Garanhuns</td><td>Inativo</td><td>R$ 1.480,00</td></tr>
      <tr><td>Gabriela Reis</td><td>Recife</td><td>Ativo</td><td>R$ 560,00</td></tr>
      <tr><td>Heitor Nunes</td><td>Olinda</td><td>Ativo</td><td>R$ 3.200,00</td></tr>
  </tbody>
</table>
ClienteCidadeSituaçãoTotal
Ana SouzaRecifeAtivoR$ 1.240,00
Bruno LimaOlindaAtivoR$ 380,00
Carla DiasCaruaruInativoR$ 2.050,00
Diego AlvesRecifeAtivoR$ 95,00
Elisa RamosPetrolinaAtivoR$ 710,00
Fábio TorresGaranhunsInativoR$ 1.480,00
Gabriela ReisRecifeAtivoR$ 560,00
Heitor NunesOlindaAtivoR$ 3.200,00
sw-table-sort="false" — nenhuma coluna ordena
<table sw-table sw-table-per="5" sw-table-sort="false">
  <thead>
    <tr><th>Cliente</th><th>Cidade</th><th>Situação</th><th>Total</th></tr>
  </thead>
  <tbody>
      <tr><td>Ana Souza</td><td>Recife</td><td>Ativo</td><td>R$ 1.240,00</td></tr>
      <tr><td>Bruno Lima</td><td>Olinda</td><td>Ativo</td><td>R$ 380,00</td></tr>
      <tr><td>Carla Dias</td><td>Caruaru</td><td>Inativo</td><td>R$ 2.050,00</td></tr>
      <tr><td>Diego Alves</td><td>Recife</td><td>Ativo</td><td>R$ 95,00</td></tr>
      <tr><td>Elisa Ramos</td><td>Petrolina</td><td>Ativo</td><td>R$ 710,00</td></tr>
      <tr><td>Fábio Torres</td><td>Garanhuns</td><td>Inativo</td><td>R$ 1.480,00</td></tr>
      <tr><td>Gabriela Reis</td><td>Recife</td><td>Ativo</td><td>R$ 560,00</td></tr>
      <tr><td>Heitor Nunes</td><td>Olinda</td><td>Ativo</td><td>R$ 3.200,00</td></tr>
  </tbody>
</table>
ClienteCidadeSituaçãoTotal
Ana SouzaRecifeAtivoR$ 1.240,00
Bruno LimaOlindaAtivoR$ 380,00
Carla DiasCaruaruInativoR$ 2.050,00
Diego AlvesRecifeAtivoR$ 95,00
Elisa RamosPetrolinaAtivoR$ 710,00
Fábio TorresGaranhunsInativoR$ 1.480,00
Gabriela ReisRecifeAtivoR$ 560,00
Heitor NunesOlindaAtivoR$ 3.200,00
sw-table-stripe="false" — sem zebra
<table sw-table sw-table-per="5" sw-table-stripe="false">
  <thead>
    <tr><th>Cliente</th><th>Cidade</th><th>Situação</th><th>Total</th></tr>
  </thead>
  <tbody>
      <tr><td>Ana Souza</td><td>Recife</td><td>Ativo</td><td>R$ 1.240,00</td></tr>
      <tr><td>Bruno Lima</td><td>Olinda</td><td>Ativo</td><td>R$ 380,00</td></tr>
      <tr><td>Carla Dias</td><td>Caruaru</td><td>Inativo</td><td>R$ 2.050,00</td></tr>
      <tr><td>Diego Alves</td><td>Recife</td><td>Ativo</td><td>R$ 95,00</td></tr>
      <tr><td>Elisa Ramos</td><td>Petrolina</td><td>Ativo</td><td>R$ 710,00</td></tr>
      <tr><td>Fábio Torres</td><td>Garanhuns</td><td>Inativo</td><td>R$ 1.480,00</td></tr>
      <tr><td>Gabriela Reis</td><td>Recife</td><td>Ativo</td><td>R$ 560,00</td></tr>
      <tr><td>Heitor Nunes</td><td>Olinda</td><td>Ativo</td><td>R$ 3.200,00</td></tr>
  </tbody>
</table>
ClienteCidadeSituaçãoTotal
Ana SouzaRecifeAtivoR$ 1.240,00
Bruno LimaOlindaAtivoR$ 380,00
Carla DiasCaruaruInativoR$ 2.050,00
Diego AlvesRecifeAtivoR$ 95,00
Elisa RamosPetrolinaAtivoR$ 710,00
Fábio TorresGaranhunsInativoR$ 1.480,00
Gabriela ReisRecifeAtivoR$ 560,00
Heitor NunesOlindaAtivoR$ 3.200,00
sw-table-nosort no <th> — só "Situação" não ordena
<table sw-table sw-table-per="5">
  <thead>
    <tr><th>Cliente</th><th>Cidade</th><th sw-table-nosort>Situação</th><th>Total</th></tr>
  </thead>
  <tbody>
      <tr><td>Ana Souza</td><td>Recife</td><td>Ativo</td><td>R$ 1.240,00</td></tr>
      <tr><td>Bruno Lima</td><td>Olinda</td><td>Ativo</td><td>R$ 380,00</td></tr>
      <tr><td>Carla Dias</td><td>Caruaru</td><td>Inativo</td><td>R$ 2.050,00</td></tr>
      <tr><td>Diego Alves</td><td>Recife</td><td>Ativo</td><td>R$ 95,00</td></tr>
      <tr><td>Elisa Ramos</td><td>Petrolina</td><td>Ativo</td><td>R$ 710,00</td></tr>
      <tr><td>Fábio Torres</td><td>Garanhuns</td><td>Inativo</td><td>R$ 1.480,00</td></tr>
      <tr><td>Gabriela Reis</td><td>Recife</td><td>Ativo</td><td>R$ 560,00</td></tr>
      <tr><td>Heitor Nunes</td><td>Olinda</td><td>Ativo</td><td>R$ 3.200,00</td></tr>
  </tbody>
</table>

2. Linhas por página

sw-table-per diz quantas linhas aparecem de início (padrão 10). sw-table-per-opts troca as opções do seletor (padrão 10, 25, 50, 100). Se o per não estiver na lista, ele entra sozinho.

ClienteCidadeSituaçãoTotal
Ana SouzaRecifeAtivoR$ 1.240,00
Bruno LimaOlindaAtivoR$ 380,00
Carla DiasCaruaruInativoR$ 2.050,00
Diego AlvesRecifeAtivoR$ 95,00
Elisa RamosPetrolinaAtivoR$ 710,00
Fábio TorresGaranhunsInativoR$ 1.480,00
Gabriela ReisRecifeAtivoR$ 560,00
Heitor NunesOlindaAtivoR$ 3.200,00
sw-table-per="3" sw-table-per-opts="3,5,8"
<table sw-table sw-table-per="3" sw-table-per-opts="3,5,8">
  <thead>
    <tr><th>Cliente</th><th>Cidade</th><th>Situação</th><th>Total</th></tr>
  </thead>
  <tbody>
      <tr><td>Ana Souza</td><td>Recife</td><td>Ativo</td><td>R$ 1.240,00</td></tr>
      <tr><td>Bruno Lima</td><td>Olinda</td><td>Ativo</td><td>R$ 380,00</td></tr>
      <tr><td>Carla Dias</td><td>Caruaru</td><td>Inativo</td><td>R$ 2.050,00</td></tr>
      <tr><td>Diego Alves</td><td>Recife</td><td>Ativo</td><td>R$ 95,00</td></tr>
      <tr><td>Elisa Ramos</td><td>Petrolina</td><td>Ativo</td><td>R$ 710,00</td></tr>
      <tr><td>Fábio Torres</td><td>Garanhuns</td><td>Inativo</td><td>R$ 1.480,00</td></tr>
      <tr><td>Gabriela Reis</td><td>Recife</td><td>Ativo</td><td>R$ 560,00</td></tr>
      <tr><td>Heitor Nunes</td><td>Olinda</td><td>Ativo</td><td>R$ 3.200,00</td></tr>
  </tbody>
</table>

3. Botões extras: exportar, copiar, imprimir, colunas

Aparecem ao lado do seletor de linhas. Exportar e imprimir levam todas as linhas filtradas (não só a página atual) e só as colunas visíveis. O CSV sai com acentos certos para abrir no Excel.

ClienteCidadeSituaçãoTotal
Ana SouzaRecifeAtivoR$ 1.240,00
Bruno LimaOlindaAtivoR$ 380,00
Carla DiasCaruaruInativoR$ 2.050,00
Diego AlvesRecifeAtivoR$ 95,00
Elisa RamosPetrolinaAtivoR$ 710,00
Fábio TorresGaranhunsInativoR$ 1.480,00
Gabriela ReisRecifeAtivoR$ 560,00
Heitor NunesOlindaAtivoR$ 3.200,00
sw-table-export="csv" — baixa tabela.csv
<table sw-table sw-table-per="4" sw-table-export="csv">
  <thead>
    <tr><th>Cliente</th><th>Cidade</th><th>Situação</th><th>Total</th></tr>
  </thead>
  <tbody>
      <tr><td>Ana Souza</td><td>Recife</td><td>Ativo</td><td>R$ 1.240,00</td></tr>
      <tr><td>Bruno Lima</td><td>Olinda</td><td>Ativo</td><td>R$ 380,00</td></tr>
      <tr><td>Carla Dias</td><td>Caruaru</td><td>Inativo</td><td>R$ 2.050,00</td></tr>
      <tr><td>Diego Alves</td><td>Recife</td><td>Ativo</td><td>R$ 95,00</td></tr>
      <tr><td>Elisa Ramos</td><td>Petrolina</td><td>Ativo</td><td>R$ 710,00</td></tr>
      <tr><td>Fábio Torres</td><td>Garanhuns</td><td>Inativo</td><td>R$ 1.480,00</td></tr>
      <tr><td>Gabriela Reis</td><td>Recife</td><td>Ativo</td><td>R$ 560,00</td></tr>
      <tr><td>Heitor Nunes</td><td>Olinda</td><td>Ativo</td><td>R$ 3.200,00</td></tr>
  </tbody>
</table>
ClienteCidadeSituaçãoTotal
Ana SouzaRecifeAtivoR$ 1.240,00
Bruno LimaOlindaAtivoR$ 380,00
Carla DiasCaruaruInativoR$ 2.050,00
Diego AlvesRecifeAtivoR$ 95,00
Elisa RamosPetrolinaAtivoR$ 710,00
Fábio TorresGaranhunsInativoR$ 1.480,00
Gabriela ReisRecifeAtivoR$ 560,00
Heitor NunesOlindaAtivoR$ 3.200,00
sw-table-export="csv,copy" — CSV + copiar para colar na planilha
<table sw-table sw-table-per="4" sw-table-export="csv,copy">
  <thead>
    <tr><th>Cliente</th><th>Cidade</th><th>Situação</th><th>Total</th></tr>
  </thead>
  <tbody>
      <tr><td>Ana Souza</td><td>Recife</td><td>Ativo</td><td>R$ 1.240,00</td></tr>
      <tr><td>Bruno Lima</td><td>Olinda</td><td>Ativo</td><td>R$ 380,00</td></tr>
      <tr><td>Carla Dias</td><td>Caruaru</td><td>Inativo</td><td>R$ 2.050,00</td></tr>
      <tr><td>Diego Alves</td><td>Recife</td><td>Ativo</td><td>R$ 95,00</td></tr>
      <tr><td>Elisa Ramos</td><td>Petrolina</td><td>Ativo</td><td>R$ 710,00</td></tr>
      <tr><td>Fábio Torres</td><td>Garanhuns</td><td>Inativo</td><td>R$ 1.480,00</td></tr>
      <tr><td>Gabriela Reis</td><td>Recife</td><td>Ativo</td><td>R$ 560,00</td></tr>
      <tr><td>Heitor Nunes</td><td>Olinda</td><td>Ativo</td><td>R$ 3.200,00</td></tr>
  </tbody>
</table>
ClienteCidadeSituaçãoTotal
Ana SouzaRecifeAtivoR$ 1.240,00
Bruno LimaOlindaAtivoR$ 380,00
Carla DiasCaruaruInativoR$ 2.050,00
Diego AlvesRecifeAtivoR$ 95,00
Elisa RamosPetrolinaAtivoR$ 710,00
Fábio TorresGaranhunsInativoR$ 1.480,00
Gabriela ReisRecifeAtivoR$ 560,00
Heitor NunesOlindaAtivoR$ 3.200,00
sw-table-print — botão de imprimir
<table sw-table sw-table-per="4" sw-table-print>
  <thead>
    <tr><th>Cliente</th><th>Cidade</th><th>Situação</th><th>Total</th></tr>
  </thead>
  <tbody>
      <tr><td>Ana Souza</td><td>Recife</td><td>Ativo</td><td>R$ 1.240,00</td></tr>
      <tr><td>Bruno Lima</td><td>Olinda</td><td>Ativo</td><td>R$ 380,00</td></tr>
      <tr><td>Carla Dias</td><td>Caruaru</td><td>Inativo</td><td>R$ 2.050,00</td></tr>
      <tr><td>Diego Alves</td><td>Recife</td><td>Ativo</td><td>R$ 95,00</td></tr>
      <tr><td>Elisa Ramos</td><td>Petrolina</td><td>Ativo</td><td>R$ 710,00</td></tr>
      <tr><td>Fábio Torres</td><td>Garanhuns</td><td>Inativo</td><td>R$ 1.480,00</td></tr>
      <tr><td>Gabriela Reis</td><td>Recife</td><td>Ativo</td><td>R$ 560,00</td></tr>
      <tr><td>Heitor Nunes</td><td>Olinda</td><td>Ativo</td><td>R$ 3.200,00</td></tr>
  </tbody>
</table>
ClienteCidadeSituaçãoTotal
Ana SouzaRecifeAtivoR$ 1.240,00
Bruno LimaOlindaAtivoR$ 380,00
Carla DiasCaruaruInativoR$ 2.050,00
Diego AlvesRecifeAtivoR$ 95,00
Elisa RamosPetrolinaAtivoR$ 710,00
Fábio TorresGaranhunsInativoR$ 1.480,00
Gabriela ReisRecifeAtivoR$ 560,00
Heitor NunesOlindaAtivoR$ 3.200,00
sw-table-colvis — menu para esconder colunas ("Total" fora do menu com sw-table-novis)
<table sw-table sw-table-per="4" sw-table-colvis>
  <thead>
    <tr><th>Cliente</th><th>Cidade</th><th>Situação</th><th sw-table-novis>Total</th></tr>
  </thead>
  <tbody>
      <tr><td>Ana Souza</td><td>Recife</td><td>Ativo</td><td>R$ 1.240,00</td></tr>
      <tr><td>Bruno Lima</td><td>Olinda</td><td>Ativo</td><td>R$ 380,00</td></tr>
      <tr><td>Carla Dias</td><td>Caruaru</td><td>Inativo</td><td>R$ 2.050,00</td></tr>
      <tr><td>Diego Alves</td><td>Recife</td><td>Ativo</td><td>R$ 95,00</td></tr>
      <tr><td>Elisa Ramos</td><td>Petrolina</td><td>Ativo</td><td>R$ 710,00</td></tr>
      <tr><td>Fábio Torres</td><td>Garanhuns</td><td>Inativo</td><td>R$ 1.480,00</td></tr>
      <tr><td>Gabriela Reis</td><td>Recife</td><td>Ativo</td><td>R$ 560,00</td></tr>
      <tr><td>Heitor Nunes</td><td>Olinda</td><td>Ativo</td><td>R$ 3.200,00</td></tr>
  </tbody>
</table>

4. Marcar linhas

sw-table-select põe uma caixinha em cada linha e uma no título para marcar todas da página. O rodapé mostra quantas estão marcadas, e o evento sw:table:select avisa o seu código.

ClienteCidadeSituaçãoTotal
Ana SouzaRecifeAtivoR$ 1.240,00
Bruno LimaOlindaAtivoR$ 380,00
Carla DiasCaruaruInativoR$ 2.050,00
Diego AlvesRecifeAtivoR$ 95,00
Elisa RamosPetrolinaAtivoR$ 710,00
Fábio TorresGaranhunsInativoR$ 1.480,00
Gabriela ReisRecifeAtivoR$ 560,00
Heitor NunesOlindaAtivoR$ 3.200,00
sw-table-select
<table sw-table sw-table-per="5" sw-table-select>
  <thead>
    <tr><th>Cliente</th><th>Cidade</th><th>Situação</th><th>Total</th></tr>
  </thead>
  <tbody>
      <tr><td>Ana Souza</td><td>Recife</td><td>Ativo</td><td>R$ 1.240,00</td></tr>
      <tr><td>Bruno Lima</td><td>Olinda</td><td>Ativo</td><td>R$ 380,00</td></tr>
      <tr><td>Carla Dias</td><td>Caruaru</td><td>Inativo</td><td>R$ 2.050,00</td></tr>
      <tr><td>Diego Alves</td><td>Recife</td><td>Ativo</td><td>R$ 95,00</td></tr>
      <tr><td>Elisa Ramos</td><td>Petrolina</td><td>Ativo</td><td>R$ 710,00</td></tr>
      <tr><td>Fábio Torres</td><td>Garanhuns</td><td>Inativo</td><td>R$ 1.480,00</td></tr>
      <tr><td>Gabriela Reis</td><td>Recife</td><td>Ativo</td><td>R$ 560,00</td></tr>
      <tr><td>Heitor Nunes</td><td>Olinda</td><td>Ativo</td><td>R$ 3.200,00</td></tr>
  </tbody>
</table>

5. No celular: vira lista que abre

Com sw-table-collapse, quando a caixa da tabela (não a tela) fica mais estreita que o número informado (padrão 680 px), só a primeira coluna aparece, com uma setinha; tocar na linha abre o resto empilhado. O quadro da esquerda é estreito e já está no modo celular; o largo, com o mesmo código, mostra a tabela inteira.

ClienteCidadeSituaçãoTotal
Ana SouzaRecifeAtivoR$ 1.240,00
Bruno LimaOlindaAtivoR$ 380,00
Carla DiasCaruaruInativoR$ 2.050,00
Diego AlvesRecifeAtivoR$ 95,00
Elisa RamosPetrolinaAtivoR$ 710,00
Fábio TorresGaranhunsInativoR$ 1.480,00
Gabriela ReisRecifeAtivoR$ 560,00
Heitor NunesOlindaAtivoR$ 3.200,00
Caixa estreita — sw-table-collapse (toque na linha) <table sw-table sw-table-per="4" sw-table-collapse sw-table-search="false"> <thead> <tr><th>Cliente</th><th>Cidade</th><th>Situação</th><th>Total</th></tr> </thead> <tbody> <tr><td>Ana Souza</td><td>Recife</td><td>Ativo</td><td>R$ 1.240,00</td></tr> <tr><td>Bruno Lima</td><td>Olinda</td><td>Ativo</td><td>R$ 380,00</td></tr> <tr><td>Carla Dias</td><td>Caruaru</td><td>Inativo</td><td>R$ 2.050,00</td></tr> <tr><td>Diego Alves</td><td>Recife</td><td>Ativo</td><td>R$ 95,00</td></tr> <tr><td>Elisa Ramos</td><td>Petrolina</td><td>Ativo</td><td>R$ 710,00</td></tr> <tr><td>Fábio Torres</td><td>Garanhuns</td><td>Inativo</td><td>R$ 1.480,00</td></tr> <tr><td>Gabriela Reis</td><td>Recife</td><td>Ativo</td><td>R$ 560,00</td></tr> <tr><td>Heitor Nunes</td><td>Olinda</td><td>Ativo</td><td>R$ 3.200,00</td></tr> </tbody> </table>
ClienteCidadeSituaçãoTotal
Ana SouzaRecifeAtivoR$ 1.240,00
Bruno LimaOlindaAtivoR$ 380,00
Carla DiasCaruaruInativoR$ 2.050,00
Diego AlvesRecifeAtivoR$ 95,00
Elisa RamosPetrolinaAtivoR$ 710,00
Fábio TorresGaranhunsInativoR$ 1.480,00
Gabriela ReisRecifeAtivoR$ 560,00
Heitor NunesOlindaAtivoR$ 3.200,00
Caixa larga — mesmo código, tabela inteira
<table sw-table sw-table-per="4" sw-table-collapse sw-table-search="false">
  <thead>
    <tr><th>Cliente</th><th>Cidade</th><th>Situação</th><th>Total</th></tr>
  </thead>
  <tbody>
      <tr><td>Ana Souza</td><td>Recife</td><td>Ativo</td><td>R$ 1.240,00</td></tr>
      <tr><td>Bruno Lima</td><td>Olinda</td><td>Ativo</td><td>R$ 380,00</td></tr>
      <tr><td>Carla Dias</td><td>Caruaru</td><td>Inativo</td><td>R$ 2.050,00</td></tr>
      <tr><td>Diego Alves</td><td>Recife</td><td>Ativo</td><td>R$ 95,00</td></tr>
      <tr><td>Elisa Ramos</td><td>Petrolina</td><td>Ativo</td><td>R$ 710,00</td></tr>
      <tr><td>Fábio Torres</td><td>Garanhuns</td><td>Inativo</td><td>R$ 1.480,00</td></tr>
      <tr><td>Gabriela Reis</td><td>Recife</td><td>Ativo</td><td>R$ 560,00</td></tr>
      <tr><td>Heitor Nunes</td><td>Olinda</td><td>Ativo</td><td>R$ 3.200,00</td></tr>
  </tbody>
</table>

6. Lembrar como a pessoa deixou

sw-table-state guarda no navegador a busca, a ordem, as linhas por página e as colunas escondidas. A pessoa sai, volta, e encontra do mesmo jeito. Dê um id à tabela: é ele que separa a memória de uma tabela da outra na mesma página.

ClienteCidadeSituaçãoTotal
Ana SouzaRecifeAtivoR$ 1.240,00
Bruno LimaOlindaAtivoR$ 380,00
Carla DiasCaruaruInativoR$ 2.050,00
Diego AlvesRecifeAtivoR$ 95,00
Elisa RamosPetrolinaAtivoR$ 710,00
Fábio TorresGaranhunsInativoR$ 1.480,00
Gabriela ReisRecifeAtivoR$ 560,00
Heitor NunesOlindaAtivoR$ 3.200,00
sw-table-state + id — ordene, recarregue a página e veja
<table sw-table id="tbl-demo-estado" sw-table-per="4" sw-table-state>
  <thead>
    <tr><th>Cliente</th><th>Cidade</th><th>Situação</th><th>Total</th></tr>
  </thead>
  <tbody>
      <tr><td>Ana Souza</td><td>Recife</td><td>Ativo</td><td>R$ 1.240,00</td></tr>
      <tr><td>Bruno Lima</td><td>Olinda</td><td>Ativo</td><td>R$ 380,00</td></tr>
      <tr><td>Carla Dias</td><td>Caruaru</td><td>Inativo</td><td>R$ 2.050,00</td></tr>
      <tr><td>Diego Alves</td><td>Recife</td><td>Ativo</td><td>R$ 95,00</td></tr>
      <tr><td>Elisa Ramos</td><td>Petrolina</td><td>Ativo</td><td>R$ 710,00</td></tr>
      <tr><td>Fábio Torres</td><td>Garanhuns</td><td>Inativo</td><td>R$ 1.480,00</td></tr>
      <tr><td>Gabriela Reis</td><td>Recife</td><td>Ativo</td><td>R$ 560,00</td></tr>
      <tr><td>Heitor Nunes</td><td>Olinda</td><td>Ativo</td><td>R$ 3.200,00</td></tr>
  </tbody>
</table>

Tabela de opções

PalavraO que fazExemplo
Ligar a tabela
sw-tableNa <table>. Liga tudo. A tabela precisa ter <thead> e <tbody>.<table sw-table>
Recursos que já vêm ligados (desligue com "false")
sw-table-searchCampo de busca. Procura o texto em todas as colunas.sw-table-search="false"
sw-table-sortOrdenar clicando no título (também pelo teclado: Tab + Enter).sw-table-sort="false"
sw-table-stripeLinhas alternadas (zebra).sw-table-stripe="false"
Paginação
sw-table-perLinhas por página. Padrão: 10.sw-table-per="25"
sw-table-per-optsOpções do seletor de linhas. Padrão: 10,25,50,100.sw-table-per-opts="5,10,20"
Botões extras
sw-table-export="csv"Botão que baixa tabela.csv (abre no Excel com acento certo).sw-table-export="csv"
sw-table-export="copy"Botão que copia as linhas para colar numa planilha. Combine: "csv,copy".sw-table-export="csv,copy"
sw-table-printBotão de imprimir (imprime todas as linhas filtradas, não só a página).sw-table-print
sw-table-colvisMenu para mostrar/esconder colunas.sw-table-colvis
sw-table-selectCaixinha para marcar linhas + "marcar todas".sw-table-select
Celular e memória
sw-table-collapseAbaixo desta largura da caixa, vira lista que abre. Sem número: 680.sw-table-collapse="760"
sw-table-stateLembra busca, ordem, linhas por página e colunas escondidas (no navegador da pessoa). Use com id.<table sw-table id="clientes" sw-table-state>
No título da coluna (<th>)
sw-table-nosortEssa coluna não ordena (ex.: coluna de ações).<th sw-table-nosort>Ações</th>
sw-table-novisEssa coluna não aparece no menu de colunas (não pode ser escondida).<th sw-table-novis>ID</th>
Modo servidor (dados vindos do seu back-end)
sw-table-urlEndereço que devolve cada página. A busca, a ordem e a paginação passam a ser do servidor.sw-table-url="/api/clientes"
sw-table-colsJSON com as colunas: label (título) e field (campo do JSON).sw-table-cols='[{"label":"Cliente","field":"nome"}]'
sw-table-ajaxAtalho antigo: sw-table-ajax="/url" é o mesmo que sw-table sw-table-url="/url".sw-table-ajax="/api/clientes"

Receitas prontas — usos reais

Situações que aparecem em quase todo site. Copie a que servir.

Painel: lista de pedidos com ações por linha Ao vivo
PedidoClienteValorAções
#1042Ana Souza349,00
#1043Bruno Lima129,00
#1044Carla Dias1899,00
<table sw-table sw-table-per="5" sw-table-export="csv">
  <thead>
    <tr><th>Pedido</th><th>Cliente</th><th>Valor</th><th sw-table-nosort>Ações</th></tr>
  </thead>
  <tbody>
    <tr><td>#1042</td><td>Ana Souza</td><td>349,00</td><td><button sw-btn="ghost rnd pp" aria-label="Editar"><i class="swi-edit"></i></button> <button sw-btn="ghost err rnd pp" aria-label="Excluir"><i class="swi-trash"></i></button></td></tr>
    <tr><td>#1043</td><td>Bruno Lima</td><td>129,00</td><td><button sw-btn="ghost rnd pp" aria-label="Editar"><i class="swi-edit"></i></button> <button sw-btn="ghost err rnd pp" aria-label="Excluir"><i class="swi-trash"></i></button></td></tr>
    <tr><td>#1044</td><td>Carla Dias</td><td>1899,00</td><td><button sw-btn="ghost rnd pp" aria-label="Editar"><i class="swi-edit"></i></button> <button sw-btn="ghost err rnd pp" aria-label="Excluir"><i class="swi-trash"></i></button></td></tr>
  </tbody>
</table>
Ações em lote com as linhas marcadas Ao vivo
ClienteCidadeSituaçãoTotal
Ana SouzaRecifeAtivoR$ 1.240,00
Bruno LimaOlindaAtivoR$ 380,00
Carla DiasCaruaruInativoR$ 2.050,00
Diego AlvesRecifeAtivoR$ 95,00
Elisa RamosPetrolinaAtivoR$ 710,00

Marque linhas para ver o que o evento traz.

<table sw-table id="clientes" sw-table-select>…</table>

<script>
  document.getElementById('clientes').addEventListener('sw:table:select', (e) => {
    // e.detail.selected = linhas marcadas, pela posição na lista original do HTML
    // (0 = primeira) — não muda quando a pessoa busca ou ordena
    console.log(e.detail.selected);
  });
</script>
Montar a tabela com dados do JavaScript Ao vivo
<table id="produtos"></table>

<script>
  SW.Table.fromData(
    '#produtos',                                               // a tabela (ou o elemento)
    ['Produto', 'Estoque', { label: 'Obs.', nosort: true }],   // colunas
    [                                                          // linhas
      ['Café 500g', 42, 'Torra média'],
      ['Café 1kg', 18, 'Torra escura'],
      ['Filtro de papel', 120, '']
    ],
    { per: 10, export: 'csv' }                                 // opcional: vira sw-table-per, sw-table-export…
  );
  // chamar de novo com outras linhas substitui o conteúdo
</script>
Modo servidor: milhares de linhas vindas do banco Referência
<table sw-table
       sw-table-url="/api/clientes"
       sw-table-per="25"
       sw-table-cols='[{"label":"Cliente","field":"nome"},{"label":"Cidade","field":"cidade"}]'>
</table>

<!-- A cada busca, ordem ou troca de página, a tabela chama:
     /api/clientes?page=1&per=25&search=ana&sort=nome&dir=asc
     (sort = o "field" da coluna clicada; search já vem em minúsculas)

     O seu servidor responde JSON num destes formatos:
     { "data": [ {"nome":"Ana","cidade":"Recife"} ], "total": 1840, "filtered": 12 }
     [ {"nome":"Ana","cidade":"Recife"} ]                 (sem total: conta as linhas que vieram)
     { "html": "<tr><td>Ana</td><td>Recife</td></tr>", "total": 1840, "filtered": 12 }

     "total" = quantos existem; "filtered" = quantos batem com a busca.
     Sem sw-table-cols, as colunas são as chaves do 1º registro. -->

Eventos

sw:table:search
A pessoa buscou algo. Traz e.detail.query (em minúsculas).
sw:table:sort
Ordenou por uma coluna. Traz e.detail.col (posição, começa em 0) e e.detail.dir ("asc" ou "desc").
sw:table:page
Trocou de página. Traz e.detail.page (começa em 1).
sw:table:select
Marcou ou desmarcou linhas. Traz e.detail.selected: a posição de cada linha marcada na lista original do HTML (0 = primeira). Buscar ou ordenar não muda essas posições.

API (JavaScript)

SW.Table.search(el, "texto")
Busca por código (preenche o campo de busca também).
SW.Table.reload(el)
Refaz a busca/ordem atual; no modo servidor, pede a página de novo.
SW.Table.export(el, "csv")
Exporta por código ("csv" baixa o arquivo, "copy" copia).
SW.Table.fromData(el, colunas, linhas, opções?)
Monta (ou remonta) a tabela a partir de listas do JavaScript. el pode ser o elemento ou um seletor como "#produtos".

Precisa de quê

  • swcore.min.css e swcore.min.js.
  • swcore.compl.min.css para os ícones da busca e dos botões extras.
  • Tabela com <thead> (títulos) e <tbody> (linhas).
  • Modo servidor: um endereço no seu back-end que responda JSON no formato mostrado na receita.

Cuidados — erros comuns

  • Tabela sem <thead>/<tbody>: o script não acha as linhas e a tabela fica vazia.
  • Valor com "R$" ou ponto de milhar ("R$ 1.240,00") ordena como texto, não como número. Para ordenar certo, deixe o número puro na célula ("1240.00") ou comece a célula pelo número.
  • Coluna de botões (editar/excluir) ordenável não faz sentido: coloque sw-table-nosort no <th> dela.
  • sw-table-state em duas tabelas sem id na mesma página: elas dividem a mesma memória. Dê um id para cada.
  • Chamar SWTable.reload(...): o nome certo é SW.Table.reload(...).
  • Esperar que a paginação do navegador aguente 10 mil linhas: todas vão no HTML e pesam. Acima de algumas centenas, use o modo servidor.

O que ele não faz

  • Sem sw-table-url, busca/ordem/paginação são feitas com as linhas que já estão no HTML — não busca nada no servidor.
  • Não edita células: é para listar. Para editar, abra um formulário (ex.: num Modal) a partir de um botão da linha.
  • No modo servidor, o menu de colunas (sw-table-colvis) não lista as colunas, e a ordenação só usa colunas com field em sw-table-cols.