forms: allow dynamic prefill of block sub fields (#51688)
This commit is contained in:
parent
6565a67a91
commit
c6a9bfb535
|
@ -43,6 +43,7 @@ from wcs.wf.register_comment import RegisterCommenterWorkflowStatusItem
|
|||
from wcs.wf.resubmit import ResubmitWorkflowStatusItem
|
||||
from wcs.wf.create_formdata import CreateFormdataWorkflowStatusItem, Mapping
|
||||
from wcs.wf.redirect_to_url import RedirectToUrlWorkflowStatusItem
|
||||
from wcs.blocks import BlockDef
|
||||
from wcs.categories import Category
|
||||
from wcs.roles import Role, logged_users_role
|
||||
from wcs.tracking_code import TrackingCode
|
||||
|
@ -7474,6 +7475,47 @@ def test_field_live_string_prefill(pub, http_requests):
|
|||
live_resp = app.post('/foo/live?modified_field_id=user', params=resp.form.submit_fields(), status=403)
|
||||
|
||||
|
||||
def test_field_live_block_string_prefill(pub, http_requests):
|
||||
FormDef.wipe()
|
||||
BlockDef.wipe()
|
||||
|
||||
block = BlockDef()
|
||||
block.name = 'foobar'
|
||||
block.fields = [
|
||||
fields.StringField(
|
||||
id='123',
|
||||
required=True,
|
||||
label='Test',
|
||||
type='string',
|
||||
prefill={'type': 'string', 'value': '{{form_var_foo|default:""}}'},
|
||||
),
|
||||
]
|
||||
block.store()
|
||||
|
||||
formdef = FormDef()
|
||||
formdef.name = 'form title'
|
||||
formdef.fields = [
|
||||
fields.StringField(id='1', label='test', type='string', varname='foo'),
|
||||
fields.BlockField(id='2', label='test', type='block:foobar'),
|
||||
]
|
||||
formdef.store()
|
||||
formdef.data_class().wipe()
|
||||
|
||||
app = get_app(pub)
|
||||
resp = app.get(formdef.get_url())
|
||||
live_url = resp.html.find('form').attrs['data-live-url']
|
||||
assert resp.html.find('div', {'data-field-id': '1'}).attrs['data-live-source'] == 'true'
|
||||
assert resp.pyquery('[data-field-id="123"].widget-prefilled') # block/string
|
||||
assert resp.form['f2$element0$f123'].value == ''
|
||||
resp.form['f1'] = 'hello'
|
||||
live_resp = app.post(live_url + '?modified_field_id=1&prefilled_123=on', params=resp.form.submit_fields())
|
||||
assert live_resp.json['result'] == {
|
||||
'1': {'visible': True},
|
||||
'2': {'visible': True},
|
||||
'2-123': {'block_id': '2', 'content': 'hello', 'field_id': '123', 'visible': True},
|
||||
}
|
||||
|
||||
|
||||
def test_form_edit_and_backoffice_field_change(pub):
|
||||
create_user(pub)
|
||||
|
||||
|
|
|
@ -725,7 +725,15 @@ class FormDef(StorableObject):
|
|||
|
||||
def set_live_condition_sources(self, form, fields):
|
||||
live_condition_fields = {}
|
||||
for field in fields:
|
||||
|
||||
def get_all_fields():
|
||||
for field in fields:
|
||||
yield field
|
||||
if field.key == 'block':
|
||||
for subfield in field.block.fields:
|
||||
yield subfield
|
||||
|
||||
for field in get_all_fields():
|
||||
if field.condition:
|
||||
field.varnames = field.get_condition_varnames(formdef=self)
|
||||
for varname in field.varnames:
|
||||
|
|
|
@ -23,6 +23,7 @@ from quixote.html import TemplateIO, htmltext
|
|||
from quixote.util import randbytes
|
||||
|
||||
from wcs import data_sources
|
||||
from wcs.blocks import BlockWidget, BlockSubWidget
|
||||
from wcs.api_utils import get_user_from_api_query_string, is_url_signed, sign_url_auto_orig
|
||||
from wcs.fields import WidgetField, FileField
|
||||
from wcs.workflows import EditableWorkflowStatusItem
|
||||
|
@ -738,21 +739,38 @@ class FormStatusPage(Directory, FormTemplateMixin):
|
|||
result[field.id]['items'] = [
|
||||
{'id': x[2], 'text': x[1]} for x in field.get_options(mode='lazy')
|
||||
]
|
||||
for widget in form.widgets:
|
||||
if not getattr(widget, 'field', None):
|
||||
continue
|
||||
if widget.field.key == 'comment':
|
||||
result[widget.field.id]['content'] = widget.content
|
||||
elif widget.field.prefill and widget.field.prefill.get('type') == 'string':
|
||||
update_prefill = bool('prefilled_%s' % widget.field.id in get_request().form)
|
||||
|
||||
def get_all_field_widgets(form):
|
||||
for widget in form.widgets:
|
||||
if not getattr(widget, 'field', None):
|
||||
continue
|
||||
yield (None, widget.field, widget)
|
||||
if isinstance(widget, BlockWidget):
|
||||
for subwidget in widget.widgets:
|
||||
if isinstance(subwidget, BlockSubWidget):
|
||||
for field_widget in subwidget.widgets:
|
||||
yield (widget.field, field_widget.field, field_widget)
|
||||
|
||||
for block, field, widget in get_all_field_widgets(form):
|
||||
if block:
|
||||
entry = {'visible': True}
|
||||
result['%s-%s' % (block.id, field.id)] = entry
|
||||
entry['block_id'] = block.id
|
||||
entry['field_id'] = field.id
|
||||
else:
|
||||
entry = result[field.id]
|
||||
if field.key == 'comment':
|
||||
entry['content'] = widget.content
|
||||
elif field.prefill and field.prefill.get('type') == 'string':
|
||||
update_prefill = bool('prefilled_%s' % field.id in get_request().form)
|
||||
if update_prefill:
|
||||
value, locked = widget.field.get_prefill_value()
|
||||
result[widget.field.id]['content'] = value
|
||||
elif widget.field.prefill and widget.field.prefill.get('type') == 'user':
|
||||
value, locked = field.get_prefill_value()
|
||||
entry['content'] = value
|
||||
elif field.prefill and field.prefill.get('type') == 'user':
|
||||
update_prefill = bool(get_request().form.get('modified_field_id') == 'user')
|
||||
if update_prefill:
|
||||
value, locked = widget.field.get_prefill_value(user=formdata.user)
|
||||
result[widget.field.id]['content'] = value
|
||||
value, locked = field.get_prefill_value(user=formdata.user)
|
||||
entry['content'] = value
|
||||
|
||||
return json.dumps({'result': result})
|
||||
|
||||
|
|
|
@ -304,7 +304,11 @@ $(function() {
|
|||
headers: {'accept': 'application/json'},
|
||||
success: function(json) {
|
||||
$.each(json.result, function(key, value) {
|
||||
var $widget = $('[data-field-id="' + key + '"]');
|
||||
if (value.block_id) {
|
||||
var $widget = $('[data-field-id="' + value.block_id + '"] [data-field-id="' + value.field_id + '"]');
|
||||
} else {
|
||||
var $widget = $('[data-field-id="' + key + '"]');
|
||||
}
|
||||
if (value.visible) {
|
||||
var was_visible = $widget.is(':visible');
|
||||
$widget.css('display', '');
|
||||
|
@ -353,16 +357,17 @@ $(function() {
|
|||
$select.trigger('wcs:options-change', {items: value.items});
|
||||
}
|
||||
if (value.content) {
|
||||
var $widget = $('[data-field-id="' + key + '"]');
|
||||
if ($widget.hasClass('comment-field')) {
|
||||
// replace comment content
|
||||
$widget.html(value.content);
|
||||
} else {
|
||||
// replace text input value
|
||||
if ($widget.is('.widget-prefilled') || $widget.is('.widget-readonly') || data.modified_field == 'user') {
|
||||
$widget.find('input, textarea').val(value.content);
|
||||
$widget.each(function(idx, widget) {
|
||||
if ($widget.hasClass('comment-field')) {
|
||||
// replace comment content
|
||||
$widget.html(value.content);
|
||||
} else {
|
||||
// replace text input value
|
||||
if ($(widget).is('.widget-prefilled') || $(widget).is('.widget-readonly') || data.modified_field == 'user') {
|
||||
$(widget).find('input, textarea').val(value.content);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
if (value.source_url) {
|
||||
// json change of URL
|
||||
|
|
Loading…
Reference in New Issue