Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Bert Detailleur 21 posts 122 karma points
    Apr 20, 2018 @ 10:45
    Bert Detailleur
    0

    Making a custom property editor for looking up addresses using Google Maps API

    Hi all

    I'm trying to do the following.

    I want a custom property editor that contains an address lookup feature. It consists of an input field, coupled to the GoogleMaps api. When a user clicks on an item from the autocomplete dropdown, then it fills out a small form with all the address info like so:

    https://developers.google.com/maps/documentation/javascript/examples/places-autocomplete-addressform

    I've already fiddled around on a local instance of umbraco v7. I can recreate the form in a property Editor, I can use the api in a seperate .js file and from there fill out the form. This approach gives one problem. Saving. Because in the example the input fields are manipulated by javascript, AngularJS will not count this as a change. Apparantly I cannot use functions like $setDirty() to fix this.

    How should I solve this according to umbraco convention? use the Google api in the controller en return values from there instead of a seperate javascript file? Or is the previous approach also plausible but am I missing something?

    I would love to hear your thoughts/advice on this.

    /Bert

  • Søren Gregersen 441 posts 1884 karma points MVP 2x c-trib
    Apr 20, 2018 @ 11:08
    Søren Gregersen
    100

    I think you are missing $scope.apply ? :)

    I prefer wrapping the "back and forth"-stuff in $timeout(function(){[...handler...})-blocks

    In my own directive for doing this (outside umbraco) I have:

                var options = {
                    types: [],
                    componentRestrictions: {}
                };
    
                var autocomplete = new window.google.maps.places.Autocomplete(element[0], options);
    
                autocomplete.setOptions({ strictBounds: options.strictBounds === true });
    
                window.google.maps.event.addListener(autocomplete, "place_changed", onPlaceChanged);
    
                var onPlaceChanged = function() {
                    $timeout(function() {
                        var place = autocomplete.getPlace();
                        ctrl && ctrl.$setViewValue(element.val());
                        if (scope.onPlaceChanged) {
                            scope.onPlaceChanged({ place: place });
                        }
                    });
                };
    

    The above code can then be used like

    <google-map-places-autocomple on-place-changed="myController.handleNewPlace(place)" />
    
  • Bert Detailleur 21 posts 122 karma points
    Apr 20, 2018 @ 14:25
    Bert Detailleur
    1

    I solved it as follows.

    this is the function that programmatically changes the form input fields + what I entered to get into my controller to get it to save. (starting at "var scope") (thanks for the hint about $scope.apply() !!). But this approach feels 'wrong' as it is not in the spirit of MVC...

    function fillInAddress() {
    // Get the place details from the autocomplete object.
    var place = autocomplete.getPlace();
    
    for (var component in componentForm) {
        document.getElementById(component).value = '';
        document.getElementById(component).disabled = false;
    }
    
    // Get each component of the address from the place details
    // and fill the corresponding field on the form.
    for (var i = 0; i < place.address_components.length; i++) {
        var addressType = place.address_components[i].types[0];
        if (componentForm[addressType]) {
            var val = place.address_components[i][componentForm[addressType]];
            document.getElementById(addressType).value = val;                        
        }
    }
    
    var scope = angular.element(document.getElementById(addressType)).scope();
    scope.$apply(function () {
        scope.model.value.address = document.getElementById("autocomplete").value;
        scope.model.value.streetNumber = document.getElementById("street_number").value;
        scope.model.value.route = document.getElementById("route").value;
        scope.model.value.locality = document.getElementById("locality").value;
        scope.model.value.state = document.getElementById("administrative_area_level_1").value;
        scope.model.value.zipcode = document.getElementById("postal_code").value;
        scope.model.value.country = document.getElementById("country").value;
    })
    

    }

  • Nitin Anand 46 posts 178 karma points
    Feb 10, 2020 @ 09:58
    Nitin Anand
    0

    Hi

    Where do you place the API Key (https://maps.googleapis.com/maps/api/js?key=*)

    regards Nitin

Please Sign in or register to post replies

Write your reply to:

Draft