Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow overriding label for values #37

Open
wants to merge 49 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
c458ee2
Add class for 'Fields' to simplify custom logic and use it for filter…
JeffersonBledsoe Sep 22, 2023
d6aa386
Fix non-required fields
JeffersonBledsoe Sep 24, 2023
17697d8
Fix reading incorrect internal value
JeffersonBledsoe Sep 24, 2023
b9bb05f
Fix values not displayign
JeffersonBledsoe Sep 24, 2023
3c45a3a
Use @property for 'value'
JeffersonBledsoe Sep 24, 2023
70a17f1
Fix some existing behaviours
JeffersonBledsoe Sep 25, 2023
9bf7879
Add test for custom_field_id
JeffersonBledsoe Sep 25, 2023
624170d
Fix custom field ID
JeffersonBledsoe Sep 25, 2023
3ea20ae
Fix inconsistent use of field_id in requess
JeffersonBledsoe Sep 25, 2023
b3ca7da
Restore support for falling back to field_id if label doesn't exist
JeffersonBledsoe Sep 25, 2023
e821e3f
Fix data storing
JeffersonBledsoe Sep 25, 2023
cd8e9bb
Fix custom_field_id in data export
JeffersonBledsoe Sep 25, 2023
bd40e5c
Merge branch 'main' into custom-label-mapping
JeffersonBledsoe Sep 25, 2023
e1994e0
Add tests for display values
JeffersonBledsoe Sep 26, 2023
b5c75da
Fix catalog using display value for storage
JeffersonBledsoe Sep 26, 2023
f2ff588
Fix XML using external value
JeffersonBledsoe Sep 27, 2023
2cf29d3
Update frontend field name
JeffersonBledsoe Sep 27, 2023
810d675
Test fix
JeffersonBledsoe Sep 27, 2023
5524684
Readme
JeffersonBledsoe Dec 15, 2023
ac749fb
Typo fix
JeffersonBledsoe Dec 15, 2023
262fce7
Merge branch 'main' into custom-label-mapping
JeffersonBledsoe Jan 8, 2024
30adf28
Add test for custom field ID and ensuring it isn't used in emails
JeffersonBledsoe Jan 9, 2024
47ede0b
Fix using field_id in XML
JeffersonBledsoe Jan 9, 2024
3785922
Remove upgrades and test files from coverage
JeffersonBledsoe Jan 9, 2024
adb24a4
Improve tests for sending and storing custom fields
JeffersonBledsoe Jan 11, 2024
c778d90
Fix for storing CSVs
JeffersonBledsoe Jan 11, 2024
f503de7
Update README.rst
JeffersonBledsoe Jan 19, 2024
bcd03c3
Make fields API clearer
Jan 19, 2024
22f8a9a
Further clarify field API
Jan 19, 2024
6a21647
Improve test coverage
Jan 19, 2024
98276f5
Merge branch 'main' into custom-label-mapping
JeffersonBledsoe Feb 15, 2024
efeb8b8
Try to integrate new email validation into fields
JeffersonBledsoe Feb 15, 2024
63bd5d0
Ensure we're using the `internal_value` API for fields incase a field…
JeffersonBledsoe Feb 15, 2024
c4f8110
Merge branch 'main' into custom-label-mapping
JeffersonBledsoe Jun 10, 2024
4b2a872
Fix missing import from test
JeffersonBledsoe Jun 10, 2024
aa3c786
Fix test being incorrect
JeffersonBledsoe Jun 10, 2024
49f7df8
Merge branch 'main' into custom-label-mapping
JeffersonBledsoe Jun 20, 2024
6fd8d93
Merge branch 'main' into custom-label-mapping
JeffersonBledsoe Sep 12, 2024
a26d13c
Cleanup bad merge
JeffersonBledsoe Sep 12, 2024
9b64a9d
Fix missing use of fields from bad merge
JeffersonBledsoe Sep 12, 2024
81d9174
Update outdated status codes
JeffersonBledsoe Sep 12, 2024
a08bf7b
lint
JeffersonBledsoe Sep 12, 2024
b5936dd
Wrong code updated....
JeffersonBledsoe Sep 12, 2024
f7b62ff
Fix test for custom display value
JeffersonBledsoe Sep 13, 2024
e716145
Fix cleanup of custom_field_id
JeffersonBledsoe Sep 16, 2024
c806b31
Update test for send action form to match actual data
JeffersonBledsoe Sep 16, 2024
85a869b
lint
JeffersonBledsoe Sep 16, 2024
d6ba9ea
Merge branch 'main' into custom-label-mapping
JeffersonBledsoe Sep 17, 2024
a094d68
Use field class for date formatting
JeffersonBledsoe Sep 17, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
[run]
relative_files = True

