The WTForms documentation is extremely inadequate; they don’t even show you one example of a custom widget that is not already received from another widget.
I am trying to create a button type that is not "entered" in html:
submit = InlineButton (name = 'submit', type = 'submit', title = 'Save this page', textWithinSpan = 'Save')
from flask.ext.wtf import Required, Length, EqualTo, Field, TextInput, html_params from flask import Markup class InlineButtonWidget(object): text = '' html_params = staticmethod(html_params) def __init__(self, input_type='submit', **kwargs): 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 Markup('<button type="submit" %s><span>%s</span></button>' % (self.html_params(name=field.name, **kwargs), kwargs['textWithinSpan'])) class InlineButton(Field): widget = InlineButtonWidget() def __init__(self, label='', **kwargs): self.widget = InlineButtonWidget('submit', label) def __call__(self, **kwargs): return self.widget(self, **kwargs) 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(name='submit', type='submit', title='Save this page', textWithinSpan='Save')
I don’t even need a field object. But it does not appear when you use only the widget.
And when you use the Field object, it gives you all kinds of invalid parameter errors.
Even going into the WTForms source code, it’s hard to understand why it will not pass Kwargs from the form to the widget.
--- UPDATE ---
Well, after I asked the question, I basically figured out a workable solution:
class InlineButtonWidget(object): html_params = staticmethod(html_params) def __init__(self, input_type='submit', text=''): self.input_type = input_type self.text = text 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 Markup('<button type="submit" %s><span>%s</span></button>' % (self.html_params(name=field.name, **kwargs), field.text)) class InlineButton(Field): widget = InlineButtonWidget() def __init__(self, label=None, validators=None, text='Save', **kwargs): super(InlineButton, self).__init__(label, validators, **kwargs) self.text = text 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('submit', text='Save', description='Save this')