I used google map auto-complete search api on my wordpress website home page and also a seperate page called find you local office. I create two short codes, one for offices and one for the form. I want to show my offices to user only in 50 miles to the user adress, also a message has been shown if the nearest office is not in 50 miles distance. I did that in my code but the calculation is not right, also when i search three to four times without refreshing the page, the offices are shown which are more than 50 miles in distance.
First Short code...
function local_offices_shortcode() {
$args = array( 'post_type' => 'local-offices', 'posts_per_page' => -1, 'orderby' => 'title', 'order' => 'ASC',);
$localOfficeQuery = new WP_Query($args);
$office_locations=array();
$output = "<div class='row your-local-office'>";
$output.='<form method="POST" action="#" class="offices-search">';
if(isset($_GET['user_address'])){
$output.='<input type="text" id="user_address" name="user_address" value="'.$_GET['user_address'].'" required>';
$output.='<input type="hidden" id="user_address_lat" name="user_address_lat" value="'.$_GET['user_address_lat'].'">
<input type="hidden" id="user_address_lng" name="user_address_lng" value="'.$_GET['user_address_lng'].'">';
}else{
$output.='<input type="text" id="user_address" name="user_address" placeholder="Enter your location" required>';
$output.='<input type="hidden" id="user_address_lat" name="user_address_lat">
<input type="hidden" id="user_address_lng" name="user_address_lng">';
}
$output.='</form>';
$output.='<h4 class="officeNotFound" style="display:none">Office not found within 50 miles. Try again later. Thank you.</h4>';
$output .= "<ul class='commentlist' id='distanceList'>";
if ($localOfficeQuery->have_posts()) {
while ($localOfficeQuery->have_posts()) {
$localOfficeQuery->the_post();
$postTitle = get_the_title();
$addressDetails=get_post_meta(get_the_ID(), "office_address", true);
$office_full_address = get_field("office_full_address", get_the_ID());
$tel=get_field("tel", get_the_ID());
$website=get_field("website", get_the_ID());
$contact_us = get_field("contact_us", get_the_ID());
//print_r($addressDetails); exit;
$lat="";
$long="";
if(isset($addressDetails["lat"])){
$lat=$addressDetails["lat"];
$long=$addressDetails["lng"];
}
$office_locations[]=array("id"=>get_the_ID(),"name"=>$postTitle, "latitude"=>$lat, "longitude"=>$long);
//print_r($office_locations);
$featured_img_url = get_the_post_thumbnail_url(get_the_ID(), 'office-map');
$output .= "<li class='offices office-".get_the_ID()."' data-distance=''>";
$output .= "<div class='image-container'>
<img src='". $featured_img_url."' />
</div>";
$output .= "<div class='title-container'><h3 class='title'>{$postTitle}</h3>";
$output .= "<p class='officefulladdress'>{$office_full_address}</p>";
$output .= "<p class='tel'>{$tel}</p>";
$output .= "<p class='distance' style='display:none;'></p>";
$output .= "<p class='website'><a href='".$website."' target='_blank'>Visit Website</a></p>";
$output .= "<p class='local-contact-us'><a href='".$contact_us."' target='_blank'>Contact Us</a></p></div>";
$output .= "</li>";
}
wp_reset_postdata();
}
$office_locations=json_encode($office_locations);
$output .= "</ul>";
$output .= "</div>";
$api_key = 'Abcdrf....';
$output.='<script src="https://maps.googleapis.com/maps/api/js?key='.$api_key.'&callback=initAutocomplete&libraries=places&v=weekly" defer ></script>
<script>
let autocomplete, address1Field, lngField, latField, mapElement, map;
function initAutocomplete() {
address1Field = document.querySelector("#user_address");
latField = document.querySelector("#user_address_lat");
lngField = document.querySelector("#user_address_lng");
let lat = latField.value;
let lng = lngField.value;
//35.6814137,-117.0419153
if( !lat ) lat = 35;
if( !lng ) lng = -117.0419153;
autocomplete = new google.maps.places.Autocomplete(address1Field, {
componentRestrictions: { country: ["GB"] },
fields: ["name", "geometry"],
});
// When the user selects an address from the drop-down, populate the
// address fields in the form.
autocomplete.addListener("place_changed", fillInAddress);
}
function fillInAddress() {
// Get the place details from the autocomplete object.
const place = autocomplete.getPlace();
if(place){
let geometry = place.geometry;
address1Field.value = place.name;
latField.value = place.geometry.location.lat();
lngField.value = place.geometry.location.lng();
}
var user_address = document.getElementById("user_address").value;
if (user_address !== "") {
// Perform postcode lookup using the Google Maps Geocoding API
var geocoding_api_url = "https://maps.googleapis.com/maps/api/geocode/json?address=" + encodeURIComponent(user_address) + "&key='.$api_key.'";
fetch(geocoding_api_url)
.then(response => response.json())
.then(result => {
if (result.results && result.results[0] && result.results[0].geometry && result.results[0].geometry.location) {
// Extract the latitude and longitude coordinates
var user_latitude = result.results[0].geometry.location.lat;
var user_longitude = result.results[0].geometry.location.lng;
// Define office locations with their coordinates
var office_locations ='.$office_locations.'
// Calculate distances and find the nearest office
var nearest_office = null;
var nearest_distance = Number.MAX_VALUE;
office_locations.forEach(function (office) {
var office_latitude = office.latitude;
var office_longitude = office.longitude;
// Calculate the distance using Haversine formula
var distance = calculateDistance(user_latitude, user_longitude, office_latitude, office_longitude);
console.log(distance);
jQuery(".office-"+office.id+" .distance").text(Math.round(distance*0.621371)+" Miles ");
jQuery(".office-"+office.id).attr("data-distance", Math.round(distance*0.621371));
sortOffices();
//jQuery("#distanceList li.offices:gt(3)").hide();
jQuery(".distance").show();
if (distance < nearest_distance) {
nearest_distance = distance;
nearest_office = office;
}
});
jQuery(".officeNotFound").hide();
if (nearest_office) {
console.log("The nearest office to your address is: " + nearest_office.name);
jQuery(".offices").hide();
if((nearest_distance*0.621371)<=50){
//jQuery(".office-"+nearest_office.id).show();
// Loop through each li element
jQuery("#distanceList li").each(function() {
// Get the data-distance attribute value
var distance = parseFloat(jQuery(this).data("distance"));
//console.log(distance);
// Check if the data-distance is less than 50
if (distance <= 50) {
console.log(distance);
// Show the li element
jQuery(this).show();
}
});
}else{
//jQuery(".officeNotFound").text("Office not found within 25 miles, The other nearest office is at "+Math.round(nearest_distance*0.621371)+" Miles");
//console.log("Office not found within 25 miles");
jQuery(".officeNotFound").show();
//jQuery(".office-"+nearest_office.id).show();
}
} else {
console.log("No offices found nearby.");
jQuery(".officeNotFound").show();
}
} else {
console.log("Invalid response from the Geocoding API.");
var user_latitude = jQuery("#user_address_lat").val();
var user_longitude = jQuery("#user_address_lng").val();
// Define office locations with their coordinates
var office_locations ='.$office_locations.'
// Calculate distances and find the nearest office
var nearest_office = null;
var nearest_distance = Number.MAX_VALUE;
office_locations.forEach(function (office) {
var office_latitude = office.latitude;
var office_longitude = office.longitude;
// Calculate the distance using Haversine formula
var distance = calculateDistance(user_latitude, user_longitude, office_latitude, office_longitude);
jQuery(".office-"+office.id+" .distance").text(Math.round(distance*0.621371)+" Miles ");
jQuery(".office-"+office.id).attr("data-distance", Math.round(distance*0.621371));
sortOffices();
//jQuery("#distanceList li.offices:gt(3)").hide();
jQuery(".distance").show();
console.log(distance);
if (distance < nearest_distance) {
nearest_distance = distance;
nearest_office = office;
}
});
jQuery(".officeNotFound").hide();
if (nearest_office) {
console.log("The nearest office to your address is: " + nearest_office.name);
jQuery(".offices").hide();
if((nearest_distance*0.621371)<=50){
//jQuery(".office-"+nearest_office.id).show();
//show all lis with distance less than 50 miles
// Loop through each li element
jQuery("#distanceList li").each(function() {
// Get the data-distance attribute value
var distance = parseFloat(jQuery(this).data("distance"));
//console.log(distance);
// Check if the data-distance is less than 50
if (distance <= 50) {
console.log(distance);
// Show the li element
jQuery(this).show();
}
});
}else{
//jQuery(".officeNotFound").text("Office not found within 25 miles, The other nearest office is at "+Math.round(nearest_distance*0.621371)+" Miles");
//console.log("Office not found within 25 miles");
jQuery(".officeNotFound").show();
//jQuery(".office-"+nearest_office.id).show();
}
} else {
console.log("No offices found nearby.");
jQuery(".officeNotFound").show();
}
}
})
.catch(error => {
console.error("Error fetching data from the Geocoding API:", error);
});
} else {
console.log("Please enter an address.");
}
}
function sortOffices(){
// Get the ul element and the list items
const distanceList = document.getElementById("distanceList");
const items = Array.from(distanceList.getElementsByTagName("li"));
// Sort the items based on the data-distance attribute
items.sort((a, b) => {
const distanceA = parseFloat(a.getAttribute("data-distance"));
const distanceB = parseFloat(b.getAttribute("data-distance"));
// Change the comparison logic based on your needs (ascending or descending)
return distanceA - distanceB;
});
// Append the sorted items back to the ul
items.forEach(item => distanceList.appendChild(item));
}
function calculateDistance(lat1, lon1, lat2, lon2) {
var radius = 3958.8; // Earths radius in Miles
var dLat = deg2rad(lat2 - lat1);
var dLon = deg2rad(lon2 - lon1);
var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) * Math.sin(dLon / 2) * Math.sin(dLon / 2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
var distance = radius * c; // Distance in Miles
return distance;
}
function deg2rad(deg) {
return deg * (Math.PI / 180);
}
window.initAutocomplete = initAutocomplete;
jQuery(document).ready(function($) {
$("#user_address").on("keyup", function() {
var inputValue = $(this).val().trim();
if (inputValue === "") {
jQuery(".offices").show();
console.log("Input field is empty");
jQuery(".officeNotFound").hide();
jQuery(".distance").text("");
removeQueryStringParameter("user_address");
removeQueryStringParameter("user_address_lat");
removeQueryStringParameter("user_address_lng");
}
});
$(".offices-search").on("submit", function(e){
e.preventDefault();
});
function removeQueryStringParameter(parameterKey) {
var url = window.location.href;
var urlParts = url.split("?");
if (urlParts.length >= 2) {
var prefix = encodeURIComponent(parameterKey) + "=";
var parts = urlParts[1].split(/[&;]/g);
// Loop through the parameters
for (var i = parts.length; i-- > 0;) {
// Remove the parameter if found
if (parts[i].lastIndexOf(prefix, 0) !== -1) {
parts.splice(i, 1);
}
}
// Update the URL without the specified parameter
url = urlParts[0] + (parts.length > 0 ? "?" + parts.join("&") : "");
// Update the browsers address bar
window.history.replaceState({}, document.title, url);
}
}
});
</script>
';
if(isset($_GET['user_address'])){
$output.='
<script>jQuery(document).ready(function($) {
fillInAddress();
});
</script>';
}
}
add_shortcode('local_offices', 'local_offices_shortcode');
Second short code...
/*shortcode for form only */
function local_offices_form_shortcode() {
$output='<form method="GET" action="'.site_url().'/your-local-office" class="offices-search">
<input type="text" id="user_address" name="user_address" placeholder="Find your local office...." required>
<input type="hidden" id="user_address_lat" name="user_address_lat">
<input type="hidden" id="user_address_lng" name="user_address_lng">
</form>';
$api_key = 'abcdef.......';
$output.='<script src="https://maps.googleapis.com/maps/api/js?key='.$api_key.'&callback=initAutocomplete&libraries=places&v=weekly" defer ></script>
<script>
let autocomplete, address1Field, lngField, latField, mapElement, map;
function initAutocomplete() {
address1Field = document.querySelector("#user_address");
latField = document.querySelector("#user_address_lat");
lngField = document.querySelector("#user_address_lng");
let lat = latField.value;
let lng = lngField.value;
//35.6814137,-117.0419153
if( !lat ) lat = 35;
if( !lng ) lng = -117.0419153;
// Prevent form submission on Enter keypress in the address input field
address1Field.addEventListener("keypress", function(e) {
if (e.key === "Enter") {
e.preventDefault();
}
});
autocomplete = new google.maps.places.Autocomplete(address1Field, {
componentRestrictions: { country: ["GB"] },
fields: ["name", "geometry"],
});
// When the user selects an address from the drop-down, populate the
// address fields in the form.
autocomplete.addListener("place_changed", fillInAddress);
}
function fillInAddress() {
// Get the place details from the autocomplete object.
const place = autocomplete.getPlace();
let geometry = place.geometry;
address1Field.value = place.name;
latField.value = place.geometry.location.lat();
lngField.value = place.geometry.location.lng();
var user_address = document.getElementById("user_address").value;
jQuery(".offices-search").submit();
}
window.initAutocomplete = initAutocomplete;
</script>
';
return $output;
}
add_shortcode('local_offices_form', 'local_offices_form_shortcode');
From this code i was expecting the calculation to be correct and upon every search the offices are shown in 50 miles distance only. No office to show in more than 50 miles distance.
Turbo Multi-language Translator
Make the better internet purchasing globaly
Turbosify SEO Speed Booster
5.0 (7)•Free plan available
Get better conversions by improving store loading speed
Installed
Turbo Multi-language Chat - AI Customer service in one hand