0001-forms-recompute-prefills-on-live-changes-51330.patch
tests/backoffice_pages/test_submission.py | ||
---|---|---|
1569 | 1569 |
assert resp.form['f3'].value == random_user.email |
1570 | 1570 |
assert resp.form['f4'].value == random_user.email |
1571 | 1571 | |
1572 |
live_url = resp.html.find('form').attrs['data-live-url'] |
|
1573 |
live_resp = app.post(live_url, params=resp.form.submit_fields()) |
|
1574 |
assert live_resp.json['result']['4']['content'] == random_user.email |
|
1575 | ||
1576 | 1572 |
resp.form['f4'] = 'altered value' # alter value |
1577 | 1573 | |
1578 | 1574 |
resp = resp.form.submit('submit') # -> validation page |
... | ... | |
1580 | 1576 |
assert 'altered value' not in resp |
1581 | 1577 | |
1582 | 1578 | |
1579 |
def test_backoffice_submission_user_selection_then_live_prefill(pub): |
|
1580 |
user = create_user(pub) |
|
1581 | ||
1582 |
for i in range(10): |
|
1583 |
random_user = pub.user_class() |
|
1584 |
random_user.name = 'random user %s' % i |
|
1585 |
random_user.email = 'test%s@invalid' % i |
|
1586 |
random_user.store() |
|
1587 | ||
1588 |
FormDef.wipe() |
|
1589 |
formdef = FormDef() |
|
1590 |
formdef.name = 'form title' |
|
1591 |
formdef.fields = [ |
|
1592 |
fields.PageField(id='0', label='1st page', type='page'), |
|
1593 |
fields.StringField( |
|
1594 |
id='3', |
|
1595 |
label='Field on 2nd page', |
|
1596 |
type='string', |
|
1597 |
varname='plop', |
|
1598 |
prefill={'type': 'user', 'value': 'email'}, |
|
1599 |
), |
|
1600 |
] |
|
1601 |
formdef.backoffice_submission_roles = user.roles[:] |
|
1602 |
formdef.workflow_roles = {'_receiver': 1} |
|
1603 |
formdef.store() |
|
1604 | ||
1605 |
app = login(get_app(pub)) |
|
1606 |
url = '/backoffice/submission/%s/' % formdef.url_name |
|
1607 |
resp = app.get(url) |
|
1608 | ||
1609 |
live_url = resp.html.find('form').attrs['data-live-url'] |
|
1610 |
assert resp.pyquery('.submit-user-selection') |
|
1611 |
resp.form['user_id'] = str(random_user.id) # happens via javascript |
|
1612 |
live_resp = app.post(live_url + '?modified_field_id=user', params=resp.form.submit_fields()) |
|
1613 |
assert live_resp.json == {'result': {'3': {'visible': True, 'content': 'test9@invalid'}}} |
|
1614 | ||
1615 | ||
1583 | 1616 |
def test_backoffice_submission_sidebar_lateral_block(pub): |
1584 | 1617 |
user = create_user(pub) |
1585 | 1618 |
tests/form_pages/test_all.py | ||
---|---|---|
2936 | 2936 | |
2937 | 2937 |
resp = app.get('/test/') |
2938 | 2938 |
assert resp.form['f0'].value == '' |
2939 |
assert 'widget-prefilled' not in resp.text |
|
2939 |
# still marked with a css class, in case of live changes. |
|
2940 |
assert 'widget-prefilled' in resp.text |
|
2940 | 2941 | |
2941 | 2942 | |
2942 | 2943 |
def test_form_page_session_var_prefill(pub): |
... | ... | |
7436 | 7437 |
assert live_resp.json['result']['7']['content'] == '<p>bla bar bla</p>' |
7437 | 7438 | |
7438 | 7439 | |
7440 |
def test_field_live_string_prefill(pub, http_requests): |
|
7441 |
FormDef.wipe() |
|
7442 |
formdef = FormDef() |
|
7443 |
formdef.name = 'Foo' |
|
7444 |
formdef.fields = [ |
|
7445 |
fields.StringField(type='string', id='1', label='Bar', size='40', required=True, varname='bar'), |
|
7446 |
fields.StringField( |
|
7447 |
type='string', |
|
7448 |
id='2', |
|
7449 |
label='Bar2', |
|
7450 |
size='40', |
|
7451 |
required=True, |
|
7452 |
varname='bar2', |
|
7453 |
prefill={'type': 'string', 'value': '{{form_var_bar|default:""}}'}, |
|
7454 |
), |
|
7455 |
] |
|
7456 |
formdef.store() |
|
7457 |
formdef.data_class().wipe() |
|
7458 | ||
7459 |
app = get_app(pub) |
|
7460 |
resp = app.get('/foo/') |
|
7461 |
assert resp.html.find('div', {'data-field-id': '1'}).attrs['data-live-source'] == 'true' |
|
7462 |
assert resp.pyquery('#var_bar2.widget-prefilled') # second field is marked as prefilled |
|
7463 |
assert resp.form['f2'].value == '' |
|
7464 |
resp.form['f1'] = 'hello' |
|
7465 |
live_resp = app.post('/foo/live?modified_field_id=1&prefilled_2=on', params=resp.form.submit_fields()) |
|
7466 |
assert live_resp.json['result']['2'] == {'visible': True, 'content': 'hello'} |
|
7467 | ||
7468 |
resp.form['f2'] = 'other' # manually changed -> widget-prefilled class will be removed |
|
7469 |
resp.form['f1'] = 'xxx' |
|
7470 |
live_resp = app.post('/foo/live?modified_field_id=1', params=resp.form.submit_fields()) |
|
7471 |
assert live_resp.json['result']['2'] == {'visible': True} |
|
7472 | ||
7473 | ||
7439 | 7474 |
def test_form_edit_and_backoffice_field_change(pub): |
7440 | 7475 |
create_user(pub) |
7441 | 7476 | |
... | ... | |
8394 | 8429 |
assert 'f1' in resp.form.fields |
8395 | 8430 |
assert resp.html.find('div', {'data-field-id': '1'}).attrs['data-live-source'] == 'true' |
8396 | 8431 |
resp.form['f1'] = 'hello' |
8397 |
live_resp = app.post('/foo/live', params=resp.form.submit_fields()) |
|
8432 |
live_resp = app.post('/foo/live?prefilled_2=on', params=resp.form.submit_fields())
|
|
8398 | 8433 |
assert live_resp.json['result']['2']['content'] == 'bla hello bla' |
8399 | 8434 |
resp.form['f1'] = 'toto' |
8400 |
live_resp = app.post('/foo/live?modified_field_id=1', params=resp.form.submit_fields()) |
|
8435 |
live_resp = app.post('/foo/live?modified_field_id=1&prefilled_2=on', params=resp.form.submit_fields())
|
|
8401 | 8436 |
assert live_resp.json['result']['2']['content'] == 'bla toto bla' |
8402 | 8437 | |
8403 | 8438 |
wcs/formdef.py | ||
---|---|---|
742 | 742 |
if not varname in live_condition_fields: |
743 | 743 |
live_condition_fields[varname] = [] |
744 | 744 |
live_condition_fields[varname].append(field) |
745 |
if field.prefill and field.prefill.get('locked') and field.prefill.get('type') == 'string':
|
|
745 |
if field.prefill and field.prefill.get('type') == 'string': |
|
746 | 746 |
for varname in field.get_referenced_varnames( |
747 | 747 |
formdef=self, value=field.prefill.get('value', '') |
748 | 748 |
): |
wcs/forms/common.py | ||
---|---|---|
707 | 707 |
for field in displayed_fields: |
708 | 708 |
if field.key == 'item' and field.display_mode == 'list' and field.varname: |
709 | 709 |
modified_field_varnames.add(field.varname) |
710 |
elif get_request().form.get('modified_field_id') == 'user': |
|
711 |
# user selection in sidebar |
|
712 |
formdata.user_id = get_request().form.get('user_id') |
|
710 | 713 |
elif get_request().form.get('modified_field_id'): |
711 | 714 |
for field in displayed_fields: |
712 | 715 |
if field.id == get_request().form.get('modified_field_id'): |
... | ... | |
738 | 741 |
continue |
739 | 742 |
if widget.field.key == 'comment': |
740 | 743 |
result[widget.field.id]['content'] = widget.content |
741 |
elif ( |
|
742 |
widget.field.prefill |
|
743 |
and widget.field.prefill.get('locked') |
|
744 |
and widget.field.prefill.get('type') == 'string' |
|
745 |
): |
|
746 |
value, locked = widget.field.get_prefill_value() |
|
747 |
result[widget.field.id]['content'] = value |
|
744 |
elif widget.field.prefill and widget.field.prefill.get('type') == 'string': |
|
745 |
update_prefill = bool('prefilled_%s' % widget.field.id in get_request().form) |
|
746 |
if update_prefill: |
|
747 |
value, locked = widget.field.get_prefill_value() |
|
748 |
result[widget.field.id]['content'] = value |
|
749 |
elif widget.field.prefill and widget.field.prefill.get('type') == 'user': |
|
750 |
update_prefill = bool(get_request().form.get('modified_field_id') == 'user') |
|
751 |
if update_prefill: |
|
752 |
value, locked = widget.field.get_prefill_value(user=formdata.user) |
|
753 |
result[widget.field.id]['content'] = value |
|
748 | 754 | |
749 | 755 |
return json.dumps({'result': result}) |
750 | 756 |
wcs/forms/root.py | ||
---|---|---|
417 | 417 |
# turn off prefilling from geolocation attributes if |
418 | 418 |
# the form is filled from the backoffice |
419 | 419 |
v = None |
420 |
if v: |
|
421 |
prefilled = True |
|
420 |
else: |
|
421 |
if v: |
|
422 |
prefilled = True |
|
423 |
# always mark widget as prefilled, even for empty content, |
|
424 |
# this will add a widget-prefilled CSS class that will be |
|
425 |
# used for live prefill changes. |
|
422 | 426 |
widget.prefilled = True |
423 | 427 | |
424 | 428 |
if not prefilled and widget: |
wcs/qommon/static/js/qommon.admin.js | ||
---|---|---|
163 | 163 |
$('div.submit-user-selection select').select2(select2_options); |
164 | 164 |
$('div.submit-user-selection').show().find('select').on('change', function() { |
165 | 165 |
$('input[type=hidden][name=user_id]').val($(this).val()); |
166 |
$('form[data-live-url]').trigger( |
|
167 |
'wcs:change', |
|
168 |
{modified_field: 'user', selected_user_id: $(this).val()} |
|
169 |
); |
|
166 | 170 |
}); |
167 | 171 |
} |
168 | 172 |
wcs/qommon/static/js/qommon.forms.js | ||
---|---|---|
291 | 291 |
if (data && data.modified_field) { |
292 | 292 |
new_data += '&modified_field_id=' + data.modified_field; |
293 | 293 |
} |
294 |
$('.widget-prefilled').each(function(idx, elem) { |
|
295 |
new_data += '&prefilled_' + $(elem).data('field-id') + '=true'; |
|
296 |
}); |
|
294 | 297 |
var live_url = $(this).data('live-url'); |
295 | 298 |
live_evaluation = $.ajax({ |
296 | 299 |
type: 'POST', |
... | ... | |
355 | 358 |
$widget.html(value.content); |
356 | 359 |
} else { |
357 | 360 |
// replace text input value |
358 |
$widget.find('input, textarea').val(value.content); |
|
361 |
if ($widget.is('.widget-prefilled') || $widget.is('.widget-readonly') || data.modified_field == 'user') { |
|
362 |
$widget.find('input, textarea').val(value.content); |
|
363 |
} |
|
359 | 364 |
} |
360 | 365 |
} |
361 | 366 |
if (value.source_url) { |
... | ... | |
375 | 380 |
}); |
376 | 381 |
} |
377 | 382 |
$('form div[data-live-source]').parents('form').trigger('wcs:change', {modified_field: 'init'}); |
383 |
$('div.widget-prefilled').on('change input paste', function(ev) { |
|
384 |
$(this).removeClass('widget-prefilled'); |
|
385 |
}); |
|
378 | 386 | |
379 | 387 |
/* searchable select */ |
380 | 388 |
$('select[data-autocomplete]').each(function(i, elem) { |
381 |
- |