Skip to main content

Store Locator Tag Enhancer Plugin (Detail Fields and Header)

Style, enhance, and link individual Store Locator tags across multiple areas

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()

  • MutationObserver

  • limitedRetry()

  • 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

Did this answer your question?