Re-work FalafelDateTime logic a bit

need to be more "standard" in how (de)serialize works etc.

also be sure to show error messages if present, not just field helptext
This commit is contained in:
Lance Edgar 2023-10-02 09:54:34 -05:00
parent 746e13d134
commit 4125be7e8d
3 changed files with 44 additions and 26 deletions

View file

@ -886,9 +886,6 @@ class Form(object):
if field.cstruct is colander.null:
return '[]'
if isinstance(field.schema.typ, types.FalafelDateTime):
return field.cstruct
try:
return self.jsonify_value(field.cstruct)
except Exception as error:
@ -980,32 +977,31 @@ class Form(object):
if field and isinstance(field.schema.typ, deform.FileData):
attrs['class_'] = 'file'
# show helptext if present
# TODO: older logic did this only if field was *not*
# readonly, perhaps should add that back..
if self.has_helptext(fieldname):
msgkey = 'message'
if self.dynamic_helptext.get(fieldname):
msgkey = ':message'
attrs[msgkey] = self.render_helptext(fieldname)
# next we will build array of messages to display..some
# fields always show a "helptext" msg, and some may have
# validation errors..
field_type = None
messages = []
# show errors if present
error_messages = self.get_error_messages(field) if field else None
if error_messages:
field_type = 'is-danger'
messages.extend(error_messages)
# TODO: this surely can't be what we ought to do
# here..? seems like we must pass JS but not JSON,
# sort of, so we custom-write the JS code to ensure
# single instead of double quotes delimit strings
# within the code.
message = '[{}]'.format(', '.join([
# show helptext if present
# TODO: older logic did this only if field was *not*
# readonly, perhaps should add that back..
if self.has_helptext(fieldname):
messages.append(self.render_helptext(fieldname))
# ..okay now we can declare the field messages and type
if field_type:
attrs['type'] = field_type
if messages:
attrs[':message'] = '[{}]'.format(', '.join([
"'{}'".format(msg.replace("'", r"\'"))
for msg in error_messages]))
attrs.update({
'type': 'is-danger',
':message': message,
})
for msg in messages]))
# merge anything caller provided
attrs.update(bfield_attrs)

View file

@ -102,17 +102,28 @@ class FalafelDateTime(colander.DateTime):
app = self.request.rattail_config.get_app()
dt = app.localtime(appstruct, from_utc=True)
return json.dumps({
return {
'date': str(dt.date()),
'time': str(dt.time()),
})
}
def deserialize(self, node, cstruct):
if not cstruct:
return colander.null
try:
date = datetime.datetime.strptime(cstruct['date'], '%Y-%m-%d').date()
except:
node.raise_invalid("Missing or invalid date")
try:
time = datetime.datetime.strptime(cstruct['time'], '%H:%M:%S').time()
except:
node.raise_invalid("Missing or invalid time")
result = datetime.datetime.combine(date, time)
app = self.request.rattail_config.get_app()
result = datetime.datetime.strptime(cstruct, '%Y-%m-%dT%H:%M:%S')
result = app.localtime(result)
result = app.make_utc(result)
return result

View file

@ -242,6 +242,17 @@ class FalafelDateTimeWidget(dfwidget.DateTimeInputWidget):
"""
template = 'datetime_falafel'
def serialize(self, field, cstruct, **kw):
readonly = kw.get('readonly', self.readonly)
values = self.get_template_values(field, cstruct, kw)
template = self.readonly_template if readonly else self.template
return field.renderer(template, **values)
def deserialize(self, field, pstruct):
if pstruct == '':
return colander.null
return pstruct
class FalafelTimeWidget(dfwidget.TimeInputWidget):
"""