new "table" field
This commit is contained in:
parent
51bd030283
commit
f80bb44dd5
|
@ -144,6 +144,9 @@ class Field:
|
|||
else:
|
||||
setattr(self, attribute, el.text.encode(charset))
|
||||
|
||||
def get_rst_view_value(self, value, indent=''):
|
||||
return indent + self.get_view_value(value)
|
||||
|
||||
|
||||
class WidgetField(Field):
|
||||
type = None
|
||||
|
@ -651,6 +654,84 @@ class PageField(Field):
|
|||
register_field_class(PageField)
|
||||
|
||||
|
||||
class TableField(WidgetField):
|
||||
key = 'table'
|
||||
description = N_('Table')
|
||||
in_listing = False # no way to represent data in a single cell
|
||||
|
||||
rows = None
|
||||
columns = None
|
||||
|
||||
widget_class = TableWidget
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
self.rows = None
|
||||
self.columns = None
|
||||
WidgetField.__init__(self, **kwargs)
|
||||
|
||||
def perform_more_widget_changes(self, form, kwargs, edit = True):
|
||||
kwargs['rows'] = self.rows
|
||||
kwargs['columns'] = self.columns
|
||||
|
||||
def fill_admin_form(self, form):
|
||||
WidgetField.fill_admin_form(self, form)
|
||||
form.add(WidgetList, 'rows', title = _('Rows'), element_type = StringWidget,
|
||||
value = self.rows, required = True,
|
||||
element_kwargs = {'render_br': False, 'size': 50},
|
||||
add_element_label = _('Add row'))
|
||||
form.add(WidgetList, 'columns', title = _('Columns'), element_type = StringWidget,
|
||||
value = self.columns, required = True,
|
||||
element_kwargs = {'render_br': False, 'size': 50},
|
||||
add_element_label = _('Add column'))
|
||||
|
||||
def get_admin_attributes(self):
|
||||
return WidgetField.get_admin_attributes(self) + ['rows', 'columns']
|
||||
|
||||
def get_view_value(self, value):
|
||||
r = TemplateIO(html=True)
|
||||
r += htmltext('<table><thead><tr><td></td>')
|
||||
for column in self.columns:
|
||||
r += htmltext('<th>%s</th>') % column
|
||||
r += htmltext('</tr></thead><tbody>')
|
||||
for i, row in enumerate(self.rows):
|
||||
r += htmltext('<tr><th>%s</th>') % row
|
||||
for j, column in enumerate(self.columns):
|
||||
r += htmltext('<td>')
|
||||
if value:
|
||||
r += value[i][j]
|
||||
r += htmltext('</td>')
|
||||
r += htmltext('</tr>')
|
||||
r += htmltext('</tbody></table>')
|
||||
|
||||
return r.getvalue()
|
||||
|
||||
def get_rst_view_value(self, value, indent=''):
|
||||
if not value:
|
||||
return indent
|
||||
r = []
|
||||
max_width = 0
|
||||
for column in self.columns:
|
||||
max_width = max(max_width, len(column))
|
||||
|
||||
for i, row in enumerate(self.rows):
|
||||
max_width = max(max_width, len(row))
|
||||
for j, column in enumerate(self.columns):
|
||||
max_width = max(max_width, len(value[i][j]))
|
||||
|
||||
r.append(' '.join(['='*max_width]*(len(self.columns)+1)))
|
||||
r.append(' '.join([column.center(max_width) for column in ['/']+self.columns]))
|
||||
r.append(' '.join(['='*max_width]*(len(self.columns)+1)))
|
||||
for i, row in enumerate(self.rows):
|
||||
r.append(' '.join([cell.center(max_width) for cell in [row] +
|
||||
[value[i][x] for x in range(len(self.columns))]]))
|
||||
r.append(' '.join(['='*max_width]*(len(self.columns)+1)))
|
||||
return '\n'.join([indent + x for x in r])
|
||||
|
||||
|
||||
register_field_class(TableField)
|
||||
|
||||
|
||||
|
||||
|
||||
def get_field_class_by_type(type):
|
||||
for k in field_classes:
|
||||
|
|
|
@ -344,7 +344,7 @@ class FormDef(StorableObject):
|
|||
elif field.type == 'date':
|
||||
details.append(' %s' % time.strftime(date_format(), data[field.id]))
|
||||
else:
|
||||
details.append(' %s' % field.get_view_value(data[field.id]))
|
||||
details.append('%s' % field.get_rst_view_value(data[field.id], indent=' '))
|
||||
details.append('')
|
||||
return '\n'.join(details)
|
||||
|
||||
|
|
|
@ -793,3 +793,77 @@ class WysiwygTextWidget(TextWidget):
|
|||
htmlescape(self.value or '') +
|
||||
htmltext("</textarea>"))
|
||||
|
||||
|
||||
class TableWidget(CompositeWidget):
|
||||
readonly = False
|
||||
|
||||
def __init__(self, name, value = None, rows = None, columns = None, **kwargs):
|
||||
CompositeWidget.__init__(self, name, value, **kwargs)
|
||||
self.rows = rows
|
||||
self.columns = columns
|
||||
|
||||
widget_kwargs = {}
|
||||
if kwargs.has_key('title'):
|
||||
del kwargs['title']
|
||||
if kwargs.has_key('readonly') and kwargs.get('readonly'):
|
||||
del kwargs['readonly']
|
||||
self.readonly = True
|
||||
widget_kwargs['readonly'] = 'readonly'
|
||||
|
||||
for i, row in enumerate(rows):
|
||||
for j, column in enumerate(columns):
|
||||
widget = self.add(StringWidget, 'c-%s-%s' % (i, j), **widget_kwargs)
|
||||
widget = self.get_widget('c-%s-%s' % (i, j))
|
||||
if value and self.readonly:
|
||||
if not get_request().form:
|
||||
get_request().form = {}
|
||||
get_request().form[widget.name] = value[i][j]
|
||||
widget.set_value(value[i][j])
|
||||
|
||||
def render_content(self):
|
||||
r = TemplateIO(html=True)
|
||||
r += htmltext('<table><thead><tr><td></td>')
|
||||
for column in self.columns:
|
||||
r += htmltext('<th>%s</th>') % column
|
||||
r += htmltext('</tr></thead><tbody>')
|
||||
for i, row in enumerate(self.rows):
|
||||
r += htmltext('<tr><th>%s</th>') % row
|
||||
for j, column in enumerate(self.columns):
|
||||
widget = self.get_widget('c-%s-%s' % (i, j))
|
||||
r += htmltext('<td>')
|
||||
r += widget.render_content()
|
||||
r += htmltext('</td>')
|
||||
r += htmltext('</tr>')
|
||||
r += htmltext('</tbody></table>')
|
||||
return r.getvalue()
|
||||
|
||||
def parse(self, request=None):
|
||||
CompositeWidget.parse(self, request=request)
|
||||
if request is None:
|
||||
request = get_request()
|
||||
if request.form or request.get_method() == 'POST':
|
||||
if self.required and not self.value:
|
||||
self.set_error(self.REQUIRED_ERROR)
|
||||
return self.value
|
||||
|
||||
def _parse(self, request):
|
||||
if self.readonly:
|
||||
return
|
||||
table = []
|
||||
for i, row in enumerate(self.rows):
|
||||
row = []
|
||||
for j, column in enumerate(self.columns):
|
||||
widget = self.get_widget('c-%s-%s' % (i, j))
|
||||
row.append(widget.parse())
|
||||
table.append(row)
|
||||
self.value = table
|
||||
|
||||
def set_value(self, value):
|
||||
self.value = value
|
||||
if not value:
|
||||
return
|
||||
for i, row in enumerate(self.rows):
|
||||
for j, column in enumerate(self.columns):
|
||||
widget = self.get_widget('c-%s-%s' % (i, j))
|
||||
widget.set_value(value[i][j])
|
||||
|
||||
|
|
Loading…
Reference in New Issue