Integrating PHP into Javascript to display map markers with Google API

Update 2:

<?php
$storeData = [];
$args = ['post_type' => 'store'];
$loop = new WP_Query($args);
foreach ($loop->posts as $post) {
    $storeData[] = [
        'title' => apply_filters('the_title', $post->post_title),
        'lat' => types_render_field('lat', ['output' => 'raw']),
        'long' => types_render_field('long', ['output' => 'raw']),
    ];
}
wp_localize_script('jquery-core', 'storeData', $storeData);
?>

<?php get_header(); ?>

<!-- Row for main content area -->
<div class="small-12 large-12 columns" id="content" role="main">

<h1 class="entry-title">Find a store</h1>

    <div id="map"></div>

    <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB2ealUwmPEEdwZXFBAAcc7tiQLAl-Tys4&callback=initMap" async defer></script>

    <script type="text/javascript">
        var map = new google.maps.Map(document.getElementById('map'), {
            zoom: 5,
            center: new google.maps.LatLng(-27.2758488, 26.1128267),
            mapTypeId: google.maps.MapTypeId.ROADMAP
        });
        var infowindow = new google.maps.InfoWindow();
        var marker, i;
        var j = storeData.length;
        function initMap() {
            for (i = 0; i < j; i++) {
                marker = new google.maps.Marker({
                    position: new google.maps.LatLng(storeData[i].lat, storeData[i].long),
                    map: map
                });

                google.maps.event.addListener(marker, 'click', (function(marker, i) {
                    return function() {
                        infowindow.setContent(storeData[i].title);
                        infowindow.open(map, marker);
                    }
                })(marker, i));
            }
        };
    </script>

</div>

<?php get_footer(); ?>

Update 1:

This is all you need:

<?php
$storeData = [];
$args = array('post_type' => 'store');
$loop = new WP_Query($args);
foreach ( $loop->posts as $post ) {
    $storeData[] = [
        'title' => apply_filters('the_title', $post->post_title),
        'lat'   => types_render_field('lat', array('output'=>'raw')),
        'long'  => types_render_field('long', array('output'=>'raw'))
    ];
}
wp_localize_script('jquery-core', 'storeData', $storeData);
?>

<?php get_header(); ?>

<!-- Row for main content area -->
<div class="small-12 large-12 columns" id="content" role="main">

<h1 class="entry-title">Find a store</h1>

    <div id="map"></div>

    <script src="https://maps.googleapis.com/maps/api/..." async defer></script>

    <script type="text/javascript">
        var map;
        function initMap() {
            map = new google.maps.Map(document.getElementById('map'), {
                center: {lat: -28.5758488, lng: 25.1128267},
                zoom: 5
            });
            var j = storeData.length;
            for (var i=0; i<j; i++) {
                var marker=new google.maps.Marker({
                    position: new google.maps.LatLng({lat: storeData[i].lat, lng: storeData[i].long}),
                    map: map,
                    title: storeData[i].title
                });
            }
        };
    </script>

</div>

Problem: In initMap() callback, you call setMarkers(map) only once. But inside the loop, you have more than one setMarkers(map) function. Then only the last setMarkers(map) function will be called by initMap() which displays the last store only.

Solution: The best solution is using wp_localize_script() to localize stores’ data to a registered script:

You must do this at the beginning of the template:

$storeData = [];

foreach ($loop->posts as $post) {
    $storeData[] = [
        'title' => apply_filters('the_title', $post->post_title),
        'lat'   => types_render_field('lat', array('output'=>'raw')),
        'long'  => types_render_field('long', array('output'=>'raw'))
    ];
}

wp_localize_script('jquery-core', 'storeData', $storeData);

Now, inside initMap() function, render each store data in storeData array:

for (var i=0; i<j; i++) {
    var marker=new google.maps.Marker({
        position: new google.maps.LatLng({lat: storeData[i].lat, lng: storeData[i].long}),
        map: map,
        title: storeData[i].title
    });
}

Leave a Comment