User:Emilio/snippets.js
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.
/* Filterable snippets */
$(function () {
// Properties whose values are comma-separated.
const multiValueProperties = new Set([
'Page keywords',
'SDG'
]);
function getValues(chip) {
const property = chip.dataset.property.trim();
const text = chip.textContent.trim();
if (!text) return [];
if (!multiValueProperties.has(property)) {
return [text];
}
return text.split(',')
.map(value => value.trim())
.filter(Boolean);
}
$('.page-snippet-filterable').each(function () {
const container = this;
if (container.dataset.filtersReady) return;
container.dataset.filtersReady = 'true';
const snippets = Array.from(
container.querySelectorAll('.page-snippet-inline')
);
if (!snippets.length) return;
const properties = new Map();
// Collect property names and distinct values.
snippets.forEach(function (snippet) {
snippet.querySelectorAll('.data-chip[data-property]')
.forEach(function (chip) {
const name = chip.dataset.property.trim();
if (!name) return;
const values = getValues(chip);
if (!values.length) return;
if (!properties.has(name)) {
properties.set(name, new Set());
}
values.forEach(function (value) {
properties.get(name).add(value);
});
});
});
if (!properties.size) return;
const controls = document.createElement('div');
controls.className = 'page-snippet-filters';
controls.style.cssText =
'display:flex;flex-wrap:wrap;gap:1em;margin:1em 0;align-items:end';
const selections = new Map();
function update() {
let visible = 0;
snippets.forEach(function (snippet) {
const chips = Array.from(
snippet.querySelectorAll('.data-chip[data-property]')
);
const matches = Array.from(selections).every(
function ([property, value]) {
if (!value) return true;
return chips.some(function (chip) {
return chip.dataset.property.trim() === property &&
getValues(chip).includes(value);
});
}
);
snippet.style.display = matches ? '' : 'none';
if (matches) visible++;
});
counter.textContent =
'Showing ' + visible + ' of ' + snippets.length + ' projects';
}
properties.forEach(function (values, name) {
const group = document.createElement('label');
group.style.cssText =
'display:flex;flex-direction:column;gap:0.25em';
group.textContent = name;
const select = document.createElement('select');
select.className = 'cdx-select';
const all = document.createElement('option');
all.value = '';
all.textContent = 'All ' + name;
select.appendChild(all);
Array.from(values)
.sort((a, b) => a.localeCompare(b))
.forEach(function (value) {
const option = document.createElement('option');
option.value = value;
option.textContent = value;
select.appendChild(option);
});
select.addEventListener('change', function () {
selections.set(name, select.value);
update();
});
group.appendChild(select);
controls.appendChild(group);
selections.set(name, '');
});
const counter = document.createElement('span');
counter.style.opacity = '0.7';
controls.appendChild(counter);
container.parentNode.insertBefore(controls, container);
update();
});
});