Welcome to the LimeSurvey Community Forum

Ask the community, share ideas, and connect with other LimeSurvey users!

Google Maps default location based on previous answer

  • jgarton77
  • jgarton77's Avatar Topic Author
  • Offline
  • New Member
  • New Member
More
9 years 3 months ago #114880 by jgarton77
I would like to have the user be able to put in a rough address or county and have the Google maps default to that approximate location, then prompting them to adjust the pin to a more detailed location.

Working on an online permit application process where the user should be able to pick the location of the proposed project.

Thank you for any tips!
The topic has been locked.
  • tpartner
  • tpartner's Avatar
  • Away
  • LimeSurvey Community Team
  • LimeSurvey Community Team
More
9 years 3 months ago #114909 by tpartner
You could use the Google Maps Geocoding Service .

Place a new short-text question directly before the map question and then place this script in the source of the map question. The script adds a button to the new short-text that, when clicked, geocodes the input address and moves the map and marker accordingly.

Code:
<script type="text/javascript" charset="utf-8">  
  $(document).ready(function() {
 
    // Identify the elements
    var mapQ = $('#question{QID}');
    var mapInput = $('input.text.location', mapQ);
    var mapSGQA = mapInput.attr('id').replace(/answer/, '').replace(/_c/, '');
    var map = gmaps[mapSGQA+'_c'];
    var marker = gmaps['marker__'+mapSGQA+'_c'];
    var addressQ = mapQ.prevAll('.text-short:eq(0)');
    var addressInput = $('input.text', addressQ);
 
    // Add a "Search" button
    addressInput.after('<button class="geocode" type="button">Move Map</button>');
 
    // Wait for the maps to load
    google.maps.event.addListenerOnce(map, 'idle', function(){
 
      // Initialize geocoder
      var geocoder = new google.maps.Geocoder();
 
      // Geocode look-up function
      function codeAddress() {
        var address = addressInput.val();
        geocoder.geocode( { 'address': address}, function(results, status) {
          if (status == google.maps.GeocoderStatus.OK) {
            // Move the map and marker
            map.setCenter(results[0].geometry.location);
            marker.setPosition(results[0].geometry.location);
            // Record the new position
            mapInput.val(Math.round(results[0].geometry.location.lat()*10000)/10000 + " " + Math.round(results[0].geometry.location.lng()*10000)/10000);
          } 
          else {
            alert("The search was not successful for the following reason: " + status);
          }
        });
      }
 
      $('button.geocode').click(function(e) {
        codeAddress();
      });
    });
  });
</script>


Here's a working sample survey:

File Attachment:

File Name: limesurvey...5976.lss
File Size:15 KB

Cheers,
Tony Partner

Solutions, code and workarounds presented in these forums are given without any warranty, implied or otherwise.
The following user(s) said Thank You: jgarton77
The topic has been locked.
More
5 years 9 months ago #168938 by aperantogalasio
Replied by aperantogalasio on topic Google Maps default location based on previous answer
Hi tpartner,

I am struggling with your code. It works fine, it geocodes and populates the text field with LAT LON coordinates.

Issue is: If I don't move the marker anymore by hand after the automatic javascript geocoding, limesurvey will not save the position stored in the text field of this question. The text field is filled, but the position not written to the database.

I am struggling to understand why - it must have something to do with the way google maps questions are implemented in limesurvey. I would be grateful for a quick helping hand here. Thanks!

LimeSurvey
Version 3.7.1+180424
The topic has been locked.
More
5 years 9 months ago #168947 by aperantogalasio
Replied by aperantogalasio on topic Google Maps default location based on previous answer
OK, I figured the solution out myself. The above code only populates the text field. If you don't move the marker anymore after doing so, you need to write the values to the database as well.

Specifically this line is missing:
Code:
$('#answer{SGQ}').val(Math.round(results[0].geometry.location.lat()*10000)/10000 + ';' + Math.round(results[0].geometry.location.lng()*10000)/10000);

See full and working code example here. With the new {SGQ} identifier, you could shorten this code even more.
Code:
<script type="text/javascript" charset="utf-8">  
  $(document).ready(function() {
 
    // Identify the elements
    var mapQ = $('#question{QID}');
    var mapInput = $('input.text.location', mapQ);
    var mapSGQA = mapInput.attr('id').replace(/answer/, '').replace(/_c/, '');
    var map = gmaps[mapSGQA+'_c'];
    var marker = gmaps['marker__'+mapSGQA+'_c'];
    var addressQ = mapQ.prevAll('.text-short:eq(0)');
    var addressInput = $('input.text', addressQ);
 
 
    // Wait for the maps to load
    google.maps.event.addListenerOnce(map, 'idle', function(){
 
      // Initialize geocoder
      var geocoder = new google.maps.Geocoder();
 
      // Geocode look-up function
      function codeAddress() {
        var address = "{PERSDATA_PD002} Steyregg";
        geocoder.geocode( { 'address': address}, function(results, status) {
          if (status == google.maps.GeocoderStatus.OK) {
            // Move the map and marker
            map.setCenter(results[0].geometry.location);
            marker.setPosition(results[0].geometry.location);
              map.panTo(marker.getPosition())
            // Record the new position
            mapInput.val(Math.round(results[0].geometry.location.lat()*10000)/10000 + " " + Math.round(results[0].geometry.location.lng()*10000)/10000);
            $('#answer{SGQ}').val(Math.round(results[0].geometry.location.lat()*10000)/10000 + ';' + Math.round(results[0].geometry.location.lng()*10000)/10000);
          } 
          else {
            alert("Automatische Adresssuche nicht erfolgreich. Fehler: " + status);
          }
        });
      }
 
 
      codeAddress();
 
    });
  });
</script>
The topic has been locked.

Lime-years ahead

Online-surveys for every purse and purpose