Esempio n. 1
0
    def __init__(self, form, eid, options, label=NotGiven, vtype=NotGiven,
                 defaultval=NotGiven, strip=True, choose='Choose:',
                 auto_validate=True, invalid=[], error_msg=None,
                 required=False, **kwargs):
        self.multiple = bool(kwargs.pop('multiple', False))
        FormFieldElementBase.__init__(self, form, eid, label,
                                      vtype, defaultval, strip, required=required, **kwargs)

        self.options = options
        self.choose = None
        if choose:
            if isinstance(choose, list):
                self.choose = choose
            else:
                self.choose = [(-2, choose), (-1, '-' * 25)]
                if required:
                    invalid = [-2, -1] + tolist(invalid)

            self.options = self.choose + options

        if auto_validate:
            choose_as_none = [cv[0] for cv in tolist(self.choose)]
            if required:
                self.add_processor(Select(self.options, invalid, choose_as_none), error_msg)
            else:
                # NotGiven is a valid option as long as a value isn't required
                ok_values = self.options + [(NotGiven, 0)] + [(NotGivenIter, 0)]
                self.add_processor(Select(ok_values, invalid, choose_as_none), error_msg)
Esempio n. 2
0
    def validate_other(self, values, state):
        soptions = set([six.text_type(d[0] if isinstance(d, tuple) else d) for d in self.options])
        sinvalid = set([six.text_type(d) for d in tolist(self.invalid)])
        svalues = set([six.text_type(d) for d in tolist(values)])

        if len(sinvalid.intersection(svalues)) != 0:
            raise Invalid(self.message('invalid', state), values, state)

        if len(soptions.intersection(svalues)) != len(svalues):
            raise Invalid(self.message('notthere', state), values, state)

        return
Esempio n. 3
0
 def _to_python_processing(self):
     """
         if "choose" value was chosen, we need to return an emtpy
         value appropriate to `multi`
     """
     FormFieldElementBase._to_python_processing(self)
     # multiple select fields should always return a list
     if self.multiple and not is_notgiven(self._safeval):
         self._safeval = tolist(self._safeval)
Esempio n. 4
0
 def _to_python(self, value, state):
     valiter = tolist(value)
     as_empty = [str(d) for d in tolist(self.as_empty)]
     vallist = [str(d) for d in valiter]
     # single
     if len(vallist) == 1:
         if vallist[0] in as_empty:
             return None
         return value
     # multiple
     to_remove = []
     for index, val in enumerate(vallist):
         if val in as_empty:
             to_remove.append(index)
     adjust = 0
     for index in to_remove:
         del valiter[index - adjust]
         adjust += 1
     return valiter
Esempio n. 5
0
    def _set_members(self, values):
        # convert to dict with unicode keys so our comparisons are always
        # the same type
        values = dict([(str(v), 1) for v in tolist(values)])

        # based on our values, set our members to chosen or not chosen
        for key, el in self.members.items():
            if str(key) in values:
                el.chosen = True
            else:
                el.chosen = False
Esempio n. 6
0
    def render_html(self):
        def option_tag(opt):
            if isinstance(opt, (list, tuple)):
                value, label = opt
            else:
                value = label = opt
            return tags.Option(label, str(value))

        displayval = self.displayval if self.displayval or self.displayval == 0 else None
        displayval = [str(val) for val in tolist(displayval)]
        options = [option_tag(opt) for opt in self.options]
        return tags.select(self.nameattr or self.id, displayval, options, **self.attributes)
Esempio n. 7
0
    def _to_python(self, value, state):
        field = state
        multiple = getattr(field, 'multiple', False)
        if self.multi_check:
            if not multiple:
                if is_iterable(value):
                    raise Invalid(self.message('nonmultiple', state), value, state)

        # now apply the validator to the value
        if not multiple or is_notgiven(value) or \
                getattr(self.validator, 'handles_multiples', False):
            return self.validator.to_python(value, state)
        else:
            retval = []
            for v in tolist(value):
                retval.append(self.validator.to_python(v, state))
            return retval
Esempio n. 8
0
    def render_static(self):
        if self.displayval == '':
            todisplay = literal(' ')
        else:
            values = []

            def mapf(option):
                if isinstance(option, tuple):
                    return str(option[0]), option[1]
                else:
                    return str(option), option
            lookup = dict(map(mapf, self.options))
            for key in tolist(self.displayval):
                try:
                    values.append(lookup[str(key)])
                except KeyError:
                    pass
            todisplay = ', '.join(values)

        self.add_attr('class', 'select')
        return HTML.span(todisplay, **self._static_attributes())
