Skip to content

Instantly share code, notes, and snippets.

@steverowling
Last active August 25, 2016 23:29
Show Gist options
  • Save steverowling/8428a9e7810e6aec456b to your computer and use it in GitHub Desktop.
Save steverowling/8428a9e7810e6aec456b to your computer and use it in GitHub Desktop.
EE Search by distance from postcode using Low Search (search form)
<!-- Load Google Maps for geocoding of postcode -->
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false"></script>
<!-- Check we have a valid UK postcode before attempting geocode lookup -->
<script>
function checkPostCode(toCheck) {
// Permitted letters depend upon their position in the postcode.
var alpha1 = "[abcdefghijklmnoprstuwyz]"; // Character 1
var alpha2 = "[abcdefghklmnopqrstuvwxy]"; // Character 2
var alpha3 = "[abcdefghjkpmnrstuvwxy]"; // Character 3
var alpha4 = "[abehmnprvwxy]"; // Character 4
var alpha5 = "[abdefghjlnpqrstuwxyz]"; // Character 5
var BFPOa5 = "[abdefghjlnpqrst]"; // BFPO alpha5
var BFPOa6 = "[abdefghjlnpqrstuwzyz]"; // BFPO alpha6
// Array holds the regular expressions for the valid postcodes
var pcexp = new Array ();
// BFPO postcodes
// pcexp.push (new RegExp ("^(bf1)(\\s*)([0-6]{1}" + BFPOa5 + "{1}" + BFPOa6 + "{1})$","i"));
// Expression for postcodes: AN NAA, ANN NAA, AAN NAA, and AANN NAA
pcexp.push (new RegExp ("^(" + alpha1 + "{1}" + alpha2 + "?[0-9]{1,2})(\\s*)([0-9]{1}" + alpha5 + "{2})$","i"));
// Expression for postcodes: ANA NAA
pcexp.push (new RegExp ("^(" + alpha1 + "{1}[0-9]{1}" + alpha3 + "{1})(\\s*)([0-9]{1}" + alpha5 + "{2})$","i"));
// Expression for postcodes: AANA NAA
pcexp.push (new RegExp ("^(" + alpha1 + "{1}" + alpha2 + "{1}" + "?[0-9]{1}" + alpha4 +"{1})(\\s*)([0-9]{1}" + alpha5 + "{2})$","i"));
// Exception for the special postcode GIR 0AA
pcexp.push (/^(GIR)(\s*)(0AA)$/i);
// Standard BFPO numbers
// pcexp.push (/^(bfpo)(\s*)([0-9]{1,4})$/i);
// c/o BFPO numbers
// pcexp.push (/^(bfpo)(\s*)(c\/o\s*[0-9]{1,3})$/i);
// Overseas Territories
// pcexp.push (/^([A-Z]{4})(\s*)(1ZZ)$/i);
// Anguilla
// pcexp.push (/^(ai-2640)$/i);
// Load up the string to check
var postCode = toCheck;
// Assume we're not going to find a valid postcode
var valid = false;
// Check the string against the types of post codes
for ( var i=0; i<pcexp.length; i++) {
if (pcexp[i].test(postCode)) {
// The post code is valid - split the post code into component parts
pcexp[i].exec(postCode);
// Copy it back into the original string, converting it to uppercase and inserting a space
// between the inward and outward codes
postCode = RegExp.$1.toUpperCase() + " " + RegExp.$3.toUpperCase();
// If it is a BFPO c/o type postcode, tidy up the "c/o" part
postCode = postCode.replace (/C\/O\s*/,"c/o ");
// If it is the Anguilla overseas territory postcode, we need to treat it specially
if (toCheck.toUpperCase() == 'AI-2640') {postCode = 'AI-2640'};
// Load new postcode back into the form element
valid = true;
// Remember that we have found that the code is valid and break from loop
break;
}
}
// Return with either the reformatted valid postcode or the original invalid postcode
if (valid) {return postCode;} else return false;
}
$(function($){
$("#postcode").blur(function(){
var postalcode = checkPostCode($('#postcode').val());
if (postalcode) {
var geocoder = new google.maps.Geocoder();
geocoder.geocode({'address': postalcode}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var latlng = results[0].geometry.location;
var source = latlng.lat()+"|"+latlng.lng();
$('#startpoint').val(source);
} else {
alert('Geocode was not successful for the following reason: ' + status);
}
});
} else {
$('#postcode-label').after('<span class="error" style="margin-left:0.25em;">Please enter a valid UK postcode.</span>');
}
});
$("#postcode").focus(function(){
$("#postcode-label").next("span").remove();
})
});
</script>
<!-- low search form -->
<!-- channel to search must have custom fields for latitude and longitude for each entry -->
<!-- segment_3 contains unique search code from low search -->
{exp:low_search:form result_page="path_to/search-results" form_class="search-form" form_name="searchform" query="{segment_3}" channel="my_channel"}
<h2>Search by distance from postcode</h2>
{error_message}
<p><input type="hidden" id="distance" name="distance:to" value="latitude|longitude" /></p>
<fieldset class="distance-search">
<input type="hidden" name="distance:from" value="" id="startpoint" />
<p><label id="postcode-label" for="postcode">Postcode</label><br /><input type="text" name="postcode" id="postcode" /></p>
<p>
<label for="radius">Search distance:</label>
<select name="distance:radius" id="radius">
<option value="0.25">This postcode only</option>
{exp:loopee
foreach="0.5|1|2|3|5|10|20"
as="key"
parse="inward"
}
<option value="{key}"{if '{key}' == '{low_search_distance:radius}'} selected{/if}>
{key} mile radius
</option>
{/exp:loopee}
</select>
</p>
</fieldset>
<p><input type="submit" name="submit" class="button button-success" value="Search by distance from postcode" /></p>
{/exp:low_search:form}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment