From a48749a2c0f1735c46d4a842af637b32604dcced Mon Sep 17 00:00:00 2001
From: Serghei Mihai <smihai@entrouvert.com>
Date: Wed, 3 Nov 2021 11:09:26 +0100
Subject: [PATCH 2/2] geolocation: add support for multiple address
 autocompletion widgets (#57792)

---
 wcs/qommon/static/js/qommon.geolocation.js    | 112 ++++++++++--------
 .../forms/widgets/select_jsonp--address.html  |   2 +-
 2 files changed, 66 insertions(+), 48 deletions(-)

diff --git a/wcs/qommon/static/js/qommon.geolocation.js b/wcs/qommon/static/js/qommon.geolocation.js
index 12d6eda7..aed26636 100644
--- a/wcs/qommon/static/js/qommon.geolocation.js
+++ b/wcs/qommon/static/js/qommon.geolocation.js
@@ -1,9 +1,12 @@
-$(function() {
-function geoloc_prefill(element_type, element_value)
+function geoloc_prefill(element_type, element_value, widget_name=null)
 {
-  $('div[data-geolocation="' + element_type +'"] input').val(element_value);
-  $('div[data-geolocation="' + element_type +'"] textarea').val(element_value);
-  var $options = $('div[data-geolocation="' + element_type +'"] option');
+  var selector = 'div[data-geolocation="' + element_type +'"]:first';
+  if (widget_name) {
+    selector = 'div[data-widget-name="' + widget_name + '"] ~ ' + selector;
+  }
+  $(selector).find('input').val(element_value);
+  $(selector).find('textarea').val(element_value);
+  var $options = $(selector).find('option');
   if ($options.length == 0) return;
 
   var slugified_value = $.slugify(element_value);
@@ -24,6 +27,62 @@ function geoloc_prefill(element_type, element_value)
   }
 }
 
+function init_sync_from_template_address() {
+  const widget_selector = '.JsonpSingleSelectWidget.template-address';
+  $(widget_selector + ' select').on('change', function() {
+    var data = $(this).select2('data');
+    var widget_name = $(this).parents('div.widget').data('widget-name');
+    if (data) {
+      var number_and_street = null;
+      var address = undefined;
+      if (typeof data[0].address == "object") {
+        address = data[0].address;
+      } else {
+        address = data[0];
+      }
+      var road = address.road || address.nom_rue;
+      var house_number = address.house_number || address.numero;
+      var city = address.city || address.nom_commune;
+      var postcode = address.postcode || address.code_postal;
+      if (house_number && road) {
+        number_and_street = house_number + ' ' + road;
+      } else {
+        number_and_street = road;
+      }
+      geoloc_prefill('number-and-street', number_and_street, widget_name);
+      geoloc_prefill('house', house_number, widget_name);
+      geoloc_prefill('road', road, widget_name);
+      geoloc_prefill('city', city, widget_name);
+      geoloc_prefill('postcode', postcode, widget_name);
+      geoloc_prefill('country', address.country, widget_name);
+    }
+  });
+
+  $('input.wcs-manual-address').on('change', function() {
+    var widget = $(this).parents('div.widget');
+    widget.nextUntil(widget_selector, 'div[data-geolocation]').find('input').attr('readonly', this.checked ? null : 'readonly');
+    widget.nextUntil(widget_selector, 'div[data-geolocation]').find('textarea').attr('readonly', this.checked ? null : 'readonly');
+    if (this.checked) {
+      widget.nextUntil(widget_selector, 'div[data-geolocation]:not(.template-address)').attr('hidden', null)
+    } else if ($(widget_selector + '.hide-address-parts').length) {
+      widget.nextUntil(widget_selector, 'div[data-geolocation]:not(.template-address)').attr('hidden', 'hidden')
+    }
+  });
+
+  if ($(widget_selector).length) {
+    $('div[data-geolocation] input, div[data-geolocation] textarea').attr('readonly', 'readonly')
+    if ($(widget_selector + '.hide-address-parts').length) {
+      $('div[data-geolocation]:not(.template-address)').attr('hidden', 'hidden')
+    }
+  }
+}
+
+
+$(function() {
+  init_sync_from_template_address();
+  $('form').on('wcs:block-row-added', function() {
+    init_sync_from_template_address();
+  });
   $(document).on('set-geolocation', function(event, coords, options) {
     $.getJSON(WCS_ROOT_URL + '/api/reverse-geocoding?lat=' + coords.lat + '&lon=' + coords.lng, function(data) {
       unset_sync_callback()
@@ -67,33 +126,7 @@ function geoloc_prefill(element_type, element_value)
       set_sync_callback()
     });
   });
-  $('.JsonpSingleSelectWidget.template-address select').on('change', function() {
-    var data = $('.JsonpSingleSelectWidget.template-address select').select2('data');
-    if (data) {
-      var number_and_street = null;
-      var address = undefined;
-      if (typeof data[0].address == "object") {
-        address = data[0].address;
-      } else {
-        address = data[0];
-      }
-      var road = address.road || address.nom_rue;
-      var house_number = address.house_number || address.numero;
-      var city = address.city || address.nom_commune;
-      var postcode = address.postcode || address.code_postal;
-      if (house_number && road) {
-        number_and_street = house_number + ' ' + road;
-      } else {
-        number_and_street = road;
-      }
-      geoloc_prefill('number-and-street', number_and_street);
-      geoloc_prefill('house', house_number);
-      geoloc_prefill('road', road);
-      geoloc_prefill('city', city);
-      geoloc_prefill('postcode', postcode);
-      geoloc_prefill('country', address.country);
-    }
-  });
+
   if ($('.qommon-map').length == 0 && $('.JsonpSingleSelectWidget.template-address').length == 0) {
     /* if there's no map on the page, we do the geolocation without leaflet. */
     if (navigator.geolocation) {
@@ -113,21 +146,6 @@ function geoloc_prefill(element_type, element_value)
       );
     }
   }
-  if ($('.JsonpSingleSelectWidget.template-address').length) {
-    $('div[data-geolocation] input, div[data-geolocation] textarea').attr('readonly', 'readonly')
-    if ($('.JsonpSingleSelectWidget.template-address.hide-address-parts').length) {
-      $('div[data-geolocation]:not(.template-address)').attr('hidden', 'hidden')
-    }
-  }
-
-  $('#wcs-manual-address').on('change', function() {
-    $('div[data-geolocation] input, div[data-geolocation] textarea').attr('readonly', this.checked ? null : 'readonly');
-    if (this.checked) {
-      $('div[data-geolocation]:not(.template-address)').attr('hidden', null)
-    } else if ($('.JsonpSingleSelectWidget.template-address.hide-address-parts').length) {
-      $('div[data-geolocation]:not(.template-address)').attr('hidden', 'hidden')
-    }
-  });
 
   function set_sync_callback() {
     var $map = $('.qommon-map');
diff --git a/wcs/qommon/templates/qommon/forms/widgets/select_jsonp--address.html b/wcs/qommon/templates/qommon/forms/widgets/select_jsonp--address.html
index 76398d79..64749488 100644
--- a/wcs/qommon/templates/qommon/forms/widgets/select_jsonp--address.html
+++ b/wcs/qommon/templates/qommon/forms/widgets/select_jsonp--address.html
@@ -4,7 +4,7 @@
 {{ block.super }}
 {% if not widget.readonly %}
 <div>
-<label><input id="wcs-manual-address" type="checkbox"><span>{% trans "If you cannot find this address in the list you can check this box to manually enter it." %}</span></label>
+<label><input class="wcs-manual-address" type="checkbox"><span>{% trans "If you cannot find this address in the list you can check this box to manually enter it." %}</span></label>
 </div>
 {% endif %}
 {% endblock %}
-- 
2.33.1

