Commit 91a5c400 authored by Tomáš Peterka's avatar Tomáš Peterka

[json_style] Refactor Base_edit, Add MatrixBox and FloatField.input_style to getHateoas

parent e85cb082
......@@ -51,7 +51,8 @@ except FormValidationError as validation_errors:
value = request.get(field_id)
if callable(value):
value(request)
if silent_mode: return context.ERP5Document_getHateoas(form=form, REQUEST=request, mode='form'), 'form'
if silent_mode:
return context.ERP5Document_getHateoas(form=form, REQUEST=request, mode='form'), 'form'
request.RESPONSE.setStatus(400)
return context.ERP5Document_getHateoas(form=form, REQUEST=request, mode='form')
......@@ -92,103 +93,109 @@ def editListBox(listbox_field, listbox):
def editMatrixBox(matrixbox_field, matrixbox):
""" Function called to edit a Matrix box
"""
if matrixbox is not None:
cell_base_id = matrixbox_field.get_value('cell_base_id')
portal_type = matrixbox_field.get_value('cell_portal_type')
getter_method = matrixbox_field.get_value('getter_method')
if getter_method not in (None, ''):
matrix_context = getattr(context,getter_method)()
if matrixbox is None:
return
cell_base_id = matrixbox_field.get_value('cell_base_id')
portal_type = matrixbox_field.get_value('cell_portal_type')
getter_method = matrixbox_field.get_value('getter_method')
if getter_method not in (None, ''):
matrix_context = getattr(context,getter_method)()
else:
matrix_context = context
if matrix_context is None:
return
kd = {}
kd['portal_type'] = portal_type
kd['base_id'] = cell_base_id
gv = {}
if matrixbox_field.has_value('global_attributes'):
hidden_attributes = [x[0] for x in matrixbox_field.get_value('global_attributes')]
for k in hidden_attributes:
gv[k] = getattr(request, k, None)
if matrixbox_field.get_value('update_cell_range'):
as_cell_range_script_id = matrixbox_field.get_value(
'as_cell_range_script_id')
lines = []
columns = []
tabs = []
extra_dimension_list_list = []
if as_cell_range_script_id:
cell_range = getattr(matrix_context,
as_cell_range_script_id)(matrixbox=True, base_id=cell_base_id)
if len(cell_range) == 1:
lines, = cell_range
elif len(cell_range) == 2:
lines, columns = cell_range
elif len(cell_range) == 3:
lines, columns, tabs = cell_range
elif len(cell_range) > 3:
lines = cell_range[0]
columns = cell_range[1]
tabs = cell_range[2]
extra_dimension_list_list = cell_range[3:]
else:
lines = matrixbox_field.get_value('lines')
columns = matrixbox_field.get_value('columns')
tabs = matrixbox_field.get_value('tabs')
column_ids = map(lambda x: x[0], columns)
line_ids = map(lambda x: x[0], lines)
tab_ids = map(lambda x: x[0], tabs)
extra_dimension_category_list_list = [[category for category, label in dimension_list] for dimension_list in extra_dimension_list_list]
# There are 3 cases
# Case 1: we do 1 dimensional matrix
# Case 2: we do 2 dimensional matrix
# Case 3: we do 2 dimensional matrix + tabs
# Case 4: we do 2 dimensional matrix + tabs + extra
cell_range = matrix_context.getCellRange(base_id = cell_base_id)
if (len(column_ids) == 0) or (column_ids[0] is None):
matrixbox_cell_range = [line_ids]
if cell_range != matrixbox_cell_range:
matrix_context.setCellRange(line_ids, base_id=cell_base_id)
elif (len(tab_ids) == 0) or (tab_ids[0] is None):
matrixbox_cell_range = [line_ids, column_ids]
if cell_range != matrixbox_cell_range:
matrix_context.setCellRange(line_ids, column_ids, base_id=cell_base_id)
else:
matrix_context = context
if matrix_context is not None:
kd = {}
kd['portal_type'] = portal_type
kd['base_id'] = cell_base_id
gv = {}
if matrixbox_field.has_value('global_attributes'):
hidden_attributes = [x[0] for x in matrixbox_field.get_value('global_attributes')]
for k in hidden_attributes:
gv[k] = getattr(request, k, None)
if matrixbox_field.get_value('update_cell_range'):
as_cell_range_script_id = matrixbox_field.get_value(
'as_cell_range_script_id')
lines = []
columns = []
tabs = []
extra_dimension_list_list = []
if as_cell_range_script_id:
cell_range = getattr(matrix_context,
as_cell_range_script_id)(matrixbox=True, base_id=cell_base_id)
if len(cell_range) == 1:
lines, = cell_range
elif len(cell_range) == 2:
lines, columns = cell_range
elif len(cell_range) == 3:
lines, columns, tabs = cell_range
elif len(cell_range) > 3:
lines = cell_range[0]
columns = cell_range[1]
tabs = cell_range[2]
extra_dimension_list_list = cell_range[3:]
else:
lines = matrixbox_field.get_value('lines')
columns = matrixbox_field.get_value('columns')
tabs = matrixbox_field.get_value('tabs')
column_ids = map(lambda x: x[0], columns)
line_ids = map(lambda x: x[0], lines)
tab_ids = map(lambda x: x[0], tabs)
extra_dimension_category_list_list = [[category for category, label in dimension_list] for dimension_list in extra_dimension_list_list]
# There are 3 cases
# Case 1: we do 1 dimensional matrix
# Case 2: we do 2 dimensional matrix
# Case 3: we do 2 dimensional matrix + tabs
# Case 4: we do 2 dimensional matrix + tabs + extra
cell_range = matrix_context.getCellRange(base_id = cell_base_id)
if (len(column_ids) == 0) or (column_ids[0] is None):
matrixbox_cell_range = [line_ids]
if cell_range != matrixbox_cell_range:
matrix_context.setCellRange(line_ids, base_id=cell_base_id)
elif (len(tab_ids) == 0) or (tab_ids[0] is None):
matrixbox_cell_range = [line_ids, column_ids]
if cell_range != matrixbox_cell_range:
matrix_context.setCellRange(line_ids, column_ids, base_id=cell_base_id)
else:
matrixbox_cell_range = [line_ids, column_ids, tab_ids]
if extra_dimension_category_list_list:
matrixbox_cell_range = matrixbox_cell_range + extra_dimension_category_list_list
if cell_range != matrixbox_cell_range:
matrix_context.setCellRange(base_id=cell_base_id, *matrixbox_cell_range)
for k,v in matrixbox.items():
# Only update cells which still exist
if matrix_context.hasInRange(*k, **kd):
c = matrix_context.newCell(*k, **kd)
if c is not None:
c.edit(edit_order=edit_order, **gv) # First update globals which include the def. of property_list
if v.has_key('variated_property'):
# For Variated Properties
value = v['variated_property']
del v['variated_property']
if gv.has_key('mapped_value_property_list'):
# Change the property which is defined by the
# first element of mapped_value_property_list
# XXX May require some changes with Sets
key = gv['mapped_value_property_list'][0]
v[key] = value
# Form: '' -> ERP5: None
cleaned_v = v.copy()
for key, value in cleaned_v.items():
if value == '':
cleaned_v[key] = None
c.edit(edit_order=edit_order, **cleaned_v) # and update the cell specific values
else:
return "Could not create cell %s" % str(k)
else:
return "Cell %s does not exist" % str(k)
matrixbox_cell_range = [line_ids, column_ids, tab_ids]
if extra_dimension_category_list_list:
matrixbox_cell_range = matrixbox_cell_range + extra_dimension_category_list_list
if cell_range != matrixbox_cell_range:
matrix_context.setCellRange(base_id=cell_base_id, *matrixbox_cell_range)
for cell_index_tuple, cell_value_dict in matrixbox.items():
# Only update cells which still exist
if not matrix_context.hasInRange(*cell_index_tuple, **kd):
return "Cell %s does not exist" % str(cell_index_tuple)
cell = matrix_context.newCell(*cell_index_tuple, **kd)
if cell is None:
return "Could not create cell %s" % str(cell_index_tuple)
cell.edit(edit_order=edit_order, **gv) # First update globals which include the def. of property_list
if cell_value_dict.has_key('variated_property'):
# For Variated Properties
value = cell_value_dict['variated_property']
del cell_value_dict['variated_property']
if gv.has_key('mapped_value_property_list'):
# Change the property which is defined by the
# first element of mapped_value_property_list
# XXX Kato: What? Why?
# XXX May require some changes with Sets
key = gv['mapped_value_property_list'][0]
cell_value_dict[key] = value
# Form: '' -> ERP5: None
cleaned_v = cell_value_dict.copy()
for key, value in cleaned_v.items():
if value == '':
cleaned_v[key] = None
cell.edit(edit_order=edit_order, **cleaned_v) # and update the cell specific values
edit_kwargs = {} # keyword arguments for `edit` function on context
......@@ -220,7 +227,8 @@ try:
editMatrixBox(field, request.get(field.id))
# Return parsed values
if silent_mode: return (edit_kwargs, encapsulated_editor_list), 'edit'
if silent_mode:
return (edit_kwargs, encapsulated_editor_list), 'edit'
# Maybe we should build a list of objects we need
# Update basic attributes
......
......@@ -94,7 +94,7 @@ def getFieldDefault(traversed_document, field, key, value=None):
return result
def renderField(traversed_document, field, form_relative_url, value=None, meta_type=None, key=None, key_prefix=None, selection_params=None):
def renderField(traversed_document, field, form, value=None, meta_type=None, key=None, key_prefix=None, selection_params=None):
"""Extract important field's attributes into `result` dictionary."""
if meta_type is None:
......@@ -120,7 +120,7 @@ def renderField(traversed_document, field, form_relative_url, value=None, meta_t
})
if meta_type == "ProxyField":
return renderField(traversed_document, field, form_relative_url, value,
return renderField(traversed_document, field, form, value,
meta_type=field.getRecursiveTemplateField().meta_type,
key=key, key_prefix=key_prefix,
selection_params=selection_params)
......@@ -151,7 +151,10 @@ def renderField(traversed_document, field, form_relative_url, value=None, meta_t
"LinesField", "ImageField", "FileField", "IntegerField",
"PasswordField", "EditorField"):
if meta_type == "FloatField":
result["precision"] = field.get_value("precision")
result.update({
"precision": field.get_value("precision"),
"input_style": field.get_value("input_style"),
})
if meta_type == "ImageField":
options = {
'display': field.get_value('image_display'),
......@@ -231,7 +234,7 @@ def renderField(traversed_document, field, form_relative_url, value=None, meta_t
# find listbox field
listbox_form_field = filter(lambda f: f.getId() == listbox_field_name, form.get_fields())[0]
# get original definition
subfield = renderField(context, listbox_form_field, getFormRelativeUrl(form))
subfield = renderField(context, listbox_form_field, form)
# overwrite, like Base_getRelatedObjectParameter does
if subfield["portal_type"] == []:
subfield["portal_type"] = field.get_value('portal_type')
......@@ -331,7 +334,7 @@ def renderField(traversed_document, field, form_relative_url, value=None, meta_t
"root_url": site_root.absolute_url(),
"script_id": script.id,
"relative_url": traversed_document.getRelativeUrl().replace("/", "%2F"),
"form_relative_url": "%s/%s" % (form_relative_url, field.id),
"form_relative_url": "%s/%s" % (getFormRelativeUrl(form), field.id),
"list_method": list_method_name,
"default_param_json": urlsafe_b64encode(json.dumps(list_method_query_dict))
}
......@@ -416,13 +419,24 @@ def renderField(traversed_document, field, form_relative_url, value=None, meta_t
}
return result
if meta_type == "MatrixBox":
# data are generated by python code for MatrixBox.py
# template_fields are better rendered here because they can be part of "hidden"
# group which is not rendered in form by default. Including
# those fields directly here saves a lot of headache later
template_field_names = ["{}_{}".format(field.id, editable_attribute)
for editable_attribute, _ in field.get_value('editable_attributes')]
result.update({
'data': field.render(key=key, value=value, REQUEST=REQUEST, render_format='list'),
'template_field_dict': {template_field: renderField(traversed_document, getattr(form, template_field), form)
for template_field in template_field_names
if template_field in form},
})
return result
# All other fields are not implemented and we'll return only basic info about them
return {
"type": meta_type,
"_debug": "Unsupported field type",
"title": Base_translateString(field.get_value("title")),
"key": key,
}
result["_debug"] = "Unknown field type " + meta_type
return result
def renderForm(traversed_document, form, response_dict, key_prefix=None, selection_params=None):
......@@ -475,30 +489,22 @@ def renderForm(traversed_document, form, response_dict, key_prefix=None, selecti
'name': form.id
}
# Go through all groups ("left", "bottom", "hidden" etc.) and add fields from
# them into form.
for group in form.Form_getGroupTitleAndId():
if group['gid'].find('hidden') < 0:
# field_list = []
for field in form.get_fields_in_group(group['goid']):
# field_list.append((field.id, renderRawField(field)))
if field.get_value("enabled"):
try:
response_dict[field.id] = renderField(traversed_document, field, form_relative_url, key_prefix=key_prefix, selection_params=selection_params)
if field_errors.has_key(field.id):
response_dict[field.id]["error_text"] = field_errors[field.id].error_text
except AttributeError:
# Do not crash if field configuration is wrong.
pass
# for field_group in field.form.get_groups():
# traversed_document.log("Field group: " + field_group)
# traversed_document.log(field_group)
# for field_property in field.form.get_fields_in_group(field_group):
# # traversed_document.log("Field attribute: " + field_property.id)
# # field.get_value(field_property.id)
# traversed_document.log(field_property)
# group_list.append((group['gid'], field_list))
# Skipping hidden group could be problematic but see MatrixBox Field above
if 'hidden' in group['gid']:
continue
for field in form.get_fields_in_group(group['goid']):
if not field.get_value("enabled"):
continue
try:
response_dict[field.id] = renderField(traversed_document, field, form, key_prefix=key_prefix, selection_params=selection_params)
if field_errors.has_key(field.id):
response_dict[field.id]["error_text"] = field_errors[field.id].error_text
except AttributeError:
# Do not crash if field configuration is wrong.
pass
response_dict["form_id"] = {
"type": "StringField",
......@@ -1079,7 +1085,7 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None,
else:
tmp_value = getProtectedProperty(document, select)
property_value = renderField(traversed_document, editable_field_dict[select], form_relative_url,
property_value = renderField(traversed_document, editable_field_dict[select], form,
tmp_value,
key='field_%s_%s' % (editable_field_dict[select].id,
document_uid))
......
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