forms: allow prefilling a map field with an address (#23293)

This commit is contained in:
Frédéric Péters 2018-05-25 14:24:16 +02:00
parent a30fae2d11
commit 83c4f1f956
3 changed files with 39 additions and 2 deletions

View File

@ -3419,6 +3419,26 @@ def test_form_map_field_back_and_submit(pub):
data = formdef.data_class().get(data_id)
assert data.data == {'1': 'bla', '0': '1.234;-1.234'}
def test_form_map_field_prefill_address(pub):
formdef = create_formdef()
formdef.fields = [
fields.PageField(id='0', label='1st page', type='page'),
fields.StringField(id='1', label='address', required=True, varname='address'),
fields.PageField(id='2', label='2nd page', type='page'),
fields.MapField(id='3', label='map',
prefill={'type': 'string', 'value': '{{ form_var_address }}'}),
]
formdef.store()
resp = get_app(pub).get('/test/')
formdef.data_class().wipe()
resp.form['f1'] = '169 rue du chateau, paris'
with mock.patch('wcs.wf.geolocate.http_get_page') as http_get_page:
http_get_page.return_value = (None, 200,
json.dumps([{'lat':'48.8337085','lon':'2.3233693'}]), None)
resp = resp.form.submit('submit')
assert resp.form['f3$latlng'].value == '48.8337085;2.3233693'
assert 'chateau' in http_get_page.call_args[0][0]
def test_form_map_multi_page(pub):
formdef = create_formdef()
formdef.fields = [fields.PageField(id='0', label='1st page', type='page'),

View File

@ -61,7 +61,7 @@ class PrefillSelectionWidget(CompositeWidget):
options = [x for x in options if x[0] in ('none', 'formula')]
elif field and field.type == 'map':
# limit choices to geolocation
options = [x for x in options if x[0] in ('none', 'geolocation')]
options = [x for x in options if x[0] in ('none', 'string', 'geolocation')]
self.add(SingleSelectWidget, 'type', options=options, value=value.get('type'),
attrs={'data-dynamic-display-parent': 'true'})
@ -1993,6 +1993,20 @@ class MapField(WidgetField):
'min_zoom', 'max_zoom', 'default_position',
'init_with_geoloc']
def get_prefill_value(self, user=None, force_string=True):
if self.prefill.get('type') != 'string' or not self.prefill.get('value'):
return (None, False)
# string is actually interpreted as a template of a string that will be
# geocoded
from wcs.wf.geolocate import GeolocateWorkflowStatusItem
geolocate = GeolocateWorkflowStatusItem()
geolocate.method = 'address_string'
geolocate.address_string = self.prefill.get('value')
coords = geolocate.geolocate_address_string(None)
if not coords:
return (None, False)
return ('%(lat)s;%(lon)s' % coords, False)
def get_view_value(self, value):
widget = self.widget_class('x%s' % random.random(), value, readonly=True)
return widget.render_widget_content()

View File

@ -371,7 +371,10 @@ class FormPage(Directory):
if verified:
form.get_widget('f%s' % k).readonly = 'readonly'
form.get_widget('f%s' % k).attrs['readonly'] = 'readonly'
req.form['f%s' % k] = v
if field.key == 'map':
req.form['f%s$latlng' % k] = v
else:
req.form['f%s' % k] = v
one = True
if not one: