如何很好地构建具有重复元素的表单
Posted
技术标签:
【中文标题】如何很好地构建具有重复元素的表单【英文标题】:How to get a build a form with repeated elements well 【发布时间】:2012-07-09 07:10:06 【问题描述】:标题确实没有说明,因为我无法总结问题。所以这里有很长的解释:
假设我要添加多个联系人的信息,并且我有这些字段:
联系人姓名 联系方式(电子邮件、电话号码、即时消息) 如果电子邮件:显示电子邮件字段(假设此字段存在) 如果电话号码:显示电话号码字段 如果即时消息:显示文本字段所以马上,我将需要 javascript 在页面本身上完成此操作(添加或删除联系人字段),我可以接受。但是,由于我可以添加多个联系人(作为软件开发人员,我不知道用户要添加多少个联系人,可能是 1、10 或 100)
所以我最大的问题是如何组织每个字段的名称等内容。我应该把所有东西都扔到names[]
、contactmethods[]
之类的东西中并按顺序访问,还是有更好的解决方案。
另外,如果服务器开始验证这些信息,并发现一些格式错误的信息,我希望能够将客户端发送给服务器的数据发送回客户端,这样他们就不会丢失一切他们进入了。我怎样才能轻松做到这一点?
一些背景信息: 当前使用的技术(相关):
烧瓶 jQuery WTForms【问题讨论】:
Flask 让您真的轻松地迭代POST
数据。您应该稍微阅读一下文档,看看是否有帮助。
是的,我对此很熟悉。我主要关心的是如果出现问题,返回数据。
根据发回服务器收到的任何内容以使客户端不会丢失它,您可以使用闪存消息(适用于从服务器到客户端的一次性“发布”)。
Flash 消息不适用于表单,但...而且我必须有一个非常复杂的模板,因为它需要支持多个预填表单或一个初始模板。
也许你应该使用数组,虽然我已经有一段时间没有使用表单数组了,我不知道如何使用 Flask 来处理它们。
【参考方案1】:
无需构建任何东西(至少在服务器端)- WTForms 已经支持您需要的东西- 它称它们为"field enclosures"。您正在寻找的行为在 wtforms.fields.FormField
和 wtforms.fields.FieldList
中找到
class ContactForm(Form):
name = TextField("Name", validators=[Required()])
contact_type = SelectField("Contact Type",
validators=[Required()],
choices=[
("email", "Email"),
("phone", "Phone Number"),
("im", "Instant Message")
])
# `If` is a custom validator - see below
email_address = TextField("Email",
validators=[If("contact_type",
"email",
[Required(), Email()])
])
phone_number = TextField("Phone #",
validators=[If("contact_type",
"phone", [Required()])
])
im_handle = TextField("IM Handle",
validators=[If("contact_type",
"im", [Required()])
])
class SignUpForm(Form):
# Other fields go here
contacts = FieldList(FormField(ContactForm))
根据用户的选择,您还需要custom validator 来验证适当的字段:
# CAUTION: Untested code ahead
class If(object):
def __init__(self,
parent,
run_validation=None,
extra_validators=None,
msg=None):
self.parent = parent
self.msg = msg if msg is not None else u"Invalid"
if callable(run_validation):
self.run_validation = run_validation
else:
_run_validation = lambda self, parent, form: parent.data == run_validation
self.run_validation = _run_validation
self.extra_validators = extra_validators if extra_validators is not None \
else []
def __call__(self, field, form):
parent = getattr(form, self.parent)
if self.run_validation(parent, form):
return field.validate(form, extra_validators=self.extra_validators)
当您在服务器端调用 form.validate()
时,将根据要求自动检查字段并适当填充错误,以便您可以将它们呈现回客户端。
在客户端创建新字段很简单,只要您命名using the same naming convention it uses - 即field.short_name + '-' + index
,WTForms 就会在后端提取它们。
【讨论】:
如果我有另一个选择字段,可以在某些选项下将电话字段(比方说)变成 2 个文本字段以解析为元组,甚至将电话字段变成选择字段怎么办?以上是关于如何很好地构建具有重复元素的表单的主要内容,如果未能解决你的问题,请参考以下文章