Flask WTForms, How to add additional attribute to options of SelectField?

Viewed 849

I tried to implement additional attribute (e.g. custom data) to the option of SelectField in FlaskForm(_Option in module wtforms.fields.core). But it didn't work.

class EventForm(FlaskForm):
    event_date = DateField(
        'Date',
        validators=[DataRequired()]
    )

    category_id = SelectField(
        'Category',
        coerce=int
    )

    recipe_id = SelectField(
        'Recipe',
        coerce=int
    )

    submit = SubmitField('Create')


def new_event():
    
    recipes = Recipe.query.all()

    categories = Category.query.all()
    form = EventForm()
    form.recipe_id.choices = [(r.id, r.recipe_name) for r in recipes]
    form.category_id.choices = [(r.id, r.category_name) for r in categories]

    ## tried to add custom data attributes, but it doesn't work
    i = 1
    for sub_option in form.recipe_id:
        sub_option(**{"data-custom": i})
        i += 1

    if form.validate_on_submit():

            event = Event(
                event_date=form.event_date.data,
                recipe_id=form.recipe_id.data,
                category_id=form.category_id.data
            )
            db.session.add(event)
            db.session.commit()
            flash('The event has been created', 'success')
            return redirect(url_for('main.home'))

    return render_template('new_event.html', form=form)

Here is HTML and there is no custom attribute added.

<select class="new-recipe form-control form-control-lg" id="recipe_id" name="recipe_id">
<option value="1">Recipe A</option>
<option value="2">Recipe B</option>

My expectation is

<select class="new-recipe form-control form-control-lg" id="recipe_id" name="recipe_id">
<option value="1" data-custom="1">Recipe A</option>
<option value="2" data-custom="2">Recipe B</option>

I checked option class and it looks like additional attribute can be added though.

Help on _Option in module wtforms.fields.core object:

class _Option(Field)
 |  _Option(*args, **kwargs)
 |  
 |  Field base class
 |  
 |  Method resolution order:
 |      _Option
 |      Field
 |      builtins.object
 |  
 |  Data and other attributes defined here:
 |  
 |  checked = False
 |  
 |  ----------------------------------------------------------------------
 |  Methods inherited from Field:
 |  
 |  __call__(self, **kwargs)
 |      Render this field as HTML, using keyword args as additional attributes.
 |      
 |      This delegates rendering to
 |      :meth:`meta.render_field <wtforms.meta.DefaultMeta.render_field>`
 |      whose default behavior is to call the field's widget, passing any
 |      keyword arguments from this call along to the widget.
 |      
 |      In all of the WTForms HTML widgets, keyword arguments are turned to
 |      HTML attributes, though in theory a widget is free to do anything it
 |      wants with the supplied keyword arguments, and widgets don't have to
 |      even do anything related to HTML.

I appreciate any help

0 Answers
Related