Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

HTML
<!-- JS: Alexandr Petrunin-->
<script>
    document.addEventListener('DOMContentLoaded', function() {
        // Handle collapse functionality
        document.querySelectorAll('[data-bs-toggle="collapse"]').forEach(trigger => {
            trigger.addEventListener('click', function(e) {
                e.preventDefault();
                const target = document.querySelector(this.getAttribute('data-bs-target'));

                // If there's a parent accordion, hide other panels
                const parent = document.querySelector(target.getAttribute('data-bs-parent'));
                if (parent) {
                    parent.querySelectorAll('.collapse.show').forEach(el => {
                        if (el !== target) {
                            el.classList.remove('show');
                        }
                    });
                }

                // Toggle target panel
                target.classList.toggle('show');
            });
        });

        // Handle list/tab functionality
        document.querySelectorAll('[data-bs-toggle="list"]').forEach(trigger => {
            trigger.addEventListener('click', function(e) {
                e.preventDefault();

                // Remove active class from all tabs in group
                const listGroup = this.closest('.list-group');
                listGroup.querySelectorAll('.active').forEach(el => {
                    el.classList.remove('active');
                });

                // Add active class to clicked tab
                this.classList.add('active');

                // Show corresponding content
                const target = document.querySelector(this.getAttribute('href'));
                const tabContent = target.closest('.tab-content');

                tabContent.querySelectorAll('.tab-pane').forEach(pane => {
                    pane.classList.remove('show', 'active');
                });

                target.classList.add('show', 'active');
            });
        });
    });

    // Add required CSS if not already present
    const style = document.createElement('style');
    style.textContent = `
    .collapse:not(.show) {
        display: none;
    }
    .collapse.show {
        display: block;
    }
    .tab-content > .tab-pane {
        display: none;
    }
    .tab-content > .active {
        display: block;
    }
`;
    document.head.appendChild(style);
</script>

<!-- Activate tooltips -->
<script>
    document.addEventListener('DOMContentLoaded', function() {
        // Find all elements with tooltip
        document.querySelectorAll('[data-bs-toggle="tooltip"]').forEach(element => {
            const title = element.getAttribute('title');

            // Create tooltip element
            const tooltip = document.createElement('div');
            tooltip.className = 'custom-tooltip';
            tooltip.textContent = title;
            document.body.appendChild(tooltip);

            // Show tooltip
            element.addEventListener('mouseenter', e => {
                const bounds = element.getBoundingClientRect();
                tooltip.style.display = 'block';

                // Position tooltip above the element
                tooltip.style.left = bounds.left + (bounds.width - tooltip.offsetWidth) / 2 + 'px';
                tooltip.style.top = bounds.top - tooltip.offsetHeight - 5 + 'px';
            });

            // Hide tooltip
            element.addEventListener('mouseleave', () => {
                tooltip.style.display = 'none';
            });

            // Remove title attribute to prevent default browser tooltip
            element.removeAttribute('title');
        });
    });

    // Add required CSS
    const tooltipStyle = document.createElement('style');
    tooltipStyle.textContent = `
    .custom-tooltip {
        display: none;
        position: fixed;
        background: rgba(0, 0, 0, 0.8);
        color: white;
        padding: 5px 10px;
        border-radius: 4px;
        font-size: 14px;
        z-index: 1000;
        pointer-events: none;
    }

    .custom-tooltip::after {
        content: '';
        position: absolute;
        bottom: -5px;
        left: 50%;
        transform: translateX(-50%);
        border-width: 5px 5px 0;
        border-style: solid;
        border-color: rgba(0, 0, 0, 0.8) transparent transparent;
    }
`;
    document.head.appendChild(tooltipStyle);
</script>

<!-- Filter bar -->
<script>
   functionfunction extractTags(raw) {
  return raw
    // extract "cycle N" first (keeps them intact)
    .replace(/cycle\s+(\d+)/gi, 'cycle-$1')
    // split on whitespace/newlines
    .trim()
    .toLowerCase()
    .split(/\s+/)
    // convert cycle-N back to "cycle N"
    .map(tag => tag.replace(/cycle-(\d+)/, 'cycle $1'))
    .filter(Boolean);
}
function searchActivities() {
  	const cards = document.querySelectorAll('#card-grid .card');

  	const filter = {
    	text: document.getElementById('card-filter-text').value.trim().toLowerCase(),
    	topic: document.getElementById('card-filter-topic').value.trim().toLowerCase(),
    	cycle: document.getElementById('card-filter-cycle').value.trim().toLowerCase(),
    	deliverable: document.getElementById('card-filter-deliverable').value.trim().toLowerCase(),
  	};

  	cards.forEach(card => {
    	const title = card.querySelector('.card-title').innerText.trim().toLowerCase();
    	
		const rawTags = card.querySelector('.tags').innerText.trim().toLowerCase();

    // Universal parsing for both “identity completed cycle 6” and multi-span tags
    	const tagList = rawTags
      .match(/cycle \d+|identity|security|standards|completed|tim|service|community|external/g) 
      || [];
extractTags(rawTags);
    	const matches = (filterValueval) => {
      if (!filterValue) return true;
      return !val || tagList.includes(filterValueval);
    };

    	const show =
      	title.includes(filter.text) &&
      	matches(filter.topic) &&
      	matches(filter.cycle) &&
      	matches(filter.deliverable);

    	card.style.display = show ? "" : "none";
  	});
}
</script>