Skip to main content

RP Promap Help: Store Locator Tag Enhancer Plugin (Header Only)

Target individual filter tags. Apply custom CSS styles per tag, Add hover effects

RP Promap Help: Store Locator Tag Enhancer Plugin

Overview

The Tag Enhancer Plugin extends the RP Promap Store Locator module by allowing you to:

  • Target individual filter tags

  • Apply custom CSS styles per tag

  • Add hover effects

  • Attach clickable links that open in a new window

  • Automatically re-apply enhancements when the DOM updates (AJAX, filtering, reloads)

This is built using the RP Promap Plugins System and includes standard load handling for stability.


Supported Element

This plugin targets the Store Locator tag list:

<ul id="scasl-tag-list-container" class="bh-sl-filters scasl-tag-list">

Each tag is identified using the checkbox value:

<input type="checkbox" name="tagsvalue" value="Stockist">

Installation

Step 1: Add Script

Paste the plugin script into your page (before closing </body> or inside your custom scripts area).

Step 2: Add Optional CSS (Recommended)

#scasl-tag-list-container li label.rp-tag-enhanced {   display: inline-flex;   align-items: center;   gap: 6px;   cursor: pointer;   transition: all 0.2s ease; }  #scasl-tag-list-container .rp-tag-link {   text-decoration: none;   color: inherit; }

Configuration

All customization is controlled inside:

tagConfig: {   "Stockist": { ... },   "Outlets": { ... } }

Tag Configuration Options

Each tag supports:

Property

Type

Description

url

string

लिंक opened in new tab

styles

object

Default CSS styles

hoverStyles

object

Styles applied on hover


Example

"Stockist": {   url: "https://example.com/stockist",   styles: {     color: "#A4118D",     fontWeight: "700"   },   hoverStyles: {     color: "#000000",     textDecoration: "underline"   } }

How It Works

1. Tag Detection

  • Finds all tags inside #scasl-tag-list-container

  • Matches each tag using input.value

2. Style Injection

  • Applies inline styles from styles

  • Adds hover interactions using hoverStyles

3. Link Injection

  • Wraps the tag label text in an anchor <a>

  • Opens links using:

target="_blank" rel="noopener noreferrer"

4. Safe Rebinding

  • Prevents duplicate event listeners using:

label.dataset.rpHoverBound

Load Handling (Important)

This plugin uses the RP Promap Standard Load System:

Included Features

  • ✅ Initial run on page load

  • 🔁 Retry system (handles delayed rendering)

  • 👀 MutationObserver (handles dynamic updates)

  • ⚡ Debounced updates (performance safe)

Behavior

window.addEventListener("load", function () {   applyUpdates();   limitedRetry(applyUpdates, 1000, 5);   startObserver(); });

This ensures:

  • Tags are enhanced even if loaded late

  • Works with AJAX / filters / Shopify locator reloads

  • Prevents page freezing from excessive DOM updates


Notes & Best Practices

Match Tag Names Exactly

Tag keys must match the checkbox value:

value="Exclusive Dealer"
"Exclusive Dealer": { ... }

Avoid Over-Styling Labels

Do not override:

  • display

  • position

Unless necessary, as it may break layout.


Performance Tips

  • Keep tagConfig lightweight

  • Avoid large inline styles

  • Use CSS classes for complex styling if needed


Link Behavior

  • Clicking the tag text opens the URL

  • Checkbox functionality still works independently


Troubleshooting

Tags not updating

  • Check selector: #scasl-tag-list-container

  • Confirm tag values match exactly

Hover not working

  • Ensure no conflicting CSS overrides

  • Check if styles are being reset elsewhere

Links not appearing

  • Confirm url is defined

  • Ensure text nodes exist inside label


Extend This Plugin

You can expand functionality by:

  • Adding icons per tag

  • Tracking clicks (analytics)

  • Conditional styling (based on active state)

  • Badge counts or dynamic labels


Part of RP Promap Plugins System

This plugin follows the modular architecture:

window.RPPromap.plugins.tagEnhancer

Allowing easy reuse, updates, and future enhancements.

<script>
(function () {
try {
window.RPPromap = window.RPPromap || {};
window.RPPromap.plugins = window.RPPromap.plugins || {};

window.RPPromap.plugins.tagEnhancer = {
selectors: {
tagList: "#scasl-tag-list-container",
tagItem: "li",
tagLabel: "label",
tagInput: 'input[name="tagsvalue"]'
},

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"
}
}
},

applyStyles: function (element, styles) {
Object.keys(styles || {}).forEach(function (key) {
element.style[key] = styles[key];
});
},

enhanceTag: function (item) {
var plugin = this;
var label = item.querySelector(plugin.selectors.tagLabel);
var input = item.querySelector(plugin.selectors.tagInput);

if (!label || !input) return;

var tagName = input.value;
var config = plugin.tagConfig[tagName];

if (!config) return;

label.classList.add("rp-tag-enhanced");
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);
});
}
},

applyUpdates: function () {
var plugin = this;
var list = document.querySelector(plugin.selectors.tagList);

if (!list) return;

var items = list.querySelectorAll(plugin.selectors.tagItem);

items.forEach(function (item) {
plugin.enhanceTag(item);
});
},

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>


© Rose Perl Technology

Did this answer your question?