Commit cd68cb24 authored by Tomáš Peterka's avatar Tomáš Peterka

[ERP5Form] FormBox validation does not use Base_edit and is able to embed...

[ERP5Form] FormBox validation does not use Base_edit and is able to embed arbitrary Form in RenderJS
parent eb028ada
......@@ -24,8 +24,8 @@
gadget = this,
field_json = options.field_json || {},
new_state = {
value: field_json.value || field_json.default || "",
text_content: field_json.value || field_json.default || "",
value: field_json.value || field_json['default'] || "",
text_content: field_json.value || field_json['default'] || "",
editable: field_json.editable,
required: field_json.required,
name: field_json.key,
......@@ -69,7 +69,8 @@
key: gadget.state.name,
view: gadget.state.view,
jio_key: erp5_document_uri.segment(2),
editable: gadget.state.editable
editable: gadget.state.editable,
embedded: true
};
// do not preserve objects in the state
......
......@@ -216,7 +216,7 @@
</item>
<item>
<key> <string>actor</string> </key>
<value> <string>zope</string> </value>
<value> <string>superkato</string> </value>
</item>
<item>
<key> <string>comment</string> </key>
......@@ -230,7 +230,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>961.56527.16709.20804</string> </value>
<value> <string>966.24080.24291.61081</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -248,7 +248,7 @@
</tuple>
<state>
<tuple>
<float>1517248866.15</float>
<float>1521818911.25</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -119,7 +119,8 @@ and handling data send&receive.
options: options,
erp5_document: undefined,
erp5_form: undefined,
url: undefined
url: undefined,
embedded: asBoolean(options.embedded)
};
if (options.hasOwnProperty('erp5_document')) {
......@@ -161,7 +162,11 @@ and handling data send&receive.
return gadget.jio_getAttachment(uri.segment(2), "view");
})
.push(function (erp5_form) {
var url = "gadget_erp5_pt_" + erp5_form.pt;
var url;
if (new_state.embedded) {
erp5_form.pt = "embedded_form_render"; // hard-coded erp5 naming
}
url = "gadget_erp5_pt_" + erp5_form.pt;
// XXX Hardcoded specific behaviour for form_view
if ((options.editable === 1) && (erp5_form.pt === "form_view")) {
url += "_editable";
......
......@@ -44,6 +44,8 @@ from Products.Formulator.Errors import FormValidationError, ValidationError
import string
from contextlib import contextmanager
MARKER = [] # placeholder for an empty value
@contextmanager
def getFormBoxContext(field, REQUEST):
other = REQUEST.other
......@@ -131,13 +133,14 @@ class FormBoxWidget(Widget.Widget):
class FormBoxEditor:
"""An editor returned from FormBox validation able to `edit` document."""
def __init__(self, result, context):
def __init__(self, attr_dict, editor_list, context):
"""Initialize with all necessary information for editing.
Keep a reference to the correct context and don't expect the caller to provide it
during the edit phase because they don't have access to the widget anymore.
"""
self.attr_dict, self.editor_list = result
self.attr_dict = attr_dict
self.editor_list = editor_list
self.edit = lambda _: self._edit(context)
def __getstate__(self):
......@@ -183,25 +186,60 @@ class FormBoxValidator(Validator.Validator):
required_not_found = 'Input is required but no input given.'
def validate(self, field, key, REQUEST):
# TODO: Handle 'cell' for validation inside listboxes,
# like it is done for rendering.
"""FormBox is a `field` with generated `REQUEST` `key` such as 'field_formbox'."""
formbox_target_id = field.get_value('formbox_target_id')
field_id = (key[len("field_"):]
if key.startswith("field_")
else key)
# Get current error fields
current_field_errors = REQUEST.get('field_errors', [])
if not formbox_target_id:
return None
with getFormBoxContext(field, REQUEST) as here:
# XXX Hardcode script name
result, result_type = here.Base_edit(formbox_target_id, silent_mode=1, key_prefix=key)
if result_type == 'edit':
return FormBoxEditor(result, here)
elif result_type == 'form':
formbox_field_errors = REQUEST.get('field_errors', [])
current_field_errors.extend(formbox_field_errors)
REQUEST.set('field_errors', current_field_errors)
getattr(here, formbox_target_id).validate_all_to_request(REQUEST, key_prefix=key)
else:
raise NotImplementedError, result_type
try:
formbox_form = getattr(here, formbox_target_id)
# validate_all should put parsed values in REQUEST[field.id + "_" + fombox_field.id]
# because it strips away the "field_" part of `key`
formbox_form.validate_all_to_request(REQUEST, key_prefix=key)
edit_kwargs = {} # keyword arguments for `edit` function on context
editor_list = [] # editors placed inside REQUEST object
# Extract all form fields from the request and call `edit` on them
for formbox_field in formbox_form.get_fields():
# Dispatch field either to `edit_kwargs` (in case of simple fields)
# or to `editor_list` in case of editors
formbox_field_id = (formbox_field.id if not formbox_field.has_value('alternate_name')
else (formbox_field.get_value('alternate_name') or formbox_field.id))
formbox_field_full_id = field_id + "_" + formbox_field_id
# attribute ID is a formbox_field.id without "my_" or "your_"
attribute_id = (formbox_field_id.split("_", 1)[1]
if formbox_field_id.startswith("my_") or formbox_field_id.startswith("your_")
else formbox_field_id)
field_value = getattr(REQUEST, formbox_field_full_id, MARKER)
if hasattr(field_value, 'edit'):
# field is an encapsulated editor; call it later
editor_list.append(field_value)
elif field_value is not MARKER:
# object own attribute (fix value Form: '' -> ERP5: None)
edit_kwargs[attribute_id] = field_value if field_value != '' else None
# listbox and matrixbox have special functions in Base_edit but they
# should just implement Editors like this one. Until then no Listboxes
# and Matrixboxes inside FormBoxes
# end for field
return FormBoxEditor(edit_kwargs, editor_list, here)
except FormValidationError as validation_errors:
form_field_errors = REQUEST.get('field_errors', [])
formbox_field_errors = formbox_form.ErrorFields(validation_errors)
form_field_errors.extend(formbox_field_errors)
REQUEST.set('field_errors', form_field_errors)
return
FormBoxWidgetInstance = FormBoxWidget()
FormBoxValidatorInstance = FormBoxValidator()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment