Search code examples
pythonflaskwtformsflask-wtforms

Flask-WTF uses input=submit instead of button type=submit


I would like Flask's "SubmitField" to use

<button type="submit" title="Save this form"><span>Save</span></button>

Instead of:

<input type="submit" title="Save this form" />

I am printing it out in templates:

{{ field(class=css_class, title=field.description, **kwargs) }}

I'm guessing that I have to somehow modify SubmitInput (the widget behind SubmitField), but I'm not sure how to do that exactly, do I somehow have to modify __html__()?

EDIT:

from flask.ext.wtf import Required, Length, EqualTo, Field, TextInput
from flask import Markup
class InlineButtonWidget(object):
    html = """
    <button type="submit" title="%s"><span>%s</span></button>
    """

    def __init__(self, input_type='submit'):
        self.input_type = input_type

    def __call__(self, field, **kwargs):
        kwargs.setdefault('id', field.id)
        kwargs.setdefault('type', self.input_type)
        if 'value' not in kwargs:
            kwargs['value'] = field._value()
        return HTMLString(self.html % (field.name, field.label ))


class InlineButton(Field):
  widget = InlineButtonWidget()
  def _value(self):
    if self.data:
        return u', '.join(self.data)
    else:
        return u''


class SignupForm(Form):
    name = TextField('Name', [Length(min=1, max=200)])
    submit = InlineButton('sign up')

I want to be able to do this:

submit = InlineButton({'name' : 'submit', 'title' : 'sign up today for prizes.', 'type' : 'submitfieldtype', 'textInsideSpan' : 'Save Current Work' })


Solution

  • It's easy. You can create new widget like InlineButtonWidget() but I think it's better to remove submit from the form and use this in the template:

    <button type="submit" title="Save this form"><span>Save</span></button>
    

    Of course, you can work with this too:

    {% for name, label in buttons %}
        <button type="submit" title="{{name}}"><span>{{name}}</span></button>
    {% endfor %}
    

    Sample widget:

    class InlineButtonWidget(object):
        html = """
        <button type="submit" title="%s"><span>%s</span></button>
        """
        
        def __init__(self, input_type='submit'):
            self.input_type = input_type
    
        def __call__(self, field, **kwargs):
            kwargs.setdefault('id', field.id)
            kwargs.setdefault('type', self.input_type)
            if 'value' not in kwargs:
                kwargs['value'] = field._value()
            return HTMLString(self.html % (field.name, field.lable ))