Add a CSS class to an option in a WTForms SelectField

前端 未结 2 1478
闹比i
闹比i 2020-12-11 23:08

Can anyone please tell me how to assign css class to choices values. I would like to change the background of each choices with small image, so how can I do

2条回答
  •  萌比男神i
    2020-12-12 00:01

    If you look deep in the bowels of WTForms you'll find a widget class called SelectField

    this is the method called build the html string:

    @classmethod
    def render_option(cls, value, label, selected, **kwargs):
        options = dict(kwargs, value=value)
        if selected:
            options['selected'] = True
        return HTMLString('' % (html_params(**options), escape(text_type(label))))
    

    this is __call__ method that invokes the render_options function defined above.

    def __call__(self, field, **kwargs):
        kwargs.setdefault('id', field.id)
        if self.multiple:
            kwargs['multiple'] = True
        html = ['')
        return HTMLString(''.join(html))
    

    You are not going to be able to add the class attribute by simply instantiating a SelectField. When you do this it creates the Option instances implicitly. At render time the render_options methods of these implicit instances are only invoked with val, selected, and label arguments.

    You can access the implicit Option instances after the fact. This is not without issue. If you look at @Johnston's example:

    >>> i = 44
    >>> form = F()
    >>> for subchoice in form.a:
    ...     print subchoice(**{'data-id': i})
    ...     i += 1
    

    He is doing exactly this. But you have to provide the attributes to the class at render time. The invocation subchoice(**{'data-id': i}) actually spits out the expected HTML. This poses quite the problem if you are integrating WTForms with a template engine. Because the something like jinja is calling these render functions for you.

    If you want this type of behavior I would recommend writing your own implementation of SelectField that allows you to pass attributes into the implicit Option instances. This way the template engine can just go about the business of invoking render and you can keep your definitions of the form consolidated in your forms.py file(s)

提交回复
热议问题