Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

VueJS2 Accessing HTML Elements within Child

I am usually using the ref keyword to access components within vue. But I seem to not have understood how I access HTML tags from within a component.

I tried:

<input type="text" ref="searchAddress" id="searchAddress" name="searchAddress" class="form-control" v-model="incidentForm.searchAddress">

and within the vue component:

var input = this.$refs.searchAddress;

but this does not work, so I assume it only works when referencing components? How do I access the input tag from within vue?

I created a class for managing all the GoogleMaps Api calls that will be included into my Vue files. Therefore I do not see a way, how I could handle accessing the data of a specific input field. What would be the right approach to avoid a direct access like this?

The full code example and being more specific: The Autocomplete Function of GoogleMaps does not return anything as I would expect. Uncaught TypeError: Cannot set property 'autocompletePlace' of undefined. this.autocompletePlace = place seems to be not working.

methods: {
        initMap: function initMap() {
            this.initialLocation = this.createInitialLocation(48.184845, 11.252553);
            this.mapSetup(this.$refs.map, this.initialLocation, function () {
                this.initAutoCompleteListener(function (place) {
                    this.autocompletePlace = place;
                });
            }.bind(this));
        }
    }

GoogleMapsApi.js

export default {
    data() {
        return {
            map: '',
            currentIncidentLocation: '',
            autocomplete: '',
            searchMarker: ''
        }
    },

    events: {
        currentIncidentLocation: function(location) {
            this.currentIncidentLocation = location;
        }
    },

    methods: {
        createInitialLocation: function(latitude, longitude) {
            return new google.maps.LatLng(latitude, longitude);
        },

        mapSetup: function(selector, initialLocation, callback) {
            this.map = new google.maps.Map(selector, {
                zoom: 10,
                mapTypeId: google.maps.MapTypeId.ROADMAP,
            });
            this.map.setCenter(initialLocation);
            this.searchMarker = this.createMarker();
            var input = document.getElementById('searchAddress');
            this.autocomplete = new google.maps.places.Autocomplete(input);
            callback();
        },

        initAutoCompleteListener: function(callback) {
            this.autocomplete.addListener('place_changed', function() {
                var place = this.autocomplete.getPlace();
                if (!place.geometry) {
                    window.alert("Der Ort konnte nicht gefunden werden");
                    return;
                }
                callback(place);
            }.bind(this));
        },

        createMarker: function() {
            var marker = new google.maps.Marker({
                map: this.map
            })
            return marker;
        }
    }
}

GISView.vue

<template>
    <div ref="map" id="map" class="google-map" style="height: 800px; position: relative; overflow: hidden;">
    </div>
</template>

<script>
    import GoogleMaps from '../mixins/GoogleMaps.js';

    export default {
        mixins: [GoogleMaps],

        data() {
            return {
                initialLocation: '',
                autocompletePlace: ''
            }
        },

        mounted() {
            this.$events.$on("MapsAPILoaded", eventData => this.initMap());
        },

        methods: {
            initMap: function() {
                this.initialLocation = this.createInitialLocation(48.184845, 11.252553);
                this.mapSetup(this.$refs.map, this.initialLocation, function() {
                    this.initAutoCompleteListener(function(place) {
                        this.autocompletePlace = place;
                    })
                }.bind(this));
            }
        }
    }
</script>
like image 395
sesc360 Avatar asked Jan 31 '26 14:01

sesc360


1 Answers

You bound the outer function, but not the inner one. Try

this.initAutoCompleteListener(function(place) {
     this.autocompletePlace = place;
}.bind(this))
like image 52
Bert Avatar answered Feb 02 '26 04:02

Bert