Ecommerce Shopify WordPress Discussion

Using a google map auto-complete search api

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.
TurboCommerce make the better internet purchasing globaly

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

TurboCommerce make the better internet purchasing globaly
Our products

The help you need, when you need it

App by Turbo Engine

3 apps • 5.0 average rating

Turbosify Speed Booster

5.0 (7)
Get better conversions by optimizing shopify store Google page speed Installed

Turbosify Translator for Wordpress Woocommerce

5.0 (74) Free Wordpress Woocommerce Plugin
Translate your wordpress website to multiple language within 1 click, no configuration needed, no No technical required

Grow your business here

Whether you want to sell products down the street or around the world, we have all the tools you need.