如何获得一个与重复元素良好的形式 [英] How to get a build a form with repeated elements well

查看:133
本文介绍了如何获得一个与重复元素良好的形式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

标题真的没有说,因为我总结这个问题有困难。所以这里有一个长的解释:

假设我添加了多个联系人的信息,并且有这些字段:


  • 联系人姓名
    联系方式(电子邮件,电话号码,即时消息)

    • 如果电子邮件:显示电子邮件字段(假设此字段存在)

    • 如果电话号码:显示电话号码字段
    • :显示文本字段



需要JavaScript来完成这个页面本身(添加添加或删除联系人字段),我可以。但是,由于我可以添加多个联系人(而作为软件开发人员,我不知道有多少联系用户想要添加,它可能是1,10或100)
$ b $所以我最大的问题是,我将如何构建像每个领域的名称的东西。我应该把所有的东西都放进 names [] contactmethods [] 之类的东西,然后按顺序访问东西,或者如果更好的解决方案。另外,如果服务器开始验证这些信息,并发现一些格式不正确的信息,我希望能够发送客户端发送的数据到服务器回到客户端,所以他们不会失去他们已经输入的一切。

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


  • 烧瓶

  • jQuery

  • WTForms

解决方案

不需要构建任何东西(至少在服务器端) - WTForms已经支持你所需要的 - 它称之为field enclosures。您正在查找的行为可以在 wtforms.fields.FormField wtforms.fields.FieldList

  class ContactForm (Form):
name = TextField(Name,validators = [Required()])
contact_type = SelectField(Contact Type,
validators = [Required()],$
(email,Email),
(phone,Phone Number),
(im,即时消息)
])
#`如果`是自定义验证器 - 见下面
email_address = TextField(Email,
validators = [If(cont (),
email,
[必填项[if(contact_type,
phone,[Required()])
])
im_handle = TextField(IM Handle,$ b $ validators = contact_type,
im,[Required()])
])

$ b $ class SignUpForm(Form):

contacts = FieldList(FormField(ContactForm))

您还需要一个自定义验证器验证给出用户的选择:

 #小心:前面未经测试的代码
class If(object):
def __init __(self,
parent,
run_validation = None,
extra_validators = None,
msg = None):
self.parent = parent
self.msg = msg如果msg不是None其他u无效
如果可调用(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如果extra_validators不是None \
else []

def __call __(self,field,form):
parent = getattr(form,self.parent)
如果self.run_validation(parent,form):
当你调用 form.validate()
在服务器端,这些字段将自动根据需求进行检查,错误将被适当地填充,以便您可以将它们呈现在客户端。



在客户端创建新字段非常简单,只要您命名,WTForms就会在后端选择它们,然后使用它使用的相同的命名约定 - 即 field.short_name + ' - '+ index


The title really doesn't say it, as i'm having trouble summarizing the issue. So here goes the long explanation:

Let's say I'm adding multiple contacts' information, and I have these fields:

  • Name of the contact
  • Method of Contact (email, phone number, instant message)
    • If email: Show an email field (let's say this field exists)
    • If phone number: Show a phone number field
    • If instant message: Show a text field

So right off the bat, I'm going to be needing JavaScript to complete this on the page itself (to add add or deletion contact fields), which I'm ok with. However, since I can add multiple contacts (and as the software developer, I don't know how many contact the user wants to add, it could be 1, 10, or 100)

So my biggest problem is how am I going to structure the things like the names for each of the field. Should I throw everything into things like names[], contactmethods[] and access things in order, or if there's a better solution.

In addition, if the server starts to verify these information, and finds some malformed info, I would like to be able to send the data that the client sent to the server back to the client, so they don't lose everything they've entered. How would I easily accomplish that?

Some background info: Technologies currently in use (that's relevant):

  • Flask
  • jQuery
  • WTForms

解决方案

No need to build anything (at least on the server side) - WTForms already supports what you need - it calls them "field enclosures". The behavior you are looking for is found in wtforms.fields.FormField and 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))

You'll also need a custom validator to validate the appropriate field, given the user's choice:

# 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)

When you call form.validate() on the server side the fields will be automatically checked against the requirements and the errors will be populated appropriately so you can render them back on the client side.

Creating new fields on the client side is simple and WTForms will pick them up on the back end as long as you name then using the same naming convention it uses - namely field.short_name + '-' + index.

这篇关于如何获得一个与重复元素良好的形式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