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 37 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
37 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
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
7 changes: 7 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,13 @@ This add-on can be seen in action at the following sites:

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

Custom label mapping
JeffersonBledsoe marked this conversation as resolved.
Show resolved Hide resolved
=========================

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
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 @@ -79,17 +79,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._value
JeffersonBledsoe marked this conversation as resolved.
Show resolved Hide resolved
if field_id in fields:
record.attrs[field_id] = value
fields_labels[field_id] = fields[field_id]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
class Field:
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 value(self):
if self._display_value_mapping:
return self._display_value_mapping.get(self._value, self._value)
return self._value

@value.setter
JeffersonBledsoe marked this conversation as resolved.
Show resolved Hide resolved
def value(self, value):
self._value = value

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

@label.setter
def label(self, label):
self._label = label

@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

@field_id.setter
def field_id(self, field_id):
self._field_id = field_id

@property
def send_in_email(self):
return True


class YesNoField(Field):
@property
def value(self):
if self._display_value_mapping:
JeffersonBledsoe marked this conversation as resolved.
Show resolved Hide resolved
if self._value is True:
return self._display_value_mapping.get("yes")
elif self._value is False:
return self._display_value_mapping.get("no")
return self._value

@property
def send_in_email(self):
return True


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


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)

return Field(field_data)


def construct_fields(fields):
return [construct_field(field) for field in fields]
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# -*- coding: utf-8 -*-


import codecs
import logging
import math
Expand Down Expand Up @@ -27,6 +28,9 @@
IFormDataStore,
IPostEvent,
)
from collective.volto.formsupport.restapi.services.submit_form.field import (
construct_fields,
)
from collective.volto.formsupport.utils import get_blocks

logger = logging.getLogger(__name__)
Expand All @@ -41,6 +45,8 @@ def __init__(self, context, data):


class SubmitPost(Service):
fields = []

def __init__(self, context, request):
super(SubmitPost, self).__init__(context, request)

Expand All @@ -61,6 +67,27 @@ def reply(self):

notify(PostEventService(self.context, self.form_data))

# Construct self.fieldss
fields_data = []
for submitted_field in self.form_data.get("data", []):
# TODO: Review if fields submitted without a field_id should be included. Is breaking change if we remove it
if submitted_field.get("field_id") is None:
fields_data.append(submitted_field)
continue
for field in self.block.get("subblocks", []):
if field.get("id", field.get("field_id")) == submitted_field.get(
"field_id"
):
fields_data.append(
{
**field,
**submitted_field,
"display_value_mapping": field.get("display_values"),
"custom_field_id": self.block.get(field["field_id"]),
}
)
self.fields = construct_fields(fields_data)

if send_action:
try:
self.send_data()
Expand Down Expand Up @@ -332,16 +359,7 @@ def filter_parameters(self):
"""
do not send attachments fields.
"""
skip_fields = [
x.get("field_id", "")
for x in self.block.get("subblocks", [])
if x.get("field_type", "") == "attachment"
]
return [
x
for x in self.form_data.get("data", [])
if x.get("field_id", "") not in skip_fields
]
return [field for field in self.fields if field.send_in_email]

def send_mail(self, msg, charset):
host = api.portal.get_tool(name="MailHost")
Expand Down Expand Up @@ -394,9 +412,7 @@ def attach_xml(self, msg):
xmlRoot = Element("form")

for field in self.filter_parameters():
SubElement(
xmlRoot, "field", name=field.get("custom_field_id", field["label"])
).text = str(field.get("value", ""))
SubElement(xmlRoot, "field", name=field.field_id).text = str(field._value)

doc = ElementTree(xmlRoot)
doc.write(output, encoding="utf-8", xml_declaration=True)
Expand Down
Loading