Ejemplo n.º 1
0
    def render_tag(self, *value, **extra_attributes):
        """ return a piece of unicode HTML that """

        assert len(value) <= 1, "Can't pass more than one argument as value"

        inner = []
        attributes = {}
        # notice the order of these update() calls! It matters

        name_prefix = extra_attributes.pop("name_prefix", "")

        # It's an option to called render_tag() with in_filter=True which tells
        # us that this tag is rendered as a filter, in the filter options.
        # This is something that can be done on-the-fly and it means that
        # certain things should work differently. For example, a 'select' type
        # input get's an added 'size' and 'multiple' attribute when used as a
        # filter.
        in_filter = extra_attributes.pop("in_filter", False)

        # core attributes
        dom_id = self.attributes.get("dom_id", "id_%s" % self.getId())
        attributes.update({"name": self._wrapPythonTypeName(name_prefix), "id": dom_id, "title": self.getTitle()})

        # saved attributes
        attributes.update(dict(self.attributes))

        # extra on rendering attributes
        attributes.update(extra_attributes)

        # Now, "hack" the attributes if this is used in a filter
        if in_filter:
            if self.input_type == "select":
                attributes["multiple"] = "multiple"
                if "size" not in attributes:
                    attributes["size"] = min(5, len(list(self.getOptionsIterable())))

        # filler is a dict that we will use to render the template
        filler = {}

        if self.input_type == "textarea":
            template = u"<textarea %(inner)s>%(value)s</textarea>"

            v = None
            if value:
                v = value[0]  # from the argument
            elif "value" in attributes:
                v = attributes.pop("value")

            if v:
                filler["value"] = Utils.safe_html_quote(v)
            else:
                filler["value"] = u""

        elif self.input_type == "select":
            template = u"<select %(inner)s>\n%(all_options)s\n</select>"
            all_options = []

            v = []
            if value:
                v = value[0]
                # makes sure the value doesn't become a nested list
                if isinstance(v, list):
                    v = Utils.flatten_lines(v)

            elif "value" in attributes:
                v = attributes.pop("value")

            if not isinstance(v, (tuple, list)):
                v = [v]

            # if the value passed to render this select contains
            # items that are not in the list of options, don't
            # use the list of options.
            _values_selected = []
            for option in self.getOptionsIterable():
                if isinstance(option, (tuple, list)):
                    value, label = option
                else:
                    value, label = option, option

                if self.getPythonType() == "int":
                    try:
                        value = int(value)
                    except ValueError:
                        pass
                elif self.getPythonType() == "float":
                    try:
                        value = float(value)
                    except ValueError:
                        pass

                if value in v:
                    tmpl = u'<option value="%s" selected="selected">%s</option>'
                    _values_selected.append(value)
                else:
                    tmpl = u'<option value="%s">%s</option>'

                all_options.append(tmpl % (value, label))

            if Set(v) - Set(_values_selected):
                # there were values that weren't in the list of options!
                _values_not_in_options = list(Set(v) - Set(_values_selected))

                # if nothing was matched in the list of options,
                # reset the whole all_options list.
                if not _values_selected and all_options:
                    all_options = []

                for value in _values_not_in_options:
                    label = value
                    tmpl = u'<option value="%s" selected="selected">%s</option>'
                    all_options.append(tmpl % (value, label))

            filler["all_options"] = "\n".join(all_options)

        elif self.input_type == "radio":
            # special case
            if not self.getOptionsIterable():
                template = u"ERROR: No options"
            else:
                template = u"%(all_inputs)s"
                all_inputs = []

                v = None
                if value:
                    v = value[0]  # from the argument

                elif "value" in attributes:
                    v = attributes.pop("value")

                special_attributes = ""
                inner = []
                for k, v2 in attributes.items():
                    if k in ("id",):
                        continue
                    inner.append('%s="%s"' % (k, v2))
                if inner:
                    special_attributes = " " + " ".join(inner)

                for option in self.getOptions():
                    if isinstance(option, (tuple, list)):
                        value, label = option
                    else:
                        value, label = option, option

                    if value == v:
                        tmpl = u'<input type="radio" value="%s" checked="checked"%s /> %s<br />'
                    else:
                        tmpl = u'<input type="radio" value="%s"%s/> %s<br />'
                    all_inputs.append(tmpl % (value, special_attributes, label))

                filler["all_inputs"] = "\n".join(all_inputs)

        elif self.input_type == "checkbox":
            # another special case

            v = None
            if value:
                v = value[0]  # from the argument
            elif "value" in attributes:
                v = attributes.pop("value")

            # If there are no options you can work this like a normal text input
            if not self.getOptions():
                # but what if it should be a boolean and it's true, then the
                # tag needs to contain checked="checked"
                if v:
                    template = u'<input type="checkbox" checked="checked" %(inner)s />'
                else:
                    template = u'<input type="checkbox" %(inner)s />'

            else:
                # crap!
                template = u"%(all_inputs)s"
                all_inputs = []

                special_attributes = ""
                inner = []
                for k, v2 in attributes.items():
                    if k in ("id",):
                        continue
                    inner.append('%s="%s"' % (k, v2))
                if inner:
                    special_attributes = " " + " ".join(inner)

                for option in self.getOptions():
                    if isinstance(option, (tuple, list)):
                        value, label = option
                    else:
                        value, label = option, option

                    if value == v:
                        tmpl = u'<input type="checkbox" value="%s" checked="checked"%s /> %s<br />'
                    else:
                        tmpl = u'<input type="checkbox" value="%s"%s/> %s<br />'
                    all_inputs.append(tmpl % (value, special_attributes, label))

                filler["all_inputs"] = "\n".join(all_inputs)

        elif self.input_type == "password":

            template = u'<input type="password" %(inner)s />'

        elif self.input_type == "file":
            template = u'<input type="file" %(inner)s />'

        else:  # type text
            template = u"<input %(inner)s />"

        if not (self.input_type == "radio" or (self.input_type == "checkbox" and self.getOptions())):

            if value and self.input_type not in ("select",):
                if value and value[0]:
                    # This overrides the default value
                    attributes["value"] = value[0]

            for key, val in sorted(attributes.items()):
                inner.append('%s="%s"' % (key, val))

            filler["inner"] = " ".join(inner)

        return template % filler
