如何构建一个具有重复元素的表单

时间:2012-07-09 20:29:27

标签: jquery python html flask wtforms

标题真的没有说出来,因为我在总结这个问题时遇到了麻烦。所以这里有很长的解释:

假设我正在添加多个联系人信息,我有以下字段:

  • 联系人姓名
  • 联系方式(电子邮件,电话号码,即时消息)
    • 如果是电子邮件:显示电子邮件字段(假设此字段存在)
    • 如果是电话号码:显示电话号码字段
    • 如果是即时消息:显示文本字段

所以,马上,我将需要JavaScript在页面本身上完成此操作(添加或删除联系人字段),我很好。但是,由于我可以添加多个联系人(作为软件开发人员,我不知道用户想要添加多少联系人,可能是1个,10个或100个)

所以我最大的问题是如何构建每个字段的名称之类的东西。我是否应该将所有内容放入names[]contactmethods[]之类的内容中,并按顺序访问内容,或者是否有更好的解决方案。

此外,如果服务器开始验证这些信息,并发现一些格式错误的信息,我希望能够将客户端发送到服务器的数据发送回客户端,这样他们就不会丢失所有内容他们进来了。我将如何轻松实现这一目标?

一些背景信息: 目前正在使用的技术(相关):

  • 烧瓶
  • 的jQuery
  • WTForms

1 个答案:

答案 0 :(得分:6)

无需构建任何东西(至少在服务器端) - WTForms已经支持你需要的东西 - 它称之为"field enclosures"。您要查找的行为可在wtforms.fields.FormFieldwtforms.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就会在后端接收它们。