Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Kimmer's avatar

Vue.js & Google Maps Api - button @click in Infowindow

I was hoping anyone can help me out with making a @click action work on a button inside a Google Maps Infowindow.

In a vue.js component I have a button in Google Maps API Infowindow. Like this

<script>
    export default {
        data: function () {
            return {
                map: null,
                infoWindow: {},
            }
        },
        created() {
            Event.listen('MapsApiLoaded', function(value){
                this.createMap();
            }.bind(this));
        },
        methods: {
            // create map
            createMap: function () {
                const element = this.$refs.map;
                const options = {
                    zoom: 7,
                    center: new google.maps.LatLng(9.625482,-84.029368)
                }
                this.map = new google.maps.Map(element, options);
                this.addMarker();
            },
            // Add marker
            addMarker: function(latLng) {
                this.marker = new google.maps.Marker({
                    position: new google.maps.LatLng(9.990378,-85.252195),
                    draggable:true,
                    map: this.map
                });
                this.marker.setMap(this.map);
                this.addInfoWindow();
            },
            // Add infowindow
            addInfoWindow: function () {
                this.infoWindow = new google.maps.InfoWindow({
                    size: new google.maps.Size(150, 50)
                });
                var contentString = '<button type="button" @click="openDialog()">This is a button</button>';
                this.infoWindow.setContent(contentString);
                this.infoWindow.open(this.map, this.marker);
            },
            // Method to be reached by click event on button in InfoWindow
            openDialog: function () {
                console.log('openDialog');
            }
        },
    };
</script>

I'm trying to reach the "openDialog" method but the @click event does not work.

How can I trigger the "openDialog" method by clicking the button in the Infowindow?

Thanks a lot in advance.

0 likes
1 reply
Kimmer's avatar
Kimmer
OP
Best Answer
Level 4

I seems vm.$mount() was the solution to my issue. https://vuejs.org/v2/api/#vm-mount

I added this to my app.js file

var infoWindowButton = Vue.extend({
  template: '<button type="button" @click="infoWindowButtonClicked()">This is a button</button></div>',
  methods : {
    infoWindowButtonClicked : function() {
      Event.fire('infoWindowButtonClicked'); 
    }
  }
})
Event.fire('infoWindowButton', new infoWindowButton().$mount()); 

And updated the above component to:

<template>
    <div class="map-container" ref="map"></div>
</template>

<script>
    export default {
        data: function () {
            return {
                map: null,
                infoWindow: {},
                infoWindowButton: '', // NEW
            }
        },
        created() {
            Event.listen('MapsApiLoaded', function(value){
                this.createMap();
            }.bind(this));
             // NEW
            Event.listen('infoWindowButton', function(component){
                this.infoWindowButton = component;
            }.bind(this));
            // NEW
            Event.listen('infoWindowButtonClicked', function(){
                this.openDialog();
            }.bind(this));
        },
        methods: {
            // create map
            createMap: function () {
                const element = this.$refs.map;
                const options = {
                    zoom: 7,
                    center: new google.maps.LatLng(9.625482,-84.029368)
                }
                this.map = new google.maps.Map(element, options);
                this.addMarker();
            },
            // Add marker
            addMarker: function(latLng) {
                this.marker = new google.maps.Marker({
                    position: new google.maps.LatLng(9.990378,-85.252195),
                    draggable:true,
                    map: this.map
                });
                this.marker.setMap(this.map);
                this.addInfoWindow();
            },
            // Add infowindow
            addInfoWindow: function () {
                this.infoWindow = new google.maps.InfoWindow({
                    size: new google.maps.Size(150, 50)
                });
                // VARIABLE UPDATED
                // var contentString = '<button type="button" @click="openDialog()">This is a button</button>';
                var contentString = this.infoWindowButton.$el;

                this.infoWindow.setContent(contentString);
                this.infoWindow.open(this.map, this.marker);
            },
            // Method to be reached by click event on button in InfoWindow
            openDialog: function () {
                console.log('openDialog');
            }
        },
    };
</script>

Note the env "infoWindowButton" data variable, the two event listeners in "created()" and the updated "contentString" variable.

Not related to this issue but to make my solution complete, events are handled by a small event wrapper which is also in my app.js

window.Event = new class {

  constructor() {
    this.vue = new Vue();
  }

  fire(event, data = null, action) {
    this.vue.$emit(event, data, action);
  }

  listen(event, callback) {
    this.vue.$on(event, callback)
  }

}

Please or to participate in this conversation.