forms: put item display value in session for select2 use (#45438)

This commit is contained in:
Frédéric Péters 2020-07-24 09:42:59 +02:00
parent 38ad83615d
commit dd74381365
2 changed files with 79 additions and 1 deletions

View File

@ -2324,6 +2324,76 @@ def test_form_multi_page_post_edit(pub):
assert logged_error.occurences_count == 2
def test_form_edit_autocomplete_list(pub):
user = create_user(pub)
NamedDataSource.wipe()
data_source = NamedDataSource(name='foobar')
data_source.data_source = {'type': 'json', 'value': 'http://remote.example.net/json'}
data_source.query_parameter = 'q'
data_source.id_parameter = 'id'
data_source.store()
formdef = create_formdef()
formdef.data_class().wipe()
formdef.fields = [
fields.ItemField(id='0', label='string', type='item',
data_source={'type': 'foobar'},
display_mode='autocomplete',
),
]
formdef.store()
workflow = Workflow(name='test')
st1 = workflow.add_status('Status1', 'st1')
editable = EditableWorkflowStatusItem()
editable.id = '_editable'
editable.by = ['_submitter', '_receiver']
st1.items.append(editable)
editable.parent = st1
workflow.store()
formdef.workflow_id = workflow.id
formdef.store()
app = get_app(pub)
login(app, username='foo', password='foo')
with mock.patch('wcs.qommon.misc.urlopen') as urlopen:
data = {'data': [{'id': '1', 'text': 'hello', 'extra': 'foo'},
{'id': '2', 'text': 'world', 'extra': 'bar'}]}
urlopen.side_effect = lambda *args: StringIO(json.dumps(data))
resp = app.get('/test/')
assert 'data-select2-url=' in resp.text
# simulate select2 mode, with qommon.forms.js adding an extra hidden widget
resp.form.fields['f0_display'] = Hidden(form=resp.form, tag='input', name='f0_display', pos=10)
resp.form['f0'].force_value('1')
resp.form.fields['f0_display'].force_value('hello')
resp = resp.form.submit('submit') # -> validation page
resp = resp.form.submit('submit') # -> submit
assert formdef.data_class().select()[0].data['0'] == '1'
assert formdef.data_class().select()[0].data['0_display'] == 'hello'
assert formdef.data_class().select()[0].data['0_structured'] == data['data'][0]
resp = resp.follow()
url = resp.request.url
resp = resp.form.submit('button_editable')
assert 'wfedit' in resp.location
resp = resp.follow()
assert 'data-value="1"' in resp
assert 'data-initial-display-value="hello"' in resp
# relogin
app = get_app(pub)
login(app, username='foo', password='foo')
resp = app.get(url)
resp = resp.form.submit('button_editable')
resp = resp.follow()
assert 'data-value="1"' in resp
assert 'data-initial-display-value="hello"' in resp
def test_form_count_dispatching(pub):
user = create_user(pub)

View File

@ -1535,7 +1535,15 @@ class ItemField(WidgetField):
return get_session().jsonp_display_values.get(
'%s_%s' % (data_source.get_jsonp_url(), value))
return data_source.get_display_value(value)
display_value = data_source.get_display_value(value)
if self.display_mode == 'autocomplete' and data_source and data_source.can_jsonp():
# store display value in session to be used by select2
url = data_source.get_jsonp_url()
if not get_session().jsonp_display_values:
get_session().jsonp_display_values = {}
get_session().jsonp_display_values['%s_%s' % (url, value)] = display_value
return display_value
def get_view_value(self, value, value_id=None, **kwargs):
value = super(ItemField, self).get_view_value(value)