Place the gmap-autocomplete component of vue2-google-maps within the map

2

I'm using the "vue2-google-maps" package in an application developed with Laravel 5.7. In this case I am creating a component with the name google-map . Dendro of this component uses gmap-autocomplete and gmap-map . The component is registered in app.js and both the map and the autocomplete input work correctly. The problem is that the input is located above the map and what I want is that it is inside the map.

I am currently achieving this:

I want it to look like the following image:

This would normally be achieved (without using vue or said package) with the following lines:

let inputSearch = document.getElementById('pac-input');
searchBoxAdd = new google.maps.places.SearchBox(inputSearch );
myMap.controls[google.maps.ControlPosition.TOP_CENTER].push(searchBoxAdd );

But in this case it is not the same anymore. According to the documentation, I saw that I can access the "map" object by adding ref="mapRef" to my gmap-map component and adding

mounted () {
    this.$refs.mapRef.$mapPromise.then((map) => {
      // En este punto ya tengo mi objeto map.
    })
  }

Based on this information I tried to do the following:

mounted () {
        this.$refs.mapRef.$mapPromise.then((map) => {
          let inputSearch = document.getElementById('pac-input');
          searchBoxAdd = new google.maps.places.SearchBox(inputSearch );
        map.controls[google.maps.ControlPosition.TOP_CENTER].push(searchBoxAdd );
        })

But it still does not load the input inside the map and in the console it shows me the following error:

  

controls.js: 118 Uncaught (in promise) TypeError: Can not read property   'zIndex' of undefined

I leave my main component, which would be "google-maps"

<template>
    <div>
        <div>
            <h2>Search and add a marker</h2>
            <label>
                <div class="form-inline">
                    <gmap-autocomplete
                        class="form-control"
                        @place_changed="setPlace">
                    </gmap-autocomplete>
                    <button @click="addMarker" class="btn btn-primary btn-flat">Add</button>
                </div>
            </label>
            <br/>
        </div>
        <br>
        <gmap-map ref="mapRef"
            :center="center"
            :zoom="12"
            style="width:100%;  height: 400px;"
        >
            <gmap-marker
                :key="index"
                v-for="(m, index) in markers"
                :position="m.position"
                @click="center=m.position"
            ></gmap-marker>
        </gmap-map>
    </div>
</template>

<script>
    import {gmapApi} from 'vue2-google-maps';

    export default {
        name: "GoogleMap",

        data() {
            return {
                // default to Montreal to keep it simple
                // change this to whatever makes sense
                center: { lat: 45.508, lng: -73.587 },
                markers: [],
                places: [],
                currentPlace: null
            };
        },

        mounted() {
            this.geolocate();
        },

        methods: {
            // receives a place object via the autocomplete component
            setPlace(place) {
                this.currentPlace = place;
            },
            addMarker() {
                if (this.currentPlace) {
                    const marker = {
                        lat: this.currentPlace.geometry.location.lat(),
                        lng: this.currentPlace.geometry.location.lng()
                    };
                    this.markers.push({ position: marker });
                    this.places.push(this.currentPlace);
                    this.center = marker;
                    this.currentPlace = null;
                }
            },
            geolocate: function() {
                navigator.geolocation.getCurrentPosition(position => {
                    this.center = {
                        lat: position.coords.latitude,
                        lng: position.coords.longitude
                    };

                });
            }
        }
    };
</script>

Thanks. Greetings!

    
asked by Fran Islas 17.12.2018 в 03:50
source

2 answers

2

I already managed to solve it, I did it with the following steps:

  • Add ref="mapRef" to the gmap-map tag. With this later I will be able to access the object "map". The label should look like this:

    <gmap-map ref="mapRef"
    :center="center"
    :zoom="12"
    :options="mapOptions" // Para ocultar el control "mapTypeControl"
     style="width:100%;  height: 400px;"
    >
    </gmap-map>
    
  • My control is as follows:

     <div class="hide">
       <div class="input-group col-md-6" id="myAutocomplete">
       <div class="input-group-prepend">
           <span class="input-group-text bg-primary" id="basic-text1">
                <i class="fa fa-search text-white" aria-hidden="true"></i>
           </span>
       </div>
       <gmap-autocomplete
           class="form-control my-0 py-1"
           @place_changed="setPlace">
       </gmap-autocomplete>
       </div>
    </div>
    

    The div "father" with the class "hide" is important, otherwise the input will be displayed on the page before you finish loading the map and then it will move it inside. With this, when it is ready the map shows it in its interior directly. The rest are already styles ...

  • I will add an extra configuration to hide mapTypeControl . This NO is required.

      data() {
                return {
                    // default to Montreal to keep it simple
                    // change this to whatever makes sense
                    center: { lat: 45.508, lng: -73.587 },
                    markers: [],
                    places: [],
                    currentPlace: null,
                    mapOptions: {
                        mapTypeControl: false
                    }
                };
            },
    
  • Once the component is mounted, ie in the event " mounted() " I will use the object "map" to add my component. The code should look like this:

    mounted() {
            this.$refs.mapRef.$mapPromise.then((map) => {
                var myControl = document.getElementById('myAutocomplete');
    
                myControl.index = 1; // Esto es importante sino arroja error.
    
                map.controls[google.maps.ControlPosition.TOP_CENTER].push(myControl);
            })
        },
    
  • Once all this is done, I get the following result:

    I hope it serves someone. Greetings!

        
    answered by 18.12.2018 / 17:29
    source
    1

    According to the documentation (and javascript in general), when instantiating A new Searchbox what you get is the instance of the "class" (in this case an object).

    On the contrary, when you push something to map.controls[<ubicación>] what google maps expects is an HTMLElement. It means you could try:

    let inputSearch = document.getElementById('pac-input'),
        searchBoxAdd = new google.maps.places.SearchBox(inputSearch );
    
        map.controls[google.maps.ControlPosition.TOP_CENTER].push(inputSearch);
    

    If that does not work, I would try to detect the first event map_idle before manipulating the DOM of the map container.

        
    answered by 17.12.2018 в 13:16