Generate a radius search of custom post type locations

Alright so I've been searching for days and driving myself crazy looking for a solution. I want to create a search function that will allow the user to search for the companies locations that are closest to a location they enter. I already have a custom post type locations and I'm using the advanced custom fields plugin. With ACF I can get the longitude and latitude of a location.

Here is the loop that I have so far. Right now I have it set so the locations are organized by category and you can click on each category and it will show you the locations related to that category. That part I figured out.

?php wp_reset_postdata();
// WP_Query arguments
$args = array (
    'post_parent' = 0,
    'post_type'             = 'locations',
    'posts_per_page'        =  -1,
    'order'                 = 'ASC'
);

// The Query
$query = new WP_Query( $args );
?
?php if ( $query-have_posts() ) : ?
    div class="col-lg-4 col-md-4 col-sm-12 col-xs-12 locations-nav-container"
        div class="col-lg-12 col-md-12 col-sm-3 col-xs-12 location-btn" data-nav="view-all"
            div class="outer"
                div class="inner"
                    View All
                /div
            /div
        /div

        ?php while ( $query-have_posts() ) : $query-the_post(); ?
            ?php
                // vars
                $title = get_the_title();
                $slug = slugify($title);
            ?
                div class="col-lg-12 col-md-12 col-sm-3 col-xs-12 location-btn" data-nav="?php echo $slug; ?"
                    div class="outer"
                        div class="inner"
                            ?php echo $title; ?
                        /div
                    /div
                /div
            ?php endwhile; ?
    /div
?php endif; ?
?php wp_reset_postdata();
// WP_Query arguments
$args = array(
    'post_type' = 'locations',
    'posts_per_page' = -1,
    'post_status' = 'publish',
    'order' = 'ASC',
    'paged' = $paged,
    'post_parent__not_in' = array(0)
);
$loop = new WP_Query( $args );
?
?php if ( $loop-have_posts()): ?
div class="col-lg-8 col-md-8 col-sm-12 col-xs-12 map-container"
    div class="map"
        ?php while ( $loop-have_posts() ) : $loop-the_post();
            $location = get_field('map');
            $title = get_the_title();
            $link = get_the_permalink();
            $terms = get_the_terms( $post-ID, 'dermcare_location_tags' );
            $area = slugify(get_the_title(wp_get_post_parent_id($post-ID)));
        ?
            div class="marker" data-lat="?php echo $location['lat']; ?" data-lng="?php echo $location['lng']; ?" data-area="?php echo $area; ?"
                div class="info-window"
                    ?php foreach ($terms as $term):?
                        h4?php echo $term-name; ?/h4
                    ?php endforeach; ?
                    ?php echo $location['address']; ?
                    br/
                    a href="?php echo $link; ?"
                        Learn More +
                    /a
                /div
            /div
        ?php endwhile; ?
    /div
/div

So with this I can generate a map with all of the locations on it. I want to be able to have a input field where the customer can enter their location and see the company locations that are closest to them.

This is the javascript I am using for the map:

'use strict';

(function ($) {

function new_map($el) {
    var $markers = $el.find('.marker');
    var args = {
        zoom: 14,
        center: new google.maps.LatLng(0, 0),
        scrollwheel: false,
        navigationControl: false,
        mapTypeControl: false,
        scaleControl: false,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    };

    var map = new google.maps.Map($el[0], args);
    map.markers = [];
    map.infowindows = [];

    // add markers
    $markers.each(function () {
        add_marker($(this), map);
    });

    center_map(map);
    return map;
}

function center_map(map) {

    var bounds = new google.maps.LatLngBounds();

    $.each(map.markers, function (i, marker) {
        var latlng = new google.maps.LatLng(marker.position.lat(), marker.position.lng());
        bounds.extend(latlng);
    });

    if (map.markers.length == 1) {
        map.setCenter(bounds.getCenter());
        map.setZoom(14);
    } else {
        map.fitBounds(bounds);
    }
}

function add_marker($marker, map) {

    var path = '';
    if(window.location.hostname == 'localhost'){
        path = '/fadc-wordpress-theme';
    }

    // var
    var latlng = new google.maps.LatLng($marker.attr('data-lat'), $marker.attr('data-lng'));
    var base = path + '/wp-content/themes/fadc/assets/images/';
    // var area = new ($marker.attr('data-area'));
    // create marker
    var marker = new google.maps.Marker({
        position: latlng,
        map: map,
        icon: base + 'non-active-pin.png',
        category: $marker.attr('data-area'),
        clickable: false
    });

    // add to array
    map.markers.push(marker);

    // Control Map Pin State
    google.maps.event.addListener(marker, 'click', function () {
        for (var j = 0; j  map.markers.length; j++) {
            if(map.markers[j].clickable != true){
                map.markers[j].setIcon(base + 'non-active-pin.png');
            }else{
                map.markers[j].setIcon(base + 'available-pin.png');
            }
            marker.setIcon(base + 'pin.png');
        }
    });

    // if marker contains HTML, add it to an infoWindow
    if ($marker.html()) {

        // create info window
        var infowindow = new google.maps.InfoWindow({
            content: $marker.html()
        });

        map.infowindows.push(infowindow);

        // show info window when marker is clicked
        google.maps.event.addListener(marker, 'click', function () {
            for (var i = 0; i  map.infowindows.length; i++) {
              map.infowindows[i].close();
            }
            infowindow.open(map, marker);
        });
    }

    $('.locations-nav-container  div').on('click', function(e){
        e.preventDefault();
        var nav = $(this).attr('data-nav');
        var infowindow;

        $('div').removeClass('active');
        $(this).addClass('active');

        for (var i = 0; i  map.infowindows.length; i++) {
          map.infowindows[i].close();
        }

        for (var j = 0; j  map.markers.length; j++) {
            map.markers[j].setIcon(base + 'non-active-pin.png');
            map.markers[j].setClickable(false);
            if(map.markers[j].category == nav || nav == 'view-all'){
                map.markers[j].setIcon(base + 'available-pin.png');
                map.markers[j].setClickable(true);
            }
        }

    });
}

var map = null;

$(document).ready(function () {
    $('.map').each(function () {
        map = new_map($(this));
    });
    $('.locations-nav-container  div:first-child').trigger('click');
});
})(jQuery);

Topic advanced-custom-fields google-maps php location-search Wordpress javascript

Category Web

About

Geeks Mental is a community that publishes articles and tutorials about Web, Android, Data Science, new techniques and Linux security.