omit =
src/collective/volto/formsupport/tests/*
src/collective/volto/formsupport/upgrades.py

[report]
include =
*/src/collective/*
Expand Down
1 change: 1 addition & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ include *.rst
include *.GPL
include *.txt
global-exclude *.pyc
global-exclude *.DS_Store
exclude coverage.json
exclude .coveragerc
exclude .isort.cfg
Expand Down
7 changes: 7 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,13 @@ This add-on can be seen in action at the following sites:

- https://www.comune.modena.it/form/contatti

Storing different values from how they are displayed
====================================================

In some cases, the text that is displayed for a field on the page and in the sent email may need to be different from the value that is stored internally. For example, you may want your "Yes/ No" widget to show "Accept" and "Decline" as the labels, but internally still store `True` and `False`.

By storing a `display_values` dictionary for each field in the block data, you can perform these mappings.


Translations
============
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
<ul>
<tal:field repeat="field parameters">
<li tal:define="
value field/value|nothing;
value field/display_value|nothing;
label field/label|nothing;
">
<p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
<tal:field repeat="field parameters">
<tr role="row"
tal:define="
value field/value|nothing;
value field/display_value|nothing;
label field/label|nothing;
"
>
Expand Down
14 changes: 8 additions & 6 deletions src/collective/volto/formsupport/datamanager/catalog.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,17 +77,19 @@ def add(self, data):
)
)
return None
fields = {}
for field in form_fields:
custom_field_id = field.get("custom_field_id")
field_id = custom_field_id if custom_field_id else field["field_id"]
fields[field_id] = field.get("label", field_id)

fields = {
x["field_id"]: x.get("custom_field_id", x.get("label", x["field_id"]))
for x in form_fields
}
record = Record()
fields_labels = {}
fields_order = []
for field_data in data:
field_id = field_data.get("field_id", "")
value = field_data.get("value", "")
field_id = field_data.field_id
# TODO: not nice using the protected member to access the real internal value, but easiest way.
value = field_data.internal_value
if field_id in fields:
record.attrs[field_id] = value
fields_labels[field_id] = fields[field_id]
Expand Down
112 changes: 112 additions & 0 deletions src/collective/volto/formsupport/restapi/services/submit_form/field.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
from collective.volto.formsupport import _
from plone import api
from plone.schema.email import _isemail
from zExceptions import BadRequest
from zope.i18n import translate


class Field:
JeffersonBledsoe marked this conversation as resolved.
Show resolved Hide resolved
def __init__(self, field_data):
def _attribute(attribute_name):
setattr(self, attribute_name, field_data.get(attribute_name))

_attribute("field_type")
_attribute("id")
_attribute("show_when_when")
_attribute("show_when_is")
_attribute("show_when_to")
_attribute("input_values")
_attribute("required")
_attribute("widget")
_attribute("use_as_reply_to")
_attribute("use_as_reply_bcc")
self._display_value_mapping = field_data.get("display_value_mapping")
self._value = field_data.get("value", "")
self._custom_field_id = field_data.get("custom_field_id")
self._label = field_data.get("label", "")
self._field_id = field_data.get("field_id", "")

@property
def display_value(self):
if self._display_value_mapping:
return self._display_value_mapping.get(self._value, self._value)
return self._value

@property
def internal_value(self):
return self._value

@property
def label(self):
return self._label if self._label else self.field_id

@property
def field_id(self):
if self._custom_field_id:
return self._custom_field_id
return self._field_id if self._field_id else self._label

@property
def send_in_email(self):
return True

def validate(self, request):
return


class YesNoField(Field):
@property
def display_value(self):
if not self._display_value_mapping:
return self.internal_value
if self.internal_value is True:
return self._display_value_mapping.get("yes")
elif self.internal_value is False:
return self._display_value_mapping.get("no")


class AttachmentField(Field):
@property
def send_in_email(self):
return False


class EmailField(Field):
def validate(self, request):
super().validate(request=request)

if _isemail(self.internal_value) is None:
raise BadRequest(
translate(
_(
"wrong_email",
default='Email not valid in "${field}" field.',
mapping={
"field": self.label,
},
),
context=request,
)
)


class DateField(Field):
def display_value(self):
return api.portal.get_localized_time(self.internal_value)


def construct_field(field_data):
if field_data.get("widget") == "single_choice":
return YesNoField(field_data)
elif field_data.get("field_type") == "attachment":
return AttachmentField(field_data)
elif field_data.get("field_type") in ["from", "email"]:
return EmailField(field_data)
elif field_data.get("field_type") == "date":
return DateField(field_data)

return Field(field_data)


def construct_fields(fields):
return [construct_field(field) for field in fields]
Loading