RP Promap Help: Store Locator Tag Enhancer Plugin
Overview
The Tag Enhancer Plugin allows you to style, enhance, and link individual Store Locator tags across multiple areas of the Store Locator experience.
This includes:
Header filter tags
Store result card tags
Store details page tags
Per-tag CSS styles
Hover effects
Optional links that open in a new window
Automatic re-application when the Store Locator updates dynamically
Supported Tag Areas
1. Header Filter Tags
Used in the filter section at the top of the Store Locator.
#scasl-tag-list-container
Example:
<input type="checkbox" name="tagsvalue" value="Stockist">
2. Store Result Card Tags
Used inside each store result card.
document.querySelectorAll('#scasl-app-container #scasl-tags .scasl-tags')DOM path:
#scasl-app-container β #scasl-tags β span.scasl-tags
3. Store Details Tags
Store details pages also use the scasl-tags class structure, so the same plugin can target them using the shared selector logic.
No additional plugin is required.
Important Note
This customization relies on custom JavaScript and CSS within your theme. It is not a built-in feature of the Store Locator app.
However, the DOM structure and selectors listed above are stable and can be reliably used for this type of RP Promap customization.
Updated Plugin Script
<style> #scasl-tag-list-container li label.rp-tag-enhanced, #scasl-app-container #scasl-tags .scasl-tags.rp-tag-enhanced { transition: all 0.2s ease; } #scasl-tag-list-container li label.rp-tag-enhanced { display: inline-flex; align-items: center; gap: 6px; cursor: pointer; } #scasl-tag-list-container .rp-tag-link, #scasl-app-container #scasl-tags .rp-tag-link { color: inherit; text-decoration: none; } .rp-special-offer-badge { color: #c40000; border: 1px solid #c40000; padding: 3px 8px; border-radius: 999px; font-weight: 700; } </style>
<script> (function () { try { window.RPPromap = window.RPPromap || {}; window.RPPromap.plugins = window.RPPromap.plugins || {}; window.RPPromap.plugins.tagEnhancer = { selectors: { headerTagList: "#scasl-tag-list-container", headerTagItem: "li", headerTagLabel: "label", headerTagInput: 'input[name="tagsvalue"]', storeTags: "#scasl-app-container #scasl-tags .scasl-tags" }, tagConfig: { "Stockist": { url: "https://example.com/stockist", styles: { color: "#A4118D", fontWeight: "700" }, hoverStyles: { color: "#000000", textDecoration: "underline" } }, "Outlets": { url: "https://example.com/outlets", styles: { color: "#ffffff", backgroundColor: "#A4118D", padding: "4px 10px", borderRadius: "999px" }, hoverStyles: { backgroundColor: "#000000", color: "#ffffff" } }, "Exclusive Dealer": { url: "https://example.com/exclusive-dealer", styles: { color: "#000000", border: "1px solid #A4118D", padding: "4px 10px", borderRadius: "999px" }, hoverStyles: { backgroundColor: "#A4118D", color: "#ffffff" } }, "Special Offer": { className: "rp-special-offer-badge", url: "https://example.com/special-offer", styles: {}, hoverStyles: { opacity: "0.75" } } }, applyStyles: function (element, styles) { Object.keys(styles || {}).forEach(function (key) { element.style[key] = styles[key]; }); }, getTagConfig: function (tagName) { return this.tagConfig[tagName] || null; }, enhanceHeaderTag: function (item) { var plugin = this; var label = item.querySelector(plugin.selectors.headerTagLabel); var input = item.querySelector(plugin.selectors.headerTagInput); if (!label || !input) return; var tagName = input.value.trim(); var config = plugin.getTagConfig(tagName); if (!config) return; label.classList.add("rp-tag-enhanced"); if (config.className) { label.classList.add(config.className); } plugin.applyStyles(label, config.styles); if (!label.dataset.rpHoverBound) { label.addEventListener("mouseenter", function () { plugin.applyStyles(label, config.hoverStyles); }); label.addEventListener("mouseleave", function () { plugin.applyStyles(label, config.styles); }); label.dataset.rpHoverBound = "true"; } if (config.url && !label.querySelector(".rp-tag-link")) { var textNodes = Array.from(label.childNodes).filter(function (node) { return node.nodeType === 3 && node.textContent.trim(); }); textNodes.forEach(function (node) { var link = document.createElement("a"); link.href = config.url; link.target = "_blank"; link.rel = "noopener noreferrer"; link.className = "rp-tag-link"; link.textContent = node.textContent.trim(); node.replaceWith(document.createTextNode(" "), link); }); } }, enhanceStoreTag: function (tagElement) { var plugin = this; var tagName = tagElement.textContent.trim(); var config = plugin.getTagConfig(tagName); if (!config) return; tagElement.classList.add("rp-tag-enhanced"); if (config.className) { tagElement.classList.add(config.className); } plugin.applyStyles(tagElement, config.styles); if (!tagElement.dataset.rpHoverBound) { tagElement.addEventListener("mouseenter", function () { plugin.applyStyles(tagElement, config.hoverStyles); }); tagElement.addEventListener("mouseleave", function () { plugin.applyStyles(tagElement, config.styles); }); tagElement.dataset.rpHoverBound = "true"; } if (config.url && !tagElement.querySelector(".rp-tag-link")) { var originalText = tagElement.textContent.trim(); tagElement.textContent = ""; var link = document.createElement("a"); link.href = config.url; link.target = "_blank"; link.rel = "noopener noreferrer"; link.className = "rp-tag-link"; link.textContent = originalText; tagElement.appendChild(link); } }, applyUpdates: function () { var plugin = this; var headerList = document.querySelector(plugin.selectors.headerTagList); if (headerList) { headerList.querySelectorAll(plugin.selectors.headerTagItem).forEach(function (item) { plugin.enhanceHeaderTag(item); }); } document.querySelectorAll(plugin.selectors.storeTags).forEach(function (tagElement) { plugin.enhanceStoreTag(tagElement); }); }, debounce: function (fn, delay) { var timeout; return function () { clearTimeout(timeout); timeout = setTimeout(fn, delay); }; }, limitedRetry: function (fn, interval, maxAttempts) { var attempts = 0; var timer = setInterval(function () { attempts += 1; fn(); if (attempts >= maxAttempts) { clearInterval(timer); } }, interval); }, startObserver: function () { var plugin = this; var debouncedApply = plugin.debounce(function () { plugin.applyUpdates(); }, 300); var observer = new MutationObserver(function (mutations) { var shouldRun = mutations.some(function (mutation) { return mutation.addedNodes.length > 0 || mutation.removedNodes.length > 0; }); if (shouldRun) { debouncedApply(); } }); observer.observe(document.body, { childList: true, subtree: true }); }, init: function () { var plugin = this; window.addEventListener("load", function () { plugin.applyUpdates(); plugin.limitedRetry(function () { plugin.applyUpdates(); }, 1000, 5); plugin.startObserver(); }); } }; window.RPPromap.plugins.tagEnhancer.init(); } catch (error) { console.warn("RP Promap store locator tag enhancer plugin:", error); } })(); </script>Configuration Notes
Each tag is configured inside:
tagConfig: { "Stockist": { ... }, "Special Offer": { ... } }The tag name must match exactly.
Example:
"Special Offer": { className: "rp-special-offer-badge", url: "https://example.com/special-offer", styles: {}, hoverStyles: { opacity: "0.75" } }Targeting Store Card Tags Only
You can target store result card tags with:
document.querySelectorAll('#scasl-app-container #scasl-tags .scasl-tags')Example:
document .querySelectorAll('#scasl-app-container #scasl-tags .scasl-tags') .forEach(function (span) { if (span.textContent.trim() === "Special Offer") { span.classList.add("rp-special-offer-badge"); } });Why No Extra Plugin Is Needed
The existing Tag Enhancer Plugin already includes:
applyUpdates()MutationObserverlimitedRetry()debounce()
Because of this, the same plugin can safely enhance dynamically rendered tags across the header, store list, and details views.
Troubleshooting
Header tags are working, but store card tags are not
Check that the card tags render as:
<span class="scasl-tags">Special Offer</span>
And are inside:
#scasl-app-container #scasl-tags
Links are not opening
Confirm the tag has a url value:
url: "https://example.com/special-offer"
Links open with:
target="_blank" rel="noopener noreferrer"
Styles are not applying
Check that the tag text matches exactly, including capitalization and spacing.
Correct:
"Exclusive Dealer"
Incorrect:
"exclusive dealer"
Best Practice
Use className for reusable styling and styles only for simple inline overrides.
Recommended:
"Special Offer": { className: "rp-special-offer-badge" }Β© Rose Perl Technology
