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>
60 lines
2.4 KiB
JavaScript
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 || {}));
|
|
}
|