Files
fitme3070.pt/assets/js/datatables-init.js
T
andreandClaude Sonnet 5 b1e88781b8 feat(backoffice): DataTables cliente-only nas 11 listagens com CSV
Fecha o item 6.9 da auditoria (sem server-side/AJAX — todas as tabelas
estão bem abaixo de 60 linhas): ordenação, pesquisa, paginação, pt-PT
e Responsive (colapso em ecrãs estreitos), reaproveitando o botão
"Exportar CSV" já existente.

DataTables 2.3.4 + Responsive 3.0.6 vendorizados em
assets/vendor/datatables-2.3.4/ (mesma versão/decisão do hub.andmore.pt),
nunca de CDN. Tradução pt-PT oficial inline em assets/js/datatables-init.js,
que expõe initDataTable(selector, opts) — cada página dá um id estável à
tabela e marca a coluna de Ações como orderable:false/searchable:false.
Os vendor scripts só carregam nas 10 páginas que os usam (injeção dinâmica
depois do DOMContentLoaded, como o loader do Summernote), não no
header/footer partilhado.

views/admin/trials/index.php ficou de fora de propósito: cada linha tem
um <select> de estado e um <textarea> de notas editados in-line antes de
"Guardar" — um redraw da DataTable a meio dessa edição (ordenar, paginar)
arrisca perder ou baralhar o que ainda não foi submetido.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-26 10:34:09 +01:00

60 lines
2.4 KiB
JavaScript

// DataTables (classic jQuery plugin) init, partilhado pelas listagens do
// backoffice que já tinham exportação CSV (audit 6.9). Cliente-only — todas
// as tabelas aqui são pequenas (bem abaixo de 60 linhas), por isso sem
// server-side processing nem AJAX.
//
// Tradução pt-PT oficial da DataTables (i18n/pt-PT.json), inline: não se
// carrega de CDN nenhum, pela mesma razão que o Roboto e o FontAwesome
// passaram a ser servidos daqui (RGPD — sem pedidos a terceiros antes do
// consentimento).
var DATATABLES_PT_PT = {
decimal: ',',
emptyTable: 'Não existem dados disponíveis na tabela',
info: 'A mostrar registos de _START_ até _END_ de um total de _TOTAL_ registos',
infoEmpty: 'A mostrar registos de 0 até 0 de um total de 0 registos',
infoFiltered: '(filtrados de um total de _MAX_ registos)',
infoPostFix: '',
thousands: '.',
lengthMenu: 'Mostrar _MENU_ registos',
loadingRecords: 'A carregar...',
processing: 'A processar...',
search: 'Pesquisar:',
zeroRecords: 'Não foram encontrados resultados',
paginate: {
first: 'Primeiro',
last: 'Último',
next: 'Seguinte',
previous: 'Anterior'
},
aria: {
sortAscending: ': ativar para ordenar a coluna de forma ascendente',
sortDescending: ': ativar para ordenar a coluna de forma descendente'
},
select: {
rows: {
_: 'Selecionadas %d linhas',
0: 'Nenhuma linha selecionada',
1: 'Selecionada 1 linha'
}
}
};
// opts pode trazer columnDefs (p.ex. marcar a coluna de Ações como
// orderable:false/searchable:false) e qualquer outra opção da DataTable —
// é feito merge profundo por cima destes valores por omissão.
function initDataTable(selector, opts) {
if (!window.jQuery || !jQuery.fn || !jQuery.fn.DataTable) return null;
var $table = jQuery(selector);
if (!$table.length) return null;
return $table.DataTable(jQuery.extend(true, {
language: DATATABLES_PT_PT,
pageLength: 25,
lengthMenu: [[10, 25, 50, -1], [10, 25, 50, 'Todos']],
responsive: true,
// Sem ordenação inicial: a ordem que a página já desenha (mais
// recente primeiro, ordem manual, etc.) é a que faz sentido por
// omissão — impor uma coluna aqui só a desfazia sem avisar.
order: []
}, opts || {}));
}