• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

zopefoundation / zc.form / 16248976557

21 Oct 2024 07:16AM UTC coverage: 82.759%. Remained the same
16248976557

push

github

icemac
Back to development: 2.2

126 of 180 branches covered (70.0%)

Branch coverage included in aggregate %.

786 of 922 relevant lines covered (85.25%)

0.85 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

85.86
/src/zc/form/browser/unionwidget.py
1
##############################################################################
2
#
3
# Copyright (c) 2003-2004 Zope Foundation and Contributors.
4
# All Rights Reserved.
5
#
6
# This software is subject to the provisions of the Zope Public License,
7
# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
8
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
9
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
10
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
11
# FOR A PARTICULAR PURPOSE.
12
#
13
##############################################################################
14
"""Union widget"""
15

16
from zope import component
1✔
17
from zope.browserpage import ViewPageTemplateFile
1✔
18
from zope.formlib import namedtemplate
1✔
19
from zope.formlib.interfaces import IInputWidget
1✔
20
from zope.formlib.interfaces import WidgetInputError
1✔
21

22
import zc.form.interfaces
1✔
23
from zc.form.i18n import _
1✔
24

25
from .widgetapi import BaseWidget
1✔
26

27

28
class CompositeOptionWidget(BaseWidget):
1✔
29

30
    def __call__(self):
1✔
31
        return None
1✔
32

33

34
class NotChosenWidget:
1✔
35
    error = name = None
1✔
36
    required = False
1✔
37

38
    def __init__(self, label, hint):
1✔
39
        self.label = label
1✔
40
        self.hint = hint
1✔
41

42
    def __call__(self):
1✔
43
        return None
1✔
44

45

46
class UnionWidget(BaseWidget):
1✔
47

48
    _field_index = None
1✔
49

50
    no_value_label = _('union_field_label-no_value', "Not specified")
1✔
51
    no_value_hint = _('union_field_hint-no_value', '')
1✔
52

53
    def loadValueFromRequest(self):
1✔
54
        field = self.context
1✔
55
        missing_value = field.missing_value
1✔
56
        value = self.request.form.get(self.name)
1✔
57
        try:
1✔
58
            value = int(value)
1✔
59
        except (TypeError, ValueError):
×
60
            value = missing_value
×
61
        else:
62
            if value >= len(field.fields):
1!
63
                value = missing_value
×
64
            else:
65
                self._field_index = value
1✔
66
                # value should be an int index of the active field
67
                active = field.fields[value].bind(self.context)
1✔
68
                if zc.form.interfaces.IOptionField.providedBy(active):
1!
69
                    return active.getValue()
×
70
                widget = component.getMultiAdapter(
1✔
71
                    (active, self.request), IInputWidget)
72
                widget.required = widget.context.required = self.required
1✔
73
                widget.setPrefix(self.name)
1✔
74
                try:
1✔
75
                    return widget.getInputValue()
1✔
76
                except WidgetInputError as e:
×
77
                    # recast with our name and title
78
                    self._error = WidgetInputError(
×
79
                        self.context.__name__,
80
                        self.label,
81
                        e.errors)
82
        return missing_value
×
83

84
    template = namedtemplate.NamedTemplate('default')
1✔
85

86
    def render(self, value):
1✔
87
        # choices = ({selected, identifier, widget},)
88
        # widget may be None, name may be None.
89
        field = self.context
1✔
90
        missing_value = field.missing_value
1✔
91
        choices = []
1✔
92
        field_index = self._field_index
1✔
93
        if field_index is not None:
1!
94
            chosen_field = field.fields[self._field_index]
×
95
        elif value is not missing_value:
1✔
96
            chosen_field = field.validField(value)
1✔
97
        else:
98
            chosen_field = None
1✔
99
        for ix, inner_field in enumerate(field.fields):
1✔
100
            selected = inner_field is chosen_field
1✔
101
            inner = inner_field.bind(field.context)
1✔
102
            identifier = "%s-%02d" % (self.name, ix)
1✔
103
            if zc.form.interfaces.IOptionField.providedBy(inner):
1✔
104
                widget = CompositeOptionWidget(inner, self.request)
1✔
105
            else:
106
                widget = component.getMultiAdapter(
1✔
107
                    (inner, self.request), IInputWidget)
108
                if selected:
1!
109
                    widget.setRenderedValue(value)
×
110
                elif self._renderedValueSet():
1!
111
                    if field.use_default_for_not_selected:
1✔
112
                        widget.setRenderedValue(inner.default)
1✔
113
                    else:
114
                        widget.setRenderedValue(inner.missing_value)
1✔
115
            widget.setPrefix(self.name)
1✔
116
            choices.append(
1✔
117
                {'selected': selected, 'identifier': identifier,
118
                 'widget': widget, 'value': str(ix)})
119
        if not field.required:
1✔
120
            ix += 1
1✔
121
            selected = chosen_field is None
1✔
122
            identifier = "%s-%02d" % (self.name, ix)
1✔
123
            widget = NotChosenWidget(self.no_value_label, self.no_value_hint)
1✔
124
            choices.append(
1✔
125
                {'selected': selected, 'identifier': identifier,
126
                 'widget': widget, 'value': str(ix)})
127
        return self.template(choices=choices)
1✔
128

129

130
default_template = namedtemplate.NamedTemplateImplementation(
1✔
131
    ViewPageTemplateFile('unionwidget.pt'), UnionWidget)
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc