Skip to main content

RP Promap Sorting Widget: Sort by State or ZIP Code First, Then Distance

This sorting widget solves that problem by adding two new sort modes

RP Promap Sorting Widget: Sort by State or ZIP Code First, Then Distance

In some store locator experiences, “nearest first” is not always the best way to display results.

A customer may search from a location near a state border, or near a dense metro area where stores from multiple cities, ZIP codes, or states appear in the results. In those cases, the closest physical location may not be the most relevant result for how the business wants locations grouped.

This RP Promap sorting widget solves that problem by adding two new sort modes:

Zip Code by Distance
State by Distance

Use Case

Standard distance sorting ranks every location purely by proximity.

That works well when the user only cares about the closest store. But in many real-world cases, a business may want results grouped first by geography, then sorted by distance within that group.

For example, a customer searching near the edge of a state may see locations from a neighboring state before locations in their intended service area. A nearby city across the border may technically be closer, but the business may want locations in the same state to appear together first.

The same applies to ZIP codes. A location in a nearby ZIP code may be closer by distance, but the business may want results grouped by ZIP code first so customers can scan locations in a more structured local order.

What the Widget Does

This silent JavaScript patch adds two new sorting options to the existing RP Promap store locator dropdown:

 'by_zipcode_distance'
'by_state_distance'

Change Mode in the script below to change the sort

No base-code edits are required.

The script waits for the store locator to load, finds the existing sort dropdown, and injects the new options automatically at runtime.

Sorting Behavior

Zip Code by Distance

Locations are sorted by ZIP code first.

If two locations share the same ZIP code, they are then sorted by distance.

Example:

10001 - 4.2 miles
10001 - 7.8 miles
10002 - 2.1 miles
10003 - 1.5 miles

Even though the 10003 location is physically closer, the ZIP code grouping stays intact.

State by Distance

Locations are sorted by state first.

If two locations are in the same state, they are then sorted by distance.

Example:

FL - 6.4 miles
FL - 12.8 miles
GA - 3.2 miles
GA - 9.6 miles

Even though the Georgia location may be closer, the Florida locations remain grouped first.

Why This Matters

This is useful when location relevance is not purely based on mileage.

Common examples include:

State-specific dealers
Territory-based sales teams
ZIP-code-based service areas
Franchise regions
Compliance or licensing boundaries
Delivery zones
Regional marketing groups

For businesses with mapped service territories, distance alone can create confusing results. Sorting by state or ZIP code first gives customers a clearer, more intentional browsing experience.

Silent Runtime Patch

The widget is designed as an overlay patch. It wraps the existing sortNumerically function at runtime and only changes behavior when one of the new sort modes is selected.

For every other sort mode, the original sorting logic is preserved.

That means existing RP Promap sorting behavior remains untouched.

Script

<script>
/**
* Overlay patch: force sort mode from script (no dropdown/UI changes)
* Set MODE to:
* - 'by_zipcode_distance'
* - 'by_state_distance'
*/
(function () {
var MODE = 'by_zipcode_distance'; // change to 'by_state_distance' as needed
var SORT_ZIP = 'by_zipcode_distance';
var SORT_STATE = 'by_state_distance';

function norm(v) { return (v || '').toString().trim().toUpperCase(); }
function zipOf(x) { return norm(x && (x.postal || x.zipcode || x.zip)); }
function stateOf(x) { return norm(x && (x.state || x.region || x.province)); }

function distanceOf(x) {
var d = Number(x && x.distance);
return Number.isFinite(d) ? d : Infinity;
}

function compareDistanceAsc(a, b) {
var da = distanceOf(a), db = distanceOf(b);
if (da < db) return -1;
if (da > db) return 1;
return 0;
}

function compareZipDistance(a, b) {
var za = zipOf(a), zb = zipOf(b);
if (za < zb) return -1;
if (za > zb) return 1;
return compareDistanceAsc(a, b);
}

function compareStateDistance(a, b) {
var sa = stateOf(a), sb = stateOf(b);
if (sa < sb) return -1;
if (sa > sb) return 1;
return compareDistanceAsc(a, b);
}

function forceMode() {
window.SCASLWtb = window.SCASLWtb || {};
window.SCASLWtb.setting = window.SCASLWtb.setting || {};
window.SCASLWtb.setting.store_sort = MODE;
}

function patchSortNumerically() {
if (typeof window.sortNumerically !== 'function') return false;
if (window.sortNumerically.__scaslForcedPatched) return true;

var original = window.sortNumerically;

window.sortNumerically = function (locationsarray) {
forceMode();

if (Array.isArray(locationsarray)) {
if (MODE === SORT_ZIP) {
locationsarray.sort(compareZipDistance);
return;
}
if (MODE === SORT_STATE) {
locationsarray.sort(compareStateDistance);
return;
}
}

return original.apply(this, arguments);
};

window.sortNumerically.__scaslForcedPatched = true;
window.sortNumerically.__scaslOriginal = original;
return true;
}

function rerenderIfPossible() {
if (typeof window.generateStockistLocations === 'function' && window.jQuerySCASL) {
window.generateStockistLocations(window.jQuerySCASL);
if (typeof window.selectedStockistItem === 'function') {
window.selectedStockistItem(window.jQuerySCASL, window.jQuerySCASL('.location-item:first'));
}
}
}

function boot() {
forceMode();
patchSortNumerically();
rerenderIfPossible();
}

var tries = 0;
var timer = setInterval(function () {
tries++;
boot();
if (tries > 80 || (window.sortNumerically && window.sortNumerically.__scaslForcedPatched)) {
clearInterval(timer);
}
}, 250);
})();
</script>

Implementation: Add the Patch to theme.liquid

To make this sorting widget run automatically across your Shopify storefront, add the script to your theme’s theme.liquid file.

This allows the patch to load globally and quietly activate only when it detects an RP Promap store locator page, map page, or “Where to Buy” experience that includes the store sort dropdown.

Where to Add It

In Shopify, go to:

Online Store → Themes → Edit Code → Layout → theme.liquid

Paste the script before the closing </body> tag:

</body>

Recommended placement:

<!-- RP Promap Store Locator Sorting Patch -->
<script>
/* Paste the RP Promap sorting widget script here */
</script>
</body>

Why Add It to theme.liquid?

Adding the widget to theme.liquid makes the patch available site-wide without editing the base RP Promap store locator code.

This is useful when your store has multiple entry points, such as:

Store locator pages
Map landing pages
Product pages with “Where to Buy” buttons
Dealer locator links
Regional availability pages

When a customer clicks a “Where to Buy” button and lands on a map or locator view, the script will already be available. Once the RP Promap dropdown and sortNumerically function are present, the patch injects the new sorting options automatically.

Safe Runtime Behavior

The script is silent and non-destructive.

If the current page does not include the RP Promap map or sort dropdown, nothing changes. If the locator loads later, the script watches the page and adds the sorting options when the dropdown appears.

This makes it safe to place in theme.liquid for global use across map pages and “Where to Buy” customer flows.

Summary

This RP Promap widget is ideal when businesses need more control over how store locator results are grouped.

Instead of relying only on nearest-distance sorting, the widget allows results to be organized by ZIP code or state first, while still preserving distance sorting inside each group.

Did this answer your question?