Esempio n. 9
0
    def _to_python_processing(self):  # noqa
        """
        filters, validates, and converts the submitted value based on
        element settings and processors
        """

        # if the value has already been processed, don't process it again
        if self._valid is not None:
            return

        valid = True
        value = self.submittedval

        # strip if necessary
        if self.strip and isinstance(value, str):
            value = value.strip()
        elif self.strip and is_iterable(value):
            newvalue = []
            for item in value:
                if isinstance(item, str):
                    newvalue.append(item.strip())
                else:
                    newvalue.append(item)
            if newvalue:
                value = newvalue

        # if nothing was submitted, but we have an if_missing, substitute
        if is_notgiven(value) and self.if_missing is not NotGiven:
            value = self.if_missing

        # handle empty or missing submit value with if_empty
        if is_empty(value) and self.if_empty is not NotGiven:
            value = self.if_empty
        # standardize all empty values as None if if_empty not given
        elif is_empty(value) and not is_notgiven(value):
            value = None

        # process required
        if self.required and self.required_empty_test(value):
            valid = False
            self.add_error('field is required')

        # process processors
        for processor, msg in self.processors:
            try:
                processor = MultiValues(processor)
                ap_value = processor.to_python(value, self)

                # FormEncode takes "empty" values and returns None
                # Since NotGiven == '', FormEncode thinks its empty
                # and returns None on us.  We override that here.
                if ap_value is not None or value is not NotGiven:
                    value = ap_value
            except formencode.Invalid as e:
                valid = False
                self.add_error((msg or str(e)))
        else:
            # we rely on MultiValues for this, but if no processor,
            # it doesn't get called
            if getattr(self, 'multiple', False) and not is_iterable(value):
                value = tolist(value)

        ###
        # Doing these again in case the processors changed the value
        ###
        # handle empty or missing submit value with if_empty
        if is_empty(value) and self.if_empty is not NotGiven:
            value = self.if_empty
        # standardize all empty values as None if if_empty not given
        elif is_empty(value) and not is_notgiven(value):
            value = None

        # process required
        if self.required and self.required_empty_test(value) and \
                'field is required' not in self.errors:
            valid = False
            self.add_error('field is required')

        # If its empty, there is no reason to run the converters.  By default,
        # the validators don't do anything if the value is empty and they WILL
        # try to convert our NotGiven value, which we want to avoid.  Therefore,
        # just skip the conversion.
        if not is_empty(value):
            # process type conversion
            if self.vtype is not NotGiven:
                if self.vtype in ('boolean', 'bool'):
                    tvalidator = formencode.compound.Any(fev.Bool(), fev.StringBool())
                elif self.vtype in ('integer', 'int'):
                    tvalidator = fev.Int
                elif self.vtype in ('number', 'num', 'float'):
                    tvalidator = fev.Number
                elif self.vtype in ('decimal'):
                    tvalidator = Decimal
                elif self.vtype in ('str', 'string'):
                    tvalidator = fev.String
                elif self.vtype in ('unicode', 'uni'):
                    tvalidator = fev.UnicodeString
                try:
                    tvalidator = MultiValues(tvalidator, multi_check=False)
                    value = tvalidator.to_python(value, self)
                except formencode.Invalid as e:
                    valid = False
                    self.add_error(str(e))

        # save
        if valid:
            self._safeval = value
            self._valid = True
        else:
            # is if_invalid if applicable
            if self.if_invalid is not NotGiven:
                # we might want to clear error messages too, but the extra
                # detail probably won't hurt (for now)
                self._safeval = self.if_invalid
                self._valid = True
            else:
                self._valid = False
Esempio n. 10
0
 def test_tolist_nonmutable_default(self):
     x = tolist(None)
     assert x == []
     x.append(3)
     assert tolist(None) == []
Esempio n. 11
0
 def test_tolist(self):
     assert tolist([1, 2]) == [1, 2]
     assert tolist((1, 2)) == [1, 2]
     assert tolist(1) == [1]
     assert tolist(None) == []
     assert tolist(None, [1, 2]) == [1, 2]