Choose APM
Print
Created by: Andrii Valenia
Capabilities
| Recurring | YesNo |
| Refund | YesNo |
| Partial refunds | YesNo |
| Multiple partial refunds | YesNo |
| Chargeback | YesNo |
(function () {
function cleanText(value) {
return (value || '').replace(/\s+/g, ' ').trim().toLowerCase();
}
var legend = document.getElementById('apm-catalog-legend-filter');
var grid = document.getElementById('apm-catalog-grid');
if (!legend || !grid) return;
var tiles = Array.from(grid.querySelectorAll('.apm-catalog-tile'));
tiles.forEach(function (tile) {
tile.setAttribute('target', '_blank');
tile.setAttribute('rel', 'noopener noreferrer');
});
var counter = document.getElementById('apm-catalog-counter');
var resetBtn = document.getElementById('apm-catalog-reset-filters');
var emptyState = document.getElementById('apm-catalog-empty');
var chips = Array.from(legend.querySelectorAll('[data-filter-group][data-filter-value]'));
var boolToggles = Array.from(legend.querySelectorAll('.apm-bool-toggle'));
if ((!chips.length && !boolToggles.length) || !tiles.length) return;
var chipGroups = [
'region',
'payment-type',
'payment-flow',
'integration-type'
];
var boolGroups = [
'recurring',
'refund',
'partial-refunds',
'multiple-partial-refunds',
'chargeback'
];
var selected = {};
var allChipValues = {};
chipGroups.forEach(function (g) {
selected[g] = new Set();
allChipValues[g] = new Set();
});
var boolSelection = {};
var defaultBoolSelection = {};
var boolFilterStrict = {};
boolToggles.forEach(function (toggle) {
var group = cleanText(toggle.dataset.filterGroup);
if (!group) return;
var active = toggle.querySelector('.apm-bool-toggle__btn.is-active');
var value = active ? cleanText(active.dataset.value) : 'yes';
boolSelection[group] = value;
defaultBoolSelection[group] = value;
boolFilterStrict[group] = false;
});
var chipMeta = chips.map(function (chip) {
var group = cleanText(chip.dataset.filterGroup);
var value = cleanText(chip.dataset.filterValue);
if (group && value && allChipValues[group]) {
allChipValues[group].add(value);
}
return {
chip: chip,
group: group,
value: value
};
}).filter(function (meta) {
return meta.group && meta.value && selected[meta.group];
});
function datasetKey(group) {
var map = {
'payment-type': 'paymentType',
'payment-flow': 'paymentFlow',
'integration-type': 'integrationType',
'partial-refunds': 'partialRefunds',
'multiple-partial-refunds': 'multiplePartialRefunds'
};
return map[group] || group;
}
function activeChipValues(group) {
if (!selected[group] || !selected[group].size) {
return allChipValues[group] || new Set();
}
return selected[group];
}
function setChipState(meta, isActive, isDisabled) {
var chip = meta.chip;
chip.dataset.active = isActive ? '1' : '0';
chip.dataset.disabled = isDisabled ? '1' : '0';
chip.classList.toggle('is-filter-on', isActive && !isDisabled);
chip.classList.toggle('is-filter-off', !isActive && !isDisabled);
chip.classList.remove('is-filter-hover', 'is-filter-focus');
chip.style.transform = '';
chip.style.outline = '';
chip.setAttribute('aria-pressed', isActive ? 'true' : 'false');
chip.setAttribute('aria-disabled', isDisabled ? 'true' : 'false');
}
function applyHoverState(meta, isHovered, isFocus) {
var chip = meta.chip;
if (chip.dataset.disabled === '1') return;
chip.classList.toggle('is-filter-hover', isHovered);
chip.classList.toggle('is-filter-focus', isFocus && isHovered);
if (!isHovered) {
chip.classList.remove('is-filter-focus');
chip.style.transform = '';
chip.style.outline = '';
}
}
function tileMatches(tile) {
var i;
for (i = 0; i < chipGroups.length; i++) {
var group = chipGroups[i];
var active = activeChipValues(group);
if (!active.size) continue;
if (active.size === allChipValues[group].size) continue;
var raw = cleanText(tile.dataset[datasetKey(group)] || '');
var parts = raw.split(/\s+/).filter(Boolean);
var hit = false;
active.forEach(function (value) {
if (parts.indexOf(value) !== -1) hit = true;
});
if (!hit) return false;
}
for (i = 0; i < boolGroups.length; i++) {
var boolGroup = boolGroups[i];
if (!boolFilterStrict[boolGroup]) continue;
var expected = boolSelection[boolGroup];
if (!expected) continue;
var actual = cleanText(tile.dataset[datasetKey(boolGroup)] || '');
if (actual !== expected) return false;
}
return true;
}
function updateCounter(matchedTotal, totalMethods) {
if (counter) {
counter.textContent = matchedTotal + '/' + totalMethods;
counter.title = matchedTotal + ' of ' + totalMethods + ' methods match filters';
}
if (emptyState) emptyState.style.display = matchedTotal === 0 ? 'block' : 'none';
scheduleChipWidthSync();
}
function refreshChipStates() {
chipMeta.forEach(function (meta) {
var active = activeChipValues(meta.group);
var isActive = !active.size || active.has(meta.value);
setChipState(meta, isActive, false);
});
}
function toggleChipFilter(group, value) {
if (!selected[group]) return;
if (selected[group].has(value)) {
if (selected[group].size <= 1) return;
selected[group].delete(value);
} else {
selected[group].add(value);
}
applyFilter();
}
function setTileMatchState(tile, matches) {
tile.classList.toggle('is-match', matches);
tile.classList.toggle('is-inactive', !matches);
tile.setAttribute('aria-disabled', matches ? 'false' : 'true');
if (matches) {
tile.removeAttribute('tabindex');
} else {
tile.setAttribute('tabindex', '-1');
}
}
var chipMeasureProbe = null;
function measureChipTextWidth(chip) {
if (!chipMeasureProbe) {
chipMeasureProbe = document.createElement('span');
chipMeasureProbe.className = 'apm-filter-chip apm-overview-pill';
chipMeasureProbe.setAttribute('aria-hidden', 'true');
chipMeasureProbe.style.position = 'absolute';
chipMeasureProbe.style.left = '-9999px';
chipMeasureProbe.style.top = '0';
chipMeasureProbe.style.visibility = 'hidden';
chipMeasureProbe.style.pointerEvents = 'none';
chipMeasureProbe.style.whiteSpace = 'nowrap';
chipMeasureProbe.style.width = 'auto';
chipMeasureProbe.style.maxWidth = 'none';
chipMeasureProbe.style.overflow = 'visible';
legend.appendChild(chipMeasureProbe);
}
var cs = window.getComputedStyle(chip);
chipMeasureProbe.className = chip.className;
chipMeasureProbe.style.cssText = [
'position:absolute',
'left:-9999px',
'top:0',
'visibility:hidden',
'pointer-events:none',
'white-space:nowrap',
'width:auto',
'max-width:none',
'min-width:0',
'overflow:visible',
'box-sizing:border-box',
'font:' + cs.font,
'padding:' + cs.padding,
'border:' + cs.border,
'border-radius:' + cs.borderRadius,
'letter-spacing:' + cs.letterSpacing
].join(';');
chipMeasureProbe.textContent = (chip.textContent || '').replace(/\s+/g, ' ').trim();
return Math.ceil(chipMeasureProbe.getBoundingClientRect().width);
}
function highlightChipAreaWidth(highlight, row) {
if (!highlight) return 0;
var label = highlight.querySelector('.apm-overview-highlight__label');
var labelW = label ? label.offsetWidth : 0;
var rowStyle = row ? getComputedStyle(row) : null;
var rowMargin = rowStyle ? (parseFloat(rowStyle.marginLeft) || 0) : 10;
var rowChrome = 0;
if (rowStyle) {
rowChrome += (parseFloat(rowStyle.paddingLeft) || 0) + (parseFloat(rowStyle.paddingRight) || 0);
rowChrome += (parseFloat(rowStyle.borderLeftWidth) || 0) + (parseFloat(rowStyle.borderRightWidth) || 0);
}
return Math.max(0, highlight.clientWidth - labelW - rowMargin - rowChrome);
}
function measureAllChipTextWidths(chips) {
var globalMax = 0;
chips.forEach(function (chip) {
globalMax = Math.max(globalMax, measureChipTextWidth(chip));
});
return globalMax;
}
function applyChipWidth(chips, widthPx) {
var px = widthPx + 'px';
chips.forEach(function (chip) {
chip.style.width = px;
chip.style.minWidth = px;
chip.style.maxWidth = px;
chip.classList.add('apm-catalog-chip-sized');
});
}
function clearChipSizing(chips) {
chips.forEach(function (chip) {
chip.classList.remove('apm-catalog-chip-sized');
chip.style.width = '';
chip.style.minWidth = '';
chip.style.maxWidth = '';
});
}
function setChipDensityMode(mode) {
legend.classList.remove('apm-catalog-chips-compact', 'apm-catalog-chips-tight', 'apm-catalog-chips-micro');
if (mode === 'compact') legend.classList.add('apm-catalog-chips-compact');
if (mode === 'tight') {
legend.classList.add('apm-catalog-chips-compact', 'apm-catalog-chips-tight');
}
if (mode === 'micro') {
legend.classList.add('apm-catalog-chips-compact', 'apm-catalog-chips-tight', 'apm-catalog-chips-micro');
}
}
function rowFitsChipWidth(row, chipWidth) {
var rowChips = row.querySelectorAll('.apm-filter-chip');
if (!rowChips.length) return true;
var highlight = row.closest('.apm-catalog-filter-highlight');
var innerW = highlight ? highlightChipAreaWidth(highlight, row) : 0;
if (!innerW) return true;
return rowChipsTotalWidth(row, chipWidth, rowChips.length) <= innerW;
}
function resolveGlobalChipWidth(allChips, rows) {
var modes = ['', 'compact', 'tight', 'micro'];
var chosenMode = 'micro';
var globalWidth = 0;
var i;
var j;
for (i = 0; i < modes.length; i++) {
setChipDensityMode(modes[i]);
globalWidth = Math.max(52, measureAllChipTextWidths(allChips));
if (!globalWidth) return { width: 0, mode: '' };
chosenMode = modes[i];
var allFit = true;
for (j = 0; j < rows.length; j++) {
if (!rowFitsChipWidth(rows[j], globalWidth)) {
allFit = false;
break;
}
}
if (allFit || i === modes.length - 1) break;
}
return { width: globalWidth, mode: chosenMode };
}
function rowChipsTotalWidth(row, chipWidth, chipCount) {
if (!chipCount) return 0;
var gap = parseFloat(getComputedStyle(row).columnGap || getComputedStyle(row).gap) || 0;
return chipWidth * chipCount + gap * Math.max(0, chipCount - 1);
}
function syncChipRowWidths() {
var rows = Array.from(legend.querySelectorAll(
'.apm-catalog-filter-highlight .legend-chip-row, .apm-catalog-filter-highlight .apm-overview-highlight__pills'
));
if (!rows.length) return;
var allChips = Array.from(legend.querySelectorAll('.apm-catalog-filter-highlight .apm-filter-chip'));
legend.classList.remove('apm-catalog-chips-sized');
legend.style.removeProperty('--apm-catalog-chip-w');
clearChipSizing(allChips);
rows.forEach(function (row) {
row.classList.remove('apm-catalog-chip-row--wrap');
});
var resolved = resolveGlobalChipWidth(allChips, rows);
if (!resolved.width) return;
setChipDensityMode(resolved.mode);
var globalWidth = Math.max(52, measureAllChipTextWidths(allChips));
legend.style.setProperty('--apm-catalog-chip-w', globalWidth + 'px');
legend.classList.add('apm-catalog-chips-sized');
applyChipWidth(allChips, globalWidth);
rows.forEach(function (row) {
if (!rowFitsChipWidth(row, globalWidth)) {
row.classList.add('apm-catalog-chip-row--wrap');
}
});
}
var syncChipWidthsRaf = 0;
function scheduleChipWidthSync() {
if (syncChipWidthsRaf) cancelAnimationFrame(syncChipWidthsRaf);
syncChipWidthsRaf = requestAnimationFrame(function () {
syncChipRowWidths();
requestAnimationFrame(function () {
syncChipWidthsRaf = 0;
syncChipRowWidths();
});
});
}
var resizeTimer = 0;
window.addEventListener('resize', function () {
clearTimeout(resizeTimer);
resizeTimer = setTimeout(scheduleChipWidthSync, 120);
});
if (document.fonts && document.fonts.ready) {
document.fonts.ready.then(scheduleChipWidthSync);
}
function applyFilter() {
refreshChipStates();
var matched = 0;
tiles.forEach(function (tile) {
var matches = tileMatches(tile);
setTileMatchState(tile, matches);
if (matches) matched += 1;
});
updateCounter(matched, tiles.length);
}
function setBoolFilter(group, value) {
if (!group) return;
boolSelection[group] = value;
var toggle = legend.querySelector('.apm-bool-toggle[data-filter-group="' + group + '"]');
if (!toggle) return;
Array.from(toggle.querySelectorAll('.apm-bool-toggle__btn')).forEach(function (btn) {
var on = cleanText(btn.dataset.value) === value;
btn.classList.toggle('is-active', on);
btn.setAttribute('aria-pressed', on ? 'true' : 'false');
});
}
chipMeta.forEach(function (meta) {
selected[meta.group].add(meta.value);
meta.chip.setAttribute('role', 'button');
meta.chip.setAttribute('tabindex', '0');
meta.chip.setAttribute('title', 'Click to toggle filter');
function toggleChip() {
toggleChipFilter(meta.group, meta.value);
}
meta.chip.addEventListener('click', toggleChip);
meta.chip.addEventListener('keydown', function (event) {
if (event.key === 'Enter' || event.key === ' ') {
event.preventDefault();
toggleChip();
}
});
meta.chip.addEventListener('mouseenter', function () { applyHoverState(meta, true, false); });
meta.chip.addEventListener('mouseleave', function () { applyHoverState(meta, false, false); });
meta.chip.addEventListener('focus', function () { applyHoverState(meta, true, true); });
meta.chip.addEventListener('blur', function () { applyHoverState(meta, false, false); });
});
boolToggles.forEach(function (toggle) {
var group = cleanText(toggle.dataset.filterGroup);
if (!group) return;
var buttons = Array.from(toggle.querySelectorAll('.apm-bool-toggle__btn'));
function setActive(btn) {
boolFilterStrict[group] = true;
setBoolFilter(group, cleanText(btn.dataset.value));
applyFilter();
}
buttons.forEach(function (btn) {
btn.addEventListener('click', function () { setActive(btn); });
});
});
tiles.forEach(function (tile) {
tile.addEventListener('click', function (event) {
if (tile.classList.contains('is-inactive')) {
event.preventDefault();
}
});
});
if (resetBtn) {
resetBtn.addEventListener('click', function () {
chipMeta.forEach(function (meta) {
selected[meta.group].add(meta.value);
});
boolGroups.forEach(function (group) {
boolFilterStrict[group] = false;
setBoolFilter(group, defaultBoolSelection[group] || 'yes');
});
applyFilter();
});
}
applyFilter();
scheduleChipWidthSync();
})();
Andrii is the author of this solution article.
Did you find it helpful?
Yes
No
Send feedback Sorry we couldn't be helpful. Help us improve this article with your feedback.