The WTForms documentation is woefully inadequate, they don't even show you one single example of a custom widget that isn't derived from another widget already.
I am trying to make a button type, that isn't an <input>
in html:
submit = InlineButton(name='submit', type='submit', title='Save this page', textWithinSpan='Save')
This is what I'm trying:
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 shouldn't even need a Field derived object. But it doesn't display when you only use Widget by itself.
And when you use the Field object, then it gives you all sorts of invalid parameter errors.
Even delving into the WTForms source code makes it difficult to understand why it won't pass Kwargs from form to widget.
--- UPDATE ---
Ok, after I submit 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')