fields: fix handling of optional item fields (#8737)
External data sources would add an empty element when the list was optional but this was not the case when using the internal elements, and things were worked around when rendering, and inserting, sometimes, the hint as a first element. This is changed to always have an empty element as first item, and replacing it with the hint when rendering.
This commit is contained in:
parent
a46d91e7d2
commit
5c21487c4c
|
@ -211,4 +211,4 @@ def test_optional_item_field_with_data_source():
|
|||
field.add_to_form(form)
|
||||
widget = form.get_widget('f1')
|
||||
assert widget is not None
|
||||
assert widget.options == [(None, '---', 'None'), ('1', 'un', '1'), ('2', 'deux', '2')]
|
||||
assert widget.options == [(None, '', 'None'), ('1', 'un', '1'), ('2', 'deux', '2')]
|
||||
|
|
|
@ -146,3 +146,30 @@ def test_map():
|
|||
assert fields.MapField().get_json_value(' 42.2 ; 10.2 ') == {'lat': 42.2, 'lon': 10.2}
|
||||
assert fields.MapField().get_json_value('') == None
|
||||
assert fields.MapField().get_json_value('foobar') == None
|
||||
|
||||
def test_item_render():
|
||||
field = fields.ItemField(id='1', label='Foobar', items=['a', 'b', 'c'])
|
||||
form = Form()
|
||||
field.add_to_form(form)
|
||||
assert str(form.render()).count('<option') == 3
|
||||
|
||||
field = fields.ItemField(id='1', label='Foobar', items=['a', 'b', 'c'],
|
||||
required=False)
|
||||
form = Form()
|
||||
field.add_to_form(form)
|
||||
assert str(form.render()).count('<option selected="selected" value="None"></option>') == 1 # None
|
||||
assert str(form.render()).count('<option') == 4 # 3 + None as first item
|
||||
|
||||
field = fields.ItemField(id='1', label='Foobar', items=['a', 'b', 'c'],
|
||||
required=False, hint='Bla bla bla')
|
||||
form = Form()
|
||||
field.add_to_form(form)
|
||||
assert str(form.render()).count('<option value="">Bla bla bla</option>') == 1 # ---
|
||||
assert str(form.render()).count('<option') == 4
|
||||
|
||||
field = fields.ItemField(id='1', label='Foobar', items=['a', 'b', 'c'],
|
||||
required=True, hint='Bla bla bla')
|
||||
form = Form()
|
||||
field.add_to_form(form)
|
||||
assert str(form.render()).count('<option value="">Bla bla bla</option>') == 1 # ---
|
||||
assert str(form.render()).count('<option') == 4
|
||||
|
|
|
@ -858,16 +858,16 @@ class ItemField(WidgetField):
|
|||
|
||||
def get_options(self):
|
||||
if not self.data_source:
|
||||
return self.items
|
||||
|
||||
options = data_sources.get_items(self.data_source)
|
||||
if options and not self.required:
|
||||
options = self.items[:]
|
||||
else:
|
||||
options = data_sources.get_items(self.data_source)
|
||||
if not self.required:
|
||||
if type(options[0]) is str:
|
||||
options[:0] = [None]
|
||||
elif len(options[0]) == 2:
|
||||
options[:0] = [(None, '---')]
|
||||
options[:0] = [(None, '')]
|
||||
elif len(options[0]) == 3:
|
||||
options[:0] = [(None, '---', None)]
|
||||
options[:0] = [(None, '', None)]
|
||||
return options
|
||||
|
||||
def perform_more_widget_changes(self, form, kwargs, edit = True):
|
||||
|
|
|
@ -1361,13 +1361,16 @@ class SingleSelectHintWidget(SingleSelectWidget):
|
|||
attrs = {'id': 'form_' + self.name}
|
||||
if self.attrs:
|
||||
attrs.update(self.attrs)
|
||||
if self.separate_hint():
|
||||
return SingleSelectWidget.render_content(self)
|
||||
tags = [htmltag('select', name=self.name, **attrs)]
|
||||
if self.hint:
|
||||
options = self.options[:]
|
||||
if not self.separate_hint() and self.hint:
|
||||
r = htmltag('option', value='', selected=None)
|
||||
tags.append(r + htmlescape(self.hint) + htmltext('</option>'))
|
||||
for object, description, key in self.options:
|
||||
if not self.required:
|
||||
# hint has been put as first element, skip the default empty
|
||||
# value.
|
||||
options = self.options[1:]
|
||||
for object, description, key in options:
|
||||
if self.is_selected(object):
|
||||
selected = 'selected'
|
||||
else:
|
||||
|
|
Loading…
Reference in New Issue