向WTForm中的字段添加CSS类

gv8xihay  于 2023-06-25  发布在  其他
关注(0)|答案(5)|浏览(145)

我正在使用wtforms(和flask)生成一个动态表单。我想添加一些自定义的css类到我生成的字段中,但到目前为止我还不能这样做。使用我找到的答案here,我尝试使用自定义小部件来添加此功能。它的实现方式与该问题的答案几乎完全相同:

class ClassedWidgetMixin(object):
  """Adds the field's name as a class.

  (when subclassed with any WTForms Field type).
  """

  def __init__(self, *args, **kwargs):
    print 'got to classed widget'
    super(ClassedWidgetMixin, self).__init__(*args, **kwargs)

  def __call__(self, field, **kwargs):
    print 'got to call'
    c = kwargs.pop('class', '') or kwargs.pop('class_', '')
    # kwargs['class'] = u'%s %s' % (field.name, c)
    kwargs['class'] = u'%s %s' % ('testclass', c)
    return super(ClassedWidgetMixin, self).__call__(field, **kwargs)

class ClassedTextField(TextField, ClassedWidgetMixin):
  print 'got to classed text field'

在视图中,我这样做是为了创建字段(ClassedTextField是从表单导入的,f是基本表单的示例):

f.test_field = forms.ClassedTextField('Test Name')

表单的其余部分创建正确,但这个jinja:

{{f.test_field}}

生成以下输出(无类):

<input id="test_field" name="test_field" type="text" value="">

任何提示将是伟大的,谢谢。

ubbxdtey

ubbxdtey1#

您实际上不需要到小部件级别将HTML类属性附加到字段的呈现。您可以简单地使用jinja模板中的class_参数指定它。
例如

{{ form.email(class_="form-control") }}

将生成以下HTML::

<input class="form-control" id="email" name="email" type="text" value="">

要动态地执行此操作,例如,使用表单的名称作为HTML class属性的值,您可以执行以下操作:
Jinja:

{{ form.email(class_="form-style-"+form.email.name) }}

输出:

<input class="form-style-email" id="email" name="email" type="text" value="">

有关注入HTML属性的更多信息,请查看官方文档。

xpszyzbs

xpszyzbs2#

如果您希望通过编程将css类(或者任何其他属性)包含到表单字段中,那么可以使用render_kw参数。
例如:

r_field = RadioField(
    'Label', 
    choices=[(1,'Enabled'),(0,'Disabled')], 
    render_kw={'class':'myclass','style':'font-size:150%'}
)

将呈现为:

<ul class="myclass" id="r_field" style="font-size:150%">
    <li><input id="r_field-0" name="r_field" type="radio" value="1"> <label for="r_field-0">Enabled</label></li>
    <li><input id="r_field-1" name="r_field" type="radio" value="0"> <label for="r_field-1">Disabled</label></li>
</ul>
bvn4nwqk

bvn4nwqk3#

WTForms 2.1中,我使用extra_classes,如下面的一行:

1.第一条路

{{ f.render_form_field(form.email, extra_classes='ourClasses') }}

我们也可以使用@John Go-Soco答案在表单字段中使用render_kw属性,就像这样。

2.第二种方式

style={'class': 'ourClasses', 'style': 'width:50%;'}
email = EmailField('Email', 
                   validators=[InputRequired(), Length(1, 64), Email()],
                   render_kw=style)

但我更喜欢使用第一种方式。

yjghlzjz

yjghlzjz4#

虽然很晚了,但这是我发现的。在呈现模板时,您可以在括号内传递任何键值对,并且它只是在呈现时放置这些键值。例如,如果你必须把一个类沿着一些占位符文本放在一起,你可以像下面这样做:

{{ form.email(class='custom-class' placeholder='email here') }}

实际渲染如下:

<input class="custom-class" id="email" name="email" placeholder="email here" type="text" value="">

基本上,您甚至可以尝试通过添加一些不存在的HTML属性和一些值来进行实验,并呈现它。
为了减少痛苦,最好将辅助函数作为宏,并直接呈现它们而不是实际字段。假设您有公共类和错误类。你可以有一个像这样的辅助宏:

{% macro render_field(field,cls,errcls) %}

  {% if field.errors %}
  <div class="form-group">
    <label for="{{ field.id}}">{{ field.label.text }}</label>
    
    {{ field(class = cls + " " + errcls,**kwargs) | safe}}
    <div class="invalid-feedback">
      {% for error in field.errors %}
      <span> {{error}}</span>
      {% endfor %}
    </div>
  </div>

  {% else %}

  <div class="form-group">
    <label for="{{ field.id}}">{{ field.label.text }}</label>
    {{ field(class = cls,**kwargs) | safe}}
  </div>
  
  {% endif %}
{% endmacro %}

现在,在渲染字段时,您可以在模板中使用如下附加属性来调用:

{{render_field(form.email,cls="formcontrol",errcls="isinvalid",placeholder="Your Email") }}

在这里我使用了引导类,只需要修改helper函数就可以了!
希望有帮助!快乐编码!

qfe3c7zg

qfe3c7zg5#

至少有5种方法可以做到这一点,这取决于你想做什么:
1.在模板中:

{{ field(class="form-control") }}

1.在字段定义中:

class MyForm(Form):
  name = StringField("name", render_kw={"class":"form-control"})

1.子分类字段:

class MyStringField(StringField):
   def __call__(self, **kwargs):
      kwargs.setdefault("class", "form-control")
      return super().__call__(**kwargs)

class MyForm(Form):
   name = MyStringField("name")

1.使用 meta(适用于所有字段):

class MyMeta(wtforms.meta.DefaultMeta):
   def render_field(self, field, render_kw):
      render_kw.setdefault("class", "form-control")
      return super().render_field(field, render_kw)

class MyForm(Form):
   name = StringField("name")

   class Meta(MyMeta):
      ...

1.使用小部件:

class MyTextInput(wtforms.widgets.TextInput):
   def __call__(self, field, **kwargs):
      kwargs.setdefault("class", "form-control")
      return super().__call__(field, **kwargs)

class MyForm(Form):
   name = StringField("name", widget=MyTextInput())

相关问题