add parameter to get the list field options from an external source (#1459)
This commit is contained in:
parent
dc9530c6a5
commit
edbd5b3a38
|
@ -0,0 +1,75 @@
|
|||
# w.c.s. - web application for online forms
|
||||
# Copyright (C) 2005-2012 Entr'ouvert
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from quixote.html import htmltext, TemplateIO
|
||||
from qommon.form import *
|
||||
|
||||
|
||||
data_source_functions = {}
|
||||
|
||||
def register_data_source_function(function, function_name=None):
|
||||
if not function_name:
|
||||
function_name = function.__name__
|
||||
if not function_name in data_source_functions:
|
||||
data_source_functions[function_name] = function
|
||||
|
||||
|
||||
class DataSourceSelectionWidget(CompositeWidget):
|
||||
def __init__(self, name, value = None, **kwargs):
|
||||
CompositeWidget.__init__(self, name, value, **kwargs)
|
||||
|
||||
if not value:
|
||||
value = {}
|
||||
|
||||
options = [('none', _('None')),
|
||||
('formula', _('Formula (Python)'))]
|
||||
|
||||
self.add(SingleSelectWidget, 'type', options = options, value = value.get('type'))
|
||||
|
||||
self.parse()
|
||||
if not self.value:
|
||||
self.value = {}
|
||||
|
||||
if self.value.get('type') == 'formula':
|
||||
self.add(StringWidget, 'value', value = value.get('value'))
|
||||
|
||||
self.add(SubmitWidget, 'apply', value = _('Apply'))
|
||||
|
||||
self._parsed = False
|
||||
|
||||
|
||||
def _parse(self, request):
|
||||
values = {}
|
||||
for name in ('type', 'value'):
|
||||
value = self.get(name)
|
||||
if value:
|
||||
values[name] = value
|
||||
if values.get('data', '').startswith('------'):
|
||||
values = None
|
||||
self.value = values or None
|
||||
|
||||
def render_content(self):
|
||||
r = TemplateIO(html=True)
|
||||
for widget in self.get_widgets():
|
||||
r += widget.render_content()
|
||||
return r.getvalue()
|
||||
|
||||
|
||||
def get_items(data_source):
|
||||
if data_source.get('type') == 'formula':
|
||||
vars = get_publisher().substitutions.get_context_variables()
|
||||
return eval(data_source.get('value'), vars, data_source_functions)
|
||||
return []
|
|
@ -33,6 +33,8 @@ from qommon import get_cfg, get_logger
|
|||
|
||||
from qommon.strftime import strftime
|
||||
|
||||
import data_sources
|
||||
|
||||
|
||||
def fixcsv(self, v):
|
||||
if type(s) is not str: return s
|
||||
|
@ -113,6 +115,7 @@ class Field:
|
|||
convert_value_to_str = None
|
||||
in_listing = False
|
||||
prefill = None
|
||||
store_display_value = None
|
||||
|
||||
stats = None
|
||||
|
||||
|
@ -649,33 +652,72 @@ class ItemField(WidgetField):
|
|||
items = []
|
||||
show_as_radio = False
|
||||
widget_class = SingleSelectHintWidget
|
||||
data_source = None
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
self.items = []
|
||||
WidgetField.__init__(self, **kwargs)
|
||||
|
||||
def perform_more_widget_changes(self, form, kwargs, edit = True):
|
||||
if edit:
|
||||
kwargs['options'] = self.items or [(None, '---')]
|
||||
if self.show_as_radio:
|
||||
self.widget_class = RadiobuttonsWidget
|
||||
if len(kwargs['options']) > 3 or len(self.items[0]) > 10:
|
||||
# TODO: absence/presence of delimitor should be an option
|
||||
kwargs['delim'] = htmltext('<br />')
|
||||
if self.data_source:
|
||||
kwargs['options'] = data_sources.get_items(self.data_source)
|
||||
elif self.items:
|
||||
kwargs['options'] = self.items
|
||||
else:
|
||||
self.widget_class = StringWidget
|
||||
kwargs['options'] = [(None, '---')]
|
||||
if self.show_as_radio:
|
||||
self.widget_class = RadiobuttonsWidget
|
||||
if len(kwargs['options']) > 3 or len(self.items[0]) > 10:
|
||||
# TODO: absence/presence of delimitor should be an option
|
||||
kwargs['delim'] = htmltext('<br />')
|
||||
|
||||
def get_display_value(self, value):
|
||||
real_value = value
|
||||
label_value = str(value)
|
||||
kwargs = {}
|
||||
self.perform_more_widget_changes(form, kwargs, False)
|
||||
if type(kwargs['options'][0]) in (tuple, list):
|
||||
for key, value in kwargs['options']:
|
||||
if str(key) == str(real_value):
|
||||
label_value = value
|
||||
break
|
||||
return label_value
|
||||
|
||||
def add_to_view_form(self, form, value = None):
|
||||
real_value = value
|
||||
label_value = self.get_display_value(value)
|
||||
self.field_key = 'f%s' % self.id
|
||||
|
||||
get_request().form[self.field_key + '_label'] = label_value # :/
|
||||
form.add(StringWidget, self.field_key + '_label', title = self.label,
|
||||
value=label_value, readonly = 'readonly', size=len(label_value))
|
||||
form.add(HiddenWidget, self.field_key, value=real_value)
|
||||
|
||||
def store_display_value(self, value):
|
||||
kwargs = {}
|
||||
self.perform_more_widget_changes(None, kwargs, False)
|
||||
if type(kwargs['options'][0]) in (tuple, list):
|
||||
for key, option_value in kwargs['options']:
|
||||
if str(key) == str(value):
|
||||
return option_value
|
||||
return str(value)
|
||||
|
||||
def fill_admin_form(self, form):
|
||||
WidgetField.fill_admin_form(self, form)
|
||||
form.add(WidgetList, 'items', title = _('Items'), element_type = StringWidget,
|
||||
value = self.items, required = True,
|
||||
element_kwargs = {'render_br': False, 'size': 50},
|
||||
add_element_label = _('Add item'))
|
||||
form.add(CheckboxWidget, 'show_as_radio', title = _('Show as radio buttons'),
|
||||
value = self.show_as_radio)
|
||||
form.add(WidgetList, 'items', title = _('Items'), element_type = StringWidget,
|
||||
value = self.items, required = False,
|
||||
element_kwargs = {'render_br': False, 'size': 50},
|
||||
add_element_label = _('Add item'))
|
||||
form.add(data_sources.DataSourceSelectionWidget, 'data_source',
|
||||
value=self.data_source,
|
||||
title=_('External Data Source'),
|
||||
hint=_('This will get the available items from an external source.'),
|
||||
required=False)
|
||||
|
||||
def get_admin_attributes(self):
|
||||
return WidgetField.get_admin_attributes(self) + ['items', 'show_as_radio']
|
||||
return WidgetField.get_admin_attributes(self) + ['items', 'show_as_radio', 'data_source']
|
||||
|
||||
def check_admin_form(self, form):
|
||||
items = form.get_widget('items').parse()
|
||||
|
|
|
@ -320,6 +320,12 @@ class FormDef(StorableObject):
|
|||
d[field.id] = widget.parse()
|
||||
if d.get(field.id) and field.convert_value_from_str:
|
||||
d[field.id] = field.convert_value_from_str(d[field.id])
|
||||
if d.get(field.id) and field.store_display_value:
|
||||
display_value = field.store_display_value(d[field.id])
|
||||
if display_value:
|
||||
d['%s_display' % field.id] = display_value
|
||||
elif d.has_key('%s_display' % field.id):
|
||||
del d['%s_display' % field.id]
|
||||
if widget and widget.cleanup:
|
||||
widget.cleanup()
|
||||
|
||||
|
|
|
@ -275,7 +275,12 @@ class FormStatusPage(Directory):
|
|||
|
||||
if not self.filled.data.has_key(f.id):
|
||||
continue
|
||||
value = self.filled.data[f.id]
|
||||
|
||||
if f.store_display_value:
|
||||
value = self.filled.data['%s_display' % f.id]
|
||||
else:
|
||||
value = self.filled.data[f.id]
|
||||
|
||||
if value is None or value == '':
|
||||
continue
|
||||
|
||||
|
|
Loading…
Reference in New Issue