MediaWiki:CustomFiltered.js
From The Seven Sages of Rome
Note: After publishing, you may have to bypass your browser's cache to see the changes.
- Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
- Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
- Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5.
(function ($) {
function init() {
var $container = $('.filtered-views-container');
if (!$container.length) return;
var $bar = $('<div>', {
id: 'smw-filter-bar',
css: { marginBottom: '10px', display: 'flex', gap: '16px', alignItems: 'center', flexWrap: 'wrap' }
});
var $searchInput = $('<input>', {
type: 'text',
id: 'smw-search-input',
placeholder: 'Search all columns…',
css: { padding: '5px 10px', fontSize: '14px', border: '1px solid #ccc', borderRadius: '4px', minWidth: '250px' }
});
var $counter = $('<span>', {
id: 'smw-filter-counter',
css: { fontSize: '14px', color: '#555' }
});
$bar.append($searchInput, $counter);
$container.before($bar);
// Track whether SMW is currently changing things, not us
var smwChanging = false;
function snapshotSMW() {
$container.find('tr.filtered-table-item').each(function () {
// Temporarily show the row to read SMW's intended state
// SMW stores its hidden state via inline style directly
var inlineDisplay = this.style.display;
$(this).data('smw-hidden', inlineDisplay === 'none');
});
}
function applySearch() {
var term = $.trim($searchInput.val()).toLowerCase();
var total = 0;
var visible = 0;
$container.find('tr.filtered-table-item').each(function () {
var $row = $(this);
total++;
if ($row.data('smw-hidden')) {
$row.hide();
return;
}
if (!term || $row.text().toLowerCase().indexOf(term) !== -1) {
$row.show();
visible++;
} else {
$row.hide();
}
});
$counter.text('Showing ' + visible + ' of ' + total + ' entries');
}
// Use a flag + timeout approach: when mutations fire, set a flag,
// wait a tick for all SMW batch changes to settle, then snapshot + apply
var smwTimer = null;
var observing = true;
var observer = new MutationObserver(function (mutations) {
// Check if any mutation came from a filtered-table-item row
// If yes, it's SMW changing things — snapshot after it settles
var smwMutation = mutations.some(function (m) {
return $(m.target).hasClass('filtered-table-item');
});
if (!smwMutation) return;
clearTimeout(smwTimer);
smwTimer = setTimeout(function () {
snapshotSMW();
applySearch();
}, 50);
});
observer.observe($container[0], {
subtree: true,
attributes: true,
attributeFilter: ['style']
});
$searchInput.on('input', function () {
applySearch();
});
snapshotSMW();
applySearch();
}
$(document).ready(function () {
init();
});
}(jQuery));