199 lines
7.6 KiB
JavaScript
199 lines
7.6 KiB
JavaScript
/* global JSINFO */
|
|
|
|
/**
|
|
* DokuWiki DataTables Plugins
|
|
*
|
|
* Home http://dokuwiki.org/template:bootstrap3
|
|
* Author Giuseppe Di Terlizzi <giuseppe.diterlizzi@gmail.com>
|
|
* License GPL 2 (http://www.gnu.org/licenses/gpl.html)
|
|
* Copyright (C) 2015-2020, Giuseppe Di Terlizzi
|
|
*/
|
|
jQuery(document).ready(function () {
|
|
|
|
const WRAP_TABLES_SELECTOR = '.page div.dt-wrapper table';
|
|
const ALL_TABLES_SELECTOR = '.page table thead';
|
|
|
|
/**
|
|
* Initialize DataTables on the given table
|
|
*
|
|
* @param {jQuery} $target_table
|
|
* @param {object} dt_config DataTable configuration
|
|
*/
|
|
function init_datatables($target_table, dt_config) {
|
|
console.debug(dt_config);
|
|
|
|
// adjust header rows if requested
|
|
let headerRows = dt_config.headerRows;
|
|
if (headerRows) {
|
|
const $tbody = jQuery('tbody', $target_table);
|
|
|
|
// if table heade ismissing, create it
|
|
let $thead = jQuery('thead', $target_table);
|
|
if ($thead.length === 0) {
|
|
$thead = jQuery('<thead>');
|
|
$target_table.prepend($thead);
|
|
}
|
|
|
|
// move the first rows from tbody to thead
|
|
headerRows -= $thead.children().length;
|
|
while (headerRows > 0) {
|
|
headerRows--;
|
|
$thead.append($tbody.children().first());
|
|
}
|
|
}
|
|
|
|
// initialize, unless there are colspans or rowspans
|
|
if (
|
|
jQuery('thead > tr', $target_table).length &&
|
|
!jQuery('tbody', $target_table).find('[rowspan], [colspan]').length
|
|
) {
|
|
$target_table.attr('width', '100%');
|
|
const table = $target_table.DataTable(dt_config);
|
|
|
|
// Add column filters if enabled
|
|
if (JSINFO.plugin.datatables.enableColumnFilters) {
|
|
addColumnFilters(table, $target_table);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Add column filters to DataTable
|
|
*
|
|
* @param {DataTable} table DataTable instance
|
|
* @param {jQuery} $target_table Table jQuery object
|
|
*/
|
|
function addColumnFilters(table, $target_table) {
|
|
const position = JSINFO.plugin.datatables.columnFiltersPosition || 'header';
|
|
const $thead = $target_table.find('thead');
|
|
|
|
// Create filter row
|
|
const $filterRow = jQuery('<tr class="dt-column-filters"></tr>');
|
|
|
|
// Add filter for each column
|
|
table.columns().every(function(index) {
|
|
const column = this;
|
|
const $th = jQuery('<th></th>');
|
|
|
|
// Create container for input and select
|
|
const $filterContainer = jQuery('<div class="dt-filter-container"></div>');
|
|
|
|
// Create search input for filtering dropdown options
|
|
const $searchInput = jQuery('<input type="text" class="dt-filter-search" placeholder="Suchen..." />');
|
|
|
|
// Create select dropdown
|
|
const $select = jQuery('<select class="dt-filter-select"><option value="">Alle anzeigen</option></select>');
|
|
|
|
// Get unique values from column
|
|
const uniqueValues = [];
|
|
const uniqueTexts = new Set();
|
|
|
|
column.data().each(function(d) {
|
|
if (d) {
|
|
// Extract text content if it contains HTML
|
|
const text = jQuery('<div>').html(d).text().trim();
|
|
if (text && !uniqueTexts.has(text)) {
|
|
uniqueTexts.add(text);
|
|
uniqueValues.push(text);
|
|
}
|
|
}
|
|
});
|
|
|
|
// Sort unique values
|
|
uniqueValues.sort();
|
|
|
|
// Populate select with unique values
|
|
uniqueValues.forEach(function(value) {
|
|
$select.append('<option value="' + jQuery('<div>').text(value).html() + '">' + value + '</option>');
|
|
});
|
|
|
|
// Filter dropdown options AND table based on search input
|
|
$searchInput.on('keyup', function() {
|
|
const searchTerm = jQuery(this).val();
|
|
|
|
// Filter dropdown options
|
|
const searchTermLower = searchTerm.toLowerCase();
|
|
$select.find('option').each(function() {
|
|
const optionText = jQuery(this).text().toLowerCase();
|
|
if (optionText.indexOf(searchTermLower) > -1 || jQuery(this).val() === '') {
|
|
jQuery(this).show();
|
|
} else {
|
|
jQuery(this).hide();
|
|
}
|
|
});
|
|
|
|
// Filter table column
|
|
if (searchTerm) {
|
|
const escapedVal = searchTerm.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
column.search(escapedVal, true, false).draw();
|
|
} else {
|
|
column.search('').draw();
|
|
}
|
|
|
|
// Reset dropdown selection when typing
|
|
$select.val('');
|
|
});
|
|
|
|
// Filter table when dropdown changes
|
|
$select.on('change', function() {
|
|
const val = jQuery(this).val();
|
|
if (val) {
|
|
// Escape special regex characters and search for exact match
|
|
const escapedVal = val.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
// Search using regex that matches the text anywhere in the cell
|
|
column.search(escapedVal, true, false).draw();
|
|
} else {
|
|
// Clear search
|
|
column.search('').draw();
|
|
}
|
|
});
|
|
|
|
// Add elements to container
|
|
$filterContainer.append($searchInput);
|
|
$filterContainer.append($select);
|
|
$th.append($filterContainer);
|
|
$filterRow.append($th);
|
|
});
|
|
|
|
// Add filter row to table
|
|
if (position === 'header') {
|
|
$thead.append($filterRow);
|
|
} else {
|
|
// Create tfoot if it doesn't exist
|
|
let $tfoot = $target_table.find('tfoot');
|
|
if ($tfoot.length === 0) {
|
|
$tfoot = jQuery('<tfoot></tfoot>');
|
|
$target_table.append($tfoot);
|
|
}
|
|
$tfoot.append($filterRow);
|
|
}
|
|
}
|
|
|
|
// MAIN
|
|
|
|
// check if plugin is configured
|
|
if (!('plugin' in JSINFO) || !('datatables' in JSINFO.plugin)) return;
|
|
|
|
// initialize on all tables, unless they have our wrapper (using default config)
|
|
if (JSINFO.plugin.datatables.enableForAllTables) {
|
|
jQuery(ALL_TABLES_SELECTOR).each(function () {
|
|
const $target_table = jQuery(this).parent();
|
|
|
|
if (!$target_table.parents('.dt-wrapper').length) {
|
|
init_datatables($target_table, JSINFO.plugin.datatables.config);
|
|
}
|
|
});
|
|
}
|
|
|
|
// initialize on all tables with our wrapper (using default config + wrapper config)
|
|
const $wrap_tables = jQuery(WRAP_TABLES_SELECTOR);
|
|
if ($wrap_tables.length) {
|
|
$wrap_tables.each(function () {
|
|
const $target_table = jQuery(this);
|
|
const wrap_config = jQuery(this).parents('.dt-wrapper').data();
|
|
const dt_config = jQuery.extend(JSINFO.plugin.datatables.config, wrap_config);
|
|
init_datatables($target_table, dt_config);
|
|
});
|
|
}
|
|
});
|