2013-01-24 38 views
7

Tài liệu WTForms có vẻ không đầy đủ, chúng thậm chí không hiển thị cho bạn một ví dụ đơn lẻ của một widget tùy chỉnh không có nguồn gốc từ một widget khác.WTForms tạo một widget tùy chỉnh

Tôi cố gắng để tạo ra một loại nút, đó không phải là "đầu vào" trong html:

submit = InlineButton (name = 'submit', type = 'submit', title = 'Lưu trang này ', 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') 

Tôi thậm chí không cần một đối tượng Field bắt nguồn. Nhưng nó không hiển thị khi bạn chỉ sử dụng Widget.

Và khi bạn sử dụng đối tượng Field, nó sẽ cung cấp cho bạn tất cả các loại lỗi tham số không hợp lệ.

Ngay cả việc đào sâu vào mã nguồn WTForms cũng khó hiểu tại sao nó không truyền Kwargs từ biểu mẫu đến tiện ích con.

--- Cập nhật ---

Ok, sau khi tôi gửi các câu hỏi tôi về cơ bản đã tìm ra một giải pháp khả thi:

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') 

Trả lời

3

trả lời dưới Update, nhưng cần init này bên trong Dòng bắt nguồn lớp học.

def __init__(self, label=None, validators=None, text='Save', **kwargs): 
    super(InlineButton, self).__init__(label, validators, **kwargs) 
    self.text = text 
4

Bạn có thể tận dụng các thuộc tính hữu ích trên trường, cụ thể là 'mô tả' và 'nhãn' cho trường hợp này. Điều này mang lại một thiết lập đơn giản hơn nhiều:

from wtforms.widgets.core import HTMLString, html_params, escape 

class InlineButtonWidget(object): 
    def __call__(self, field, **kwargs): 
     kwargs.setdefault('type', 'submit') 
     # Allow passing title= or alternately use field.description 
     title = kwargs.pop('title', field.description or '') 
     params = html_params(title=title, **kwargs) 

     html = '<button %s><span>%s</span></button>' 
     return HTMLString(html % (params, escape(field.label.text))) 

Cách sử dụng: (bọc cho dễ đọc)

class MyForm(Form): 
    foo = BooleanField(
     u'Save', 
     description='Click here to save', 
     widget=InlineButtonWidget() 
    ) 

luân phiên, có một loại lĩnh vực cho nó:

class InlineButtonField(BooleanField): 
    widget = InlineButtonWidget() 

class MyForm(Form): 
    foo = InlineButtonField('Save', description='Save Me')