Ejemplo n.º 2
0
    def testValidValue(self, value):
        """ return a tuple of (valid or not [bool], message [unicode]) if the value
        passes all the validation expressions (assuming the field has any)
        """
        # check the python type
        if self.python_type == "ustring":
            # should be possible to do this
            try:
                unicode(value)
            except TypeError:
                return False, u"Not a unicode string"
        elif self.python_type == "int":
            try:
                int(value)
            except ValueError:
                return False, u"Not an integer number"
        elif self.python_type == "float":
            try:
                float(value)
            except ValueError:
                return False, u"Not a floating point number"
        elif self.python_type == "long":
            try:
                long(value)
            except ValueError:
                return False, u"Not a long integer number"
        elif self.python_type == "date":
            try:
                if isinstance(value, basestring):
                    DateTime(value)
            except DateError:
                return False, u"Not a valid date"
        elif self.python_type == "ulines":
            if isinstance(value, basestring):
                try:
                    [unicode(x) for x in value.splitlines()]
                except ValueError:
                    return False, u"Not a list of unicode strings"
            elif value is not None:
                value = Utils.flatten_lines(value)
                try:
                    [unicode(x) for x in value]
                except ValueError:
                    return False, u"Not a list of unicode strings"
        elif self.python_type == "lines":
            if isinstance(value, basestring):
                try:
                    [str(x) for x in value.splitlines()]
                except ValueError:
                    return False, u"Not a list of strings"
            elif value is not None:
                value = Utils.flatten_lines(value)
                try:
                    [str(x) for x in value]
                except ValueError:
                    return False, u"Not a list of strings"

        # check each TALES expression
        for ve in self.getValidationExpressions():
            ec = self._getExprContext(self, extra_namespaces=dict(value=value))
            ex = Expression(ve.expression)
            if not bool(ex(ec)):
                return False, ve.message

        # by default no validation expression made it invalid
        return True, None
Ejemplo n.º 3
0
    def setCustomFieldData(self, field, key, value):
        """ append this to self.custom_fields_data (dict).
        The parameter @field is the custom field object. 
        """

        if field.input_type == "file":
            # upload the file into the issue and change @value to the id
            value.read(1)
            if self._isFile(value):
                # upload it!
                folder_id = "upload-%s" % field.getId()
                if not safe_hasattr(self, folder_id):
                    self.manage_addFolder(folder_id)
                container = getattr(self, folder_id)
                ids = self._uploadFileattachments(container, [value])
                ids = ["%s/%s" % (folder_id, x) for x in ids]
                value = ids[0]
            else:
                # nothing worth saving
                return
        elif field.python_type == "int":
            value = int(value)
        elif field.python_type == "float":
            value = float(value)
        elif field.python_type == "long":
            value = long(value)
        elif field.python_type == "lines":
            if isinstance(value, tuple):
                value = list(value)
            elif isinstance(value, basestring):
                value = [value]
            else:
                # due to way Zope's cast handles <selects>
                # with name "foo:ulines" you get
                # ['one', ['two']]
                value = Utils.flatten_lines(value)
                assert isinstance(value, list), "value not a list"
            # every item should be a str
            value = [str(x) for x in value]
        elif field.python_type == "ulines":
            if isinstance(value, tuple):
                value = list(value)
            elif isinstance(value, basestring):
                value = [value]
            elif value is None:
                value = []
            else:
                # due to way Zope's cast handles <selects>
                # with name "foo:ulines" you get
                # ['one', ['two']]
                if isinstance(value, list):
                    value = Utils.flatten_lines(value)
                assert isinstance(value, list), "value not a list it's a %s" % type(value)
            # every item should be a str
            value = [unicodify(x) for x in value]
        elif field.python_type == "date":
            if isinstance(value, basestring):
                value = DateTime(value)
        elif field.python_type == "boolean":
            value = bool(value)
        elif field.python_type == "ustring":
            value = unicodify(value)
        else:
            value = str(value)

        data = getattr(self, "custom_fields_data", None)
        if data is None:
            self.custom_fields_data = PersistentMapping()

        self.custom_fields_data[key] = value