MediaWiki:CustomFiltered.js: Difference between revisions
From The Seven Sages of Rome
No edit summary |
No edit summary Tag: Reverted |
||
| Line 24: | Line 24: | ||
$container.before($bar); | $container.before($bar); | ||
var $rows = $container.find('tr.filtered-table-item'); | |||
var | |||
// Use a real HTML attribute (not jQuery .data()) so we can always | |||
// distinguish SMW state from our own display manipulation | |||
function snapshotSMW() { | function snapshotSMW() { | ||
$ | $rows.each(function () { | ||
// | // Read the raw inline style before we touch anything | ||
$(this).attr('data-smw-hidden', this.style.display === 'none' ? '1' : '0'); | |||
$(this). | |||
}); | }); | ||
} | } | ||
| Line 38: | Line 37: | ||
function applySearch() { | function applySearch() { | ||
var term = $.trim($searchInput.val()).toLowerCase(); | var term = $.trim($searchInput.val()).toLowerCase(); | ||
var total = | var total = $rows.length; | ||
var visible = 0; | var visible = 0; | ||
$ | $rows.each(function () { | ||
var $row = $(this); | var $row = $(this); | ||
if ($row. | if ($row.attr('data-smw-hidden') === '1') { | ||
// Restore SMW's hidden state without triggering observer | |||
this.style.display = 'none'; | |||
return; | return; | ||
} | } | ||
if (!term || $row.text().toLowerCase().indexOf(term) !== -1) { | if (!term || $row.text().toLowerCase().indexOf(term) !== -1) { | ||
this.style.display = ''; | |||
visible++; | visible++; | ||
} else { | } else { | ||
this.style.display = 'none'; | |||
} | } | ||
}); | }); | ||
| Line 61: | Line 60: | ||
} | } | ||
var smwTimer = null; | var smwTimer = null; | ||
var observer = new MutationObserver(function (mutations) { | var observer = new MutationObserver(function (mutations) { | ||
var relevantChange = mutations.some(function (m) { | |||
return m.target.hasAttribute && m.target.hasAttribute('data-smw-hidden') === false | |||
var | && $(m.target).hasClass('filtered-table-item'); | ||
return $(m.target).hasClass('filtered-table-item'); | |||
}); | }); | ||
if (! | if (!relevantChange) return; | ||
// Pause observer, snapshot raw SMW state, then reapply search | |||
observer.disconnect(); | |||
clearTimeout(smwTimer); | clearTimeout(smwTimer); | ||
| Line 79: | Line 77: | ||
snapshotSMW(); | snapshotSMW(); | ||
applySearch(); | applySearch(); | ||
observer.observe($container[0], observerConfig); | |||
}, 50); | }, 50); | ||
}); | }); | ||
var observerConfig = { | |||
subtree: true, | subtree: true, | ||
attributes: true, | attributes: true, | ||
attributeFilter: ['style'] | attributeFilter: ['style'] | ||
}); | }; | ||
// Initial snapshot before observer starts | |||
snapshotSMW(); | |||
applySearch(); | |||
observer.observe($container[0], observerConfig); | |||
$searchInput.on('input', function () { | $searchInput.on('input', function () { | ||
applySearch(); | applySearch(); | ||
}); | }); | ||
} | } | ||
Revision as of 15:17, 27 February 2026
(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);
var $rows = $container.find('tr.filtered-table-item');
// Use a real HTML attribute (not jQuery .data()) so we can always
// distinguish SMW state from our own display manipulation
function snapshotSMW() {
$rows.each(function () {
// Read the raw inline style before we touch anything
$(this).attr('data-smw-hidden', this.style.display === 'none' ? '1' : '0');
});
}
function applySearch() {
var term = $.trim($searchInput.val()).toLowerCase();
var total = $rows.length;
var visible = 0;
$rows.each(function () {
var $row = $(this);
if ($row.attr('data-smw-hidden') === '1') {
// Restore SMW's hidden state without triggering observer
this.style.display = 'none';
return;
}
if (!term || $row.text().toLowerCase().indexOf(term) !== -1) {
this.style.display = '';
visible++;
} else {
this.style.display = 'none';
}
});
$counter.text('Showing ' + visible + ' of ' + total + ' entries');
}
var smwTimer = null;
var observer = new MutationObserver(function (mutations) {
var relevantChange = mutations.some(function (m) {
return m.target.hasAttribute && m.target.hasAttribute('data-smw-hidden') === false
&& $(m.target).hasClass('filtered-table-item');
});
if (!relevantChange) return;
// Pause observer, snapshot raw SMW state, then reapply search
observer.disconnect();
clearTimeout(smwTimer);
smwTimer = setTimeout(function () {
snapshotSMW();
applySearch();
observer.observe($container[0], observerConfig);
}, 50);
});
var observerConfig = {
subtree: true,
attributes: true,
attributeFilter: ['style']
};
// Initial snapshot before observer starts
snapshotSMW();
applySearch();
observer.observe($container[0], observerConfig);
$searchInput.on('input', function () {
applySearch();
});
}
$(document).ready(function () {
init();
});
}(jQuery));