def slider_edit_renderer(widget, data): value = fetch_value(widget, data) content = '' range = attr_value('range', widget, data) if range is True: lower_input_attrs = { 'type': 'text', 'name': '%s.lower' % widget.dottedpath, 'id': cssid(widget, 'input-lower'), 'style': 'display:none;', 'class': 'lower_value', 'value': value and value[0], } content += data.tag('input', **lower_input_attrs) upper_input_attrs = { 'type': 'text', 'name': '%s.upper' % widget.dottedpath, 'id': cssid(widget, 'input-upper'), 'style': 'display:none;', 'class': 'upper_value', 'value': value and value[1], } content += data.tag('input', **upper_input_attrs) else: input_attrs = { 'type': 'text', 'name': widget.dottedpath, 'id': cssid(widget, 'input'), 'style': 'display:none;', 'class': 'slider_value', 'value': value, } content += data.tag('input', **input_attrs) show_value = attr_value('show_value', widget, data) if show_value: unit = attr_value('unit', widget, data) if unit: content += data.tag('span', '%s: ' % unit, **{'class': 'unit'}) if range is True: content += data.tag('span', value[0], **{'class': 'lower_value'}) content += ' - ' content += data.tag('span', value[1], **{'class': 'upper_value'}) else: content += data.tag('span', value, **{'class': 'slider_value'}) slider_attrs = {'class': 'slider'} if attr_value('orientation', widget, data) == 'vertical': height = attr_value('height', widget, data) if height: slider_attrs['style'] = 'height:%spx;' % height content += data.tag('div', ' ', **slider_attrs) wrapper_attrs = data_attrs_helper(widget, data, js_options) wrapper_attrs['class'] = cssclasses(widget, data) html_data = widget.attrs['data'] data_keys = html_data.keys() for key in data_keys: if key in js_options: raise ValueError(u"Additional data dict contains reserved " u"attribute name '%s'" % key) wrapper_attrs['data-%s' % key] = html_data[key] return data.tag('div', content, **wrapper_attrs)
def reference_renderer(widget, data): """Properties: multivalued flag whether reference field is multivalued target ajax target for reference browser triggering """ if widget.attrs.get('multivalued'): return wrap_ajax_target(select_edit_renderer(widget, data), widget) value = ['', ''] if data.extracted is not UNSET: value = [data.extracted, data.request.get(widget.dottedpath)] elif data.request.get('%s.uid' % widget.dottedpath): value = [ data.request.get('%s.uid' % widget.dottedpath), data.request.get(widget.dottedpath), ] elif data.value is not UNSET and data.value is not None: value = data.value text_attrs = { 'type': 'text', 'value': value[1], 'name_': widget.dottedpath, 'id': cssid(widget, 'input'), 'class_': cssclasses(widget, data), } hidden_attrs = { 'type': 'hidden', 'value': value[0], 'name_': '%s.uid' % widget.dottedpath, } return wrap_ajax_target( tag('input', **text_attrs) + tag('input', **hidden_attrs), widget)
def div_renderer(widget, data): attrs = { 'id': attr_value('id', widget, data), 'class_': cssclasses(widget, data) } attrs.update(as_data_attrs(attr_value('data', widget, data))) return data.tag('div', data.rendered, **attrs)
def reference_renderer(widget, data): if widget.attrs.get('multivalued'): return select_renderer(widget, data) value = ['', ''] if data.extracted is not UNSET: value = [data.extracted, data.request.get(widget.dottedpath)] elif data.request.get('%s.uid' % widget.dottedpath): value = [ data.request.get('%s.uid' % widget.dottedpath), data.request.get(widget.dottedpath), ] elif data.value is not UNSET and data.value is not None: value = data.value text_attrs = { 'type': 'text', 'value': value[1], 'name_': widget.dottedpath, 'id': cssid(widget, 'input'), 'class_': cssclasses(widget, data), } hidden_attrs = { 'type': 'hidden', 'value': value[0], 'name_': '%s.uid' % widget.dottedpath, } return tag('input', **text_attrs) + tag('input', **hidden_attrs)
def render_time_input(widget, data, value, postfix=None, css_class=False): tag = data.tag widgetname = widget.dottedpath if postfix: widgetname = '{}.{}'.format(widgetname, postfix) if value is True: value = '' if not value and data.request: value = data.request.get(widgetname) disabled = 'disabled' if attr_value('disabled', widget, data) else None attrs = { 'type': 'text', 'value': value, 'name_': widgetname, 'id': cssid(widget, 'input', postfix), 'size': 5, 'disabled': disabled, } class_ = [attr_value('timeinput_class', widget, data)] timepicker = attr_value('timepicker', widget, data) if timepicker and not disabled: class_.append(attr_value('timepicker_class', widget, data)) if css_class: attrs['class_'] = cssclasses(widget, data, additional=class_) else: attrs['class_'] = ' '.join(class_) return tag('input', **attrs)
def render_time_input(widget, data, value, postfix=None, css_class=False): tag = data.tag widgetname = widget.dottedpath if postfix: widgetname = '%s.%s' % (widgetname, postfix) if value is True: value = '' if not value and data.request: value = data.request.get(widgetname) disabled = attr_value('disabled', widget, data) and 'disabled' or None attrs = { 'type': 'text', 'value': value, 'name_': widgetname, 'id': cssid(widget, 'input', postfix), 'size': 5, 'disabled': disabled, } class_ = '' timepicker = attr_value('timepicker', widget, data) if timepicker and not disabled: class_ = attr_value('timepicker_class', widget, data) if css_class: additional = class_ and [class_] or list() attrs['class_'] = cssclasses(widget, data, additional=additional) elif class_: attrs['class_'] = class_ return tag('input', **attrs)
def td_renderer(widget, data): attrs = { "id": widget.attrs.get("id"), "class_": cssclasses(widget, data), "colspan": widget.attrs.get("colspan"), "rowspan": widget.attrs.get("rowspan"), } return data.tag("td", data.rendered, **attrs)
def fieldset_renderer(widget, data): fs_attrs = { 'id': cssid(widget, 'fieldset'), 'class_': cssclasses(widget, data) } rendered = data.rendered if widget.attrs['legend']: rendered = data.tag('legend', widget.attrs['legend']) + rendered return data.tag('fieldset', rendered, **fs_attrs)
def hidden_renderer(widget, data): hidden_attrs = { 'type': 'hidden', 'value': fetch_value(widget, data), 'name_': widget.dottedpath, 'id': cssid(widget, 'input'), 'class_': cssclasses(widget, data), } return data.tag('input', **hidden_attrs)
def recaptcha_edit_renderer(widget, data): recaptcha_attrs = { 'id': cssid(widget, 'recaptcha'), 'class': ' '.join([cssclasses(widget, data)]), } data_attrs = ['theme', 'lang', 'public_key'] recaptcha_attrs.update(data_attrs_helper(widget, data, data_attrs)) recaptcha = data.tag('div', ' ', **recaptcha_attrs) public_key = attr_value('public_key', widget, data) return recaptcha + NO_SCRIPT_TEMPLATE.format(public_key=public_key)
def fieldset_renderer(widget, data): fs_attrs = { 'id': cssid(widget, 'fieldset'), 'class_': cssclasses(widget, data) } rendered = data.rendered legend = attr_value('legend', widget, data) if legend: rendered = data.tag('legend', legend) + rendered return data.tag('fieldset', rendered, **fs_attrs)
def div_renderer(widget, data): attrs = { 'id': widget.attrs.get('id'), 'class_': cssclasses(widget, data), } if len(widget): rendered = compound_renderer(widget, data) else: rendered = data.rendered return data.tag('div', rendered, **attrs)
def th_renderer(widget, data): attrs = { 'id': attr_value('id', widget, data), 'class_': cssclasses(widget, data), 'colspan': attr_value('colspan', widget, data), 'rowspan': attr_value('rowspan', widget, data), } contents = attr_value('label', widget, data) if not contents: contents = data.rendered return data.tag('th', contents, **attrs)
def th_renderer(widget, data): attrs = { "id": widget.attrs.get("id"), "class_": cssclasses(widget, data), "colspan": widget.attrs.get("colspan"), "rowspan": widget.attrs.get("rowspan"), } contents = widget.attrs.get("label") if not contents: contents = data.rendered return data.tag("th", contents, **attrs)
def th_renderer(widget, data): attrs = { 'id': widget.attrs.get('id'), 'class_': cssclasses(widget, data), 'colspan': widget.attrs.get('colspan'), 'rowspan': widget.attrs.get('rowspan'), } contents = widget.attrs.get('label') if not contents: contents = data.rendered return data.tag('th', contents, **attrs)
def array_display_proxy_renderer(widget, data): """B/C. Use ``display_proxy`` widget attribute. """ input_attrs = { 'type': 'hidden', 'value': fetch_value(widget, data), 'name_': widget.dottedpath, 'id': cssid(widget, 'input'), 'class_': cssclasses(widget, data), 'required': attr_value('required', widget, data) and 'required' or None } return data.tag('input', **input_attrs) + data.rendered
def form_renderer(widget, data): form_attrs = { 'action': widget.attrs['action'], 'method': widget.attrs['method'], 'enctype': widget.attrs['method']=='post' and \ widget.attrs['enctype'] or None, 'class_': cssclasses(widget, data), 'id': 'form-%s' % '-'.join(widget.path), } if callable(form_attrs['action']): form_attrs['action'] = form_attrs['action'](widget, data) return data.tag('form', data.rendered, **form_attrs)
def td_renderer(widget, data): attrs = { 'id': widget.attrs.get('id'), 'class_': cssclasses(widget, data), 'colspan': widget.attrs.get('colspan'), 'rowspan': widget.attrs.get('rowspan'), } if len(widget): rendered = compound_renderer(widget, data) else: rendered = data.rendered return data.tag('td', rendered, **attrs)
def form_edit_renderer(widget, data): method = attr_value('method', widget, data) enctype = method == 'post' and attr_value('enctype', widget, data) or None noval = attr_value('novalidate', widget, data) and 'novalidate' or None form_attrs = { 'action': attr_value('action', widget, data), 'method': method, 'enctype': enctype, 'novalidate': noval, 'class_': cssclasses(widget, data), 'id': 'form-{0}'.format('-'.join(widget.path)), } return data.tag('form', data.rendered, **form_attrs)
def form_edit_renderer(widget, data): form_attrs = { 'action': widget.attrs['action'], 'method': widget.attrs['method'], 'enctype': widget.attrs['method'] == 'post' and \ widget.attrs['enctype'] or None, 'novalidate': widget.attrs['novalidate'] and 'novalidate' or None, 'class_': cssclasses(widget, data), 'id': 'form-%s' % '-'.join(widget.path), } if callable(form_attrs['action']): form_attrs['action'] = form_attrs['action'](widget, data) return data.tag('form', data.rendered, **form_attrs)
def form_edit_renderer(widget, data): method = attr_value('method', widget, data) enctype = method == 'post' and attr_value('enctype', widget, data) or None noval = attr_value('novalidate', widget, data) and 'novalidate' or None form_attrs = { 'action': attr_value('action', widget, data), 'method': method, 'enctype': enctype, 'novalidate': noval, 'class_': cssclasses(widget, data), 'id': 'form-{0}'.format('-'.join(widget.path)), } form_attrs.update(as_data_attrs(attr_value('data', widget, data))) return data.tag('form', data.rendered, **form_attrs)
def reference_edit_renderer(widget, data): """Properties: multivalued flag whether reference field is multivalued. vocabulary if multivalued, provide a vocabulary mapping uids to node names. target ajax target for reference browser triggering. root path of reference browser root. Defaults to '/' referencable list of node info names which are referencable. Defaults to '', which means all objects are referencable, given they provide ``IUUIDAware`` and a node info. """ if widget.attrs.get('multivalued'): rendered = select_edit_renderer(widget, data) return wrap_ajax_target(rendered, widget, data) value = ['', ''] if data.extracted is not UNSET: value = [data.extracted, data.request.get(widget.dottedpath)] elif data.request.get('{}.uid'.format(widget.dottedpath)): value = [ data.request.get('{}.uid'.format(widget.dottedpath)), data.request.get(widget.dottedpath), ] elif data.value is not UNSET and data.value is not None: value = data.value text_attrs = { 'type': 'text', 'value': value[1], 'name_': widget.dottedpath, 'id': cssid(widget, 'input'), 'class_': cssclasses(widget, data), 'readonly': 'readonly', } hidden_attrs = { 'type': 'hidden', 'value': value[0], 'name_': '{}.uid'.format(widget.dottedpath), } rendered = tag('input', **text_attrs) + tag('input', **hidden_attrs) return wrap_ajax_target(rendered, widget, data)
def reference_edit_renderer(widget, data): """Properties: multivalued flag whether reference field is multivalued. vocabulary if multivalued, provide a vocabulary mapping uids to node names. target ajax target for reference browser triggering. root path of reference browser root. Defaults to '/' referencable list of node info names which are referencable. Defaults to '', which means all objects are referencable, given they provide ``IUUIDAware`` and a node info. """ if widget.attrs.get('multivalued'): rendered = select_edit_renderer(widget, data) return wrap_ajax_target(rendered, widget, data) value = ['', ''] if data.extracted is not UNSET: value = [data.extracted, data.request.get(widget.dottedpath)] elif data.request.get('%s.uid' % widget.dottedpath): value = [ data.request.get('%s.uid' % widget.dottedpath), data.request.get(widget.dottedpath), ] elif data.value is not UNSET and data.value is not None: value = data.value text_attrs = { 'type': 'text', 'value': value[1], 'name_': widget.dottedpath, 'id': cssid(widget, 'input'), 'class_': cssclasses(widget, data), 'readonly': 'readonly', } hidden_attrs = { 'type': 'hidden', 'value': value[0], 'name_': '%s.uid' % widget.dottedpath, } rendered = tag('input', **text_attrs) + tag('input', **hidden_attrs) return wrap_ajax_target(rendered, widget, data)
def array_wrapper_renderer(widget, data): add_css = '' if not widget.attrs['static']: for attr in ['add', 'remove', 'sort']: if widget.attrs[attr]: add_css += ' array-%s' % attr else: add_css += ' array-static' kw = { 'id': cssid(widget, 'array'), 'class': cssclasses(widget, data) + add_css, } if not 'array' in kw['class'].split(' '): kw['class'] = 'array %s' % kw['class'] rendered = data.rendered return data.tag('div', rendered, **kw)
def render_datetime_input(widget, data, date, time): tag = data.tag timeinput = '' if time: timeinput = render_time_input(widget, data, time, postfix='time') additional_classes = [attr_value('dateinput_class', widget, data)] datepicker = attr_value('datepicker', widget, data) disabled = attr_value('disabled', widget, data) if datepicker and not disabled: datepicker_class = attr_value('datepicker_class', widget, data) additional_classes.append(datepicker_class) attrs = { 'type': 'text', 'value': date, 'name_': widget.dottedpath, 'id': cssid(widget, 'input'), 'class_': cssclasses(widget, data, additional=additional_classes), 'size': 10, 'disabled': 'disabled' if disabled else None, } return tag('input', **attrs) + timeinput
def render_datetime_input(widget, data, date, time): tag = data.tag timeinput = '' if time: timeinput = render_time_input(widget, data, time, 'time') additional_classes = [] datepicker = attr_value('datepicker', widget, data) disabled = attr_value('disabled', widget, data) if datepicker and not disabled: datepicker_class = attr_value('datepicker_class', widget, data) additional_classes.append(datepicker_class) attrs = { 'type': 'text', 'value': date, 'name_': widget.dottedpath, 'id': cssid(widget, 'input'), 'class_': cssclasses(widget, data, additional=additional_classes), 'size': 10, 'disabled': disabled and 'disabled' or None, } return tag('input', **attrs) + timeinput
def reference_edit_renderer(widget, data): if widget.attrs.get('multivalued'): prepare_vocab_property(widget, data) rendered = select_edit_renderer(widget, data) trigger = reference_trigger_renderer(widget, data) return wrap_ajax_target(rendered + trigger, widget, data) label = fetch_reference_label(widget, data) value = fetch_reference_value(widget, data) text_attrs = { 'type': 'text', 'value': label, 'name_': widget.dottedpath, 'id': cssid(widget, 'input'), 'class_': cssclasses(widget, data), 'readonly': 'readonly', } hidden_attrs = { 'type': 'hidden', 'value': value if value else '', 'name_': '{}.uid'.format(widget.dottedpath), } rendered = tag('input', **text_attrs) + tag('input', **hidden_attrs) trigger = reference_trigger_renderer(widget, data) return wrap_ajax_target(rendered + trigger, widget, data)
def tr_renderer(widget, data): attrs = { 'id': widget.attrs.get('id'), 'class_': cssclasses(widget, data), } return data.tag('tr', data.rendered, **attrs)
def test_css_classes(self): # Test CSS Classes @plumbing(Nodespaces, Attributes) class CSSTestNode(OrderedNode): pass widget = CSSTestNode() widget.attrs['required'] = False widget.attrs['required_class'] = None widget.attrs['required_class_default'] = 'required' widget.attrs['error_class'] = None widget.attrs['error_class_default'] = 'error' widget.attrs['class'] = None widget.attrs['class_add'] = None class DummyData(object): def __init__(self): self.errors = [] data = DummyData() self.assertEqual(cssclasses(widget, data), None) widget.attrs['class'] = 'foo bar' self.assertEqual(cssclasses(widget, data), 'bar foo') widget.attrs['class'] = None widget.attrs['required'] = True self.assertEqual(cssclasses(widget, data), None) widget.required = False data.errors = True self.assertEqual(cssclasses(widget, data), None) widget.attrs['error_class'] = True self.assertEqual(cssclasses(widget, data), 'error') widget.attrs['class'] = 'foo bar' self.assertEqual(cssclasses(widget, data), 'bar error foo') widget.attrs['class'] = lambda w, d: 'baz' self.assertEqual(cssclasses(widget, data), 'baz error') widget.attrs['class_add'] = lambda w, d: 'addclass_from_callable' self.assertEqual(cssclasses(widget, data), 'addclass_from_callable baz error') widget.attrs['class_add'] = 'addclass' self.assertEqual(cssclasses(widget, data), 'addclass baz error') widget.attrs['class'] = None widget.attrs['class_add'] = None widget.attrs['error_class'] = 'othererror' self.assertEqual(cssclasses(widget, data), 'othererror') data.errors = False self.assertEqual(cssclasses(widget, data), None) widget.attrs['required'] = True self.assertEqual(cssclasses(widget, data), None) widget.attrs['required_class'] = True self.assertEqual(cssclasses(widget, data), 'required') widget.attrs['required_class'] = 'otherrequired' self.assertEqual(cssclasses(widget, data), 'otherrequired') widget.attrs['error_class'] = True data.errors = True widget.attrs['required_class'] = 'required' self.assertEqual(cssclasses(widget, data), 'error required') widget.attrs['class'] = 'foo bar' self.assertEqual(cssclasses(widget, data), 'bar error foo required') self.assertEqual(cssclasses(widget, data, additional=['zika', 'akiz']), 'akiz bar error foo required zika')
def test_css_classes(self): # Test CSS Classes @plumbing(Nodespaces, Attributes) class CSSTestNode(OrderedNode): pass widget = CSSTestNode() widget.attrs['required'] = False widget.attrs['required_class'] = None widget.attrs['required_class_default'] = 'required' widget.attrs['error_class'] = None widget.attrs['error_class_default'] = 'error' widget.attrs['class'] = None widget.attrs['class_add'] = None class DummyData(object): def __init__(self): self.errors = [] data = DummyData() self.assertEqual(cssclasses(widget, data), None) widget.attrs['class'] = 'foo bar' self.assertEqual(cssclasses(widget, data), 'bar foo') widget.attrs['class'] = None widget.attrs['required'] = True self.assertEqual(cssclasses(widget, data), None) widget.required = False data.errors = True self.assertEqual(cssclasses(widget, data), None) widget.attrs['error_class'] = True self.assertEqual(cssclasses(widget, data), 'error') widget.attrs['class'] = 'foo bar' self.assertEqual(cssclasses(widget, data), 'bar error foo') widget.attrs['class'] = lambda w, d: 'baz' self.assertEqual(cssclasses(widget, data), 'baz error') widget.attrs['class_add'] = lambda w, d: 'addclass_from_callable' self.assertEqual( cssclasses(widget, data), 'addclass_from_callable baz error' ) widget.attrs['class_add'] = 'addclass' self.assertEqual(cssclasses(widget, data), 'addclass baz error') widget.attrs['class'] = None widget.attrs['class_add'] = None widget.attrs['error_class'] = 'othererror' self.assertEqual(cssclasses(widget, data), 'othererror') data.errors = False self.assertEqual(cssclasses(widget, data), None) widget.attrs['required'] = True self.assertEqual(cssclasses(widget, data), None) widget.attrs['required_class'] = True self.assertEqual(cssclasses(widget, data), 'required') widget.attrs['required_class'] = 'otherrequired' self.assertEqual(cssclasses(widget, data), 'otherrequired') widget.attrs['error_class'] = True data.errors = True widget.attrs['required_class'] = 'required' self.assertEqual(cssclasses(widget, data), 'error required') widget.attrs['class'] = 'foo bar' self.assertEqual( cssclasses(widget, data), 'bar error foo required' ) self.assertEqual( cssclasses(widget, data, additional=['zika', 'akiz']), 'akiz bar error foo required zika' )
def tr_renderer(widget, data): attrs = { 'id': attr_value('id', widget, data), 'class_': cssclasses(widget, data), } return data.tag('tr', data.rendered, **attrs)
def table_renderer(widget, data): attrs = {"id": widget.attrs.get("id"), "class_": cssclasses(widget, data)} return data.tag("table", data.rendered, **attrs)
def cron_edit_renderer(widget, data): value = fetch_value(widget, data) if value is not UNSET and value is not attr_value('emptyvalue', widget, data, EMPTY_VALUE): value = [it.strip() for it in value.split(' ') if it.strip()] if len(value) == 5: value.append('*') if len(value) < 6: raise ValueError('Invalid cron rule') value = { 'minute': value[0], 'hour': value[1], 'dom': value[2], 'month': value[3], 'dow': value[4], 'year': value[5] } container = widget['container'] = factory( 'div', name='cron', value=value, props={ 'structural': True, 'id': cssid(widget, 'input'), 'class': cssclasses(widget, data), 'data': { 'lang': attr_value('lang', widget, data), 'start_year': attr_value('start_year', widget, data), 'end_year': attr_value('end_year', widget, data) } }) container['minute'] = factory('div:cron_value_edit_action:hidden', props={ 'persist': False, 'label': _('label_minute', default='Minute'), 'div.class': 'cron-value minute' }) container['hour'] = factory('div:cron_value_edit_action:hidden', props={ 'persist': False, 'label': _('label_hour', default='Hour'), 'div.class': 'cron-value hour' }) container['dom'] = factory('div:cron_value_edit_action:hidden', props={ 'persist': False, 'label': _('label_dom', default='Day of Month'), 'div.class': 'cron-value dom' }) container['month'] = factory('div:cron_value_edit_action:hidden', props={ 'persist': False, 'label': _('label_month', default='Month'), 'div.class': 'cron-value month' }) container['dow'] = factory('div:cron_value_edit_action:hidden', props={ 'persist': False, 'label': _('label_dow', default='Day of Week'), 'div.class': 'cron-value dow' }) container['year'] = factory('div:cron_value_edit_action:hidden', props={ 'persist': False, 'label': _('label_year', default='Year'), 'div.class': 'cron-value year' }) container['editarea'] = factory('div', props={ 'structural': True, 'class': 'editarea', })