Exemple #1
0
    def render(self, ctx, key, args, errors):
        converter = iformal.IDateTupleConvertible(self.original)
        namer = self._namer(key)
        if errors:
            year = args.get(namer('year'), [''])[0]
            month = args.get(namer('month'), [''])[0]
            day = args.get(namer('day'), [''])[0]
        else:
            year, month, day = converter.fromType(args.get(key))

        return self._renderTag(ctx, year, month, day, namer, False)
Exemple #2
0
    def render(self, ctx, key, args, errors):
        converter = iformal.IDateTupleConvertible(self.original)
        namer = self._namer(key)
        if errors:
            year = args.get(namer('year'), [''])[0]
            month = args.get(namer('month'), [''])[0]
            # return a blank for the day
            day = ''
        else:
            year, month, day = converter.fromType(args.get(key))
            # if we have a year as default data, stringify it and only use last two digits
            if year is not None:
                year = str(year)[2:]

        return self._renderTag(ctx, year, month, namer, False)
Exemple #3
0
class MMYYDatePartsInput(object):
    """
    Two input fields for entering the month and year.
    """
    implements(iformal.IWidget)

    cutoffYear = 70

    def __init__(self, original, cutoffYear=None):
        self.original = original
        if cutoffYear is not None:
            self.cutoffYear = cutoffYear

    def _namer(self, prefix):
        def _(part):
            return '%s__%s' % (prefix, part)

        return _

    def _renderTag(self, ctx, year, month, namer, readonly):
        yearTag = T.input(type="text", name=namer('year'), value=year, size=2)
        monthTag = T.input(type="text",
                           name=namer('month'),
                           value=month,
                           size=2)
        if readonly:
            tags = (yearTag, monthTag)
            for tag in tags:
                tag(class_='readonly', readonly='readonly')
        return monthTag, ' / ', yearTag, ' (mm/yy)'

    def render(self, ctx, key, args, errors):
        converter = iformal.IDateTupleConvertible(self.original)
        namer = self._namer(key)
        if errors:
            year = args.get(namer('year'), [''])[0]
            month = args.get(namer('month'), [''])[0]
            # return a blank for the day
            day = ''
        else:
            year, month, day = converter.fromType(args.get(key))
            # if we have a year as default data, stringify it and only use last two digits
            if year is not None:
                year = str(year)[2:]

        return self._renderTag(ctx, year, month, namer, False)

    def renderImmutable(self, ctx, key, args, errors):
        converter = iformal.IDateTupleConvertible(self.original)
        year, month, day = converter.fromType(args.get(key))
        namer = self._namer(key)
        # if we have a year as default data, stringify it and only use last two digits
        if year is not None:
            year = str(year)[2:]
        return self._renderTag(ctx, year, month, namer, True)

    def processInput(self, ctx, key, args):
        namer = self._namer(key)
        value = [
            args.get(namer(part), [''])[0].strip()
            for part in ('year', 'month')
        ]
        value = [p for p in value if p]
        if not value:
            value = None
        elif len(value) != 2:
            raise validation.FieldValidationError("Invalid date")
        if value is not None:
            try:
                value = [int(p) for p in value]
            except ValueError, e:
                raise validation.FieldValidationError("Invalid date")
            if value[1] < 0 or value[1] > 99:
                raise validation.FieldValidationError(
                    "Invalid year. Please enter a two-digit year.")
            if value[0] > self.cutoffYear:
                value[0] = 1900 + value[0]
            else:
                value[0] = 2000 + value[0]
            value.append(1)
        value = iformal.IDateTupleConvertible(self.original).toType(value)
        return self.original.validate(value)
Exemple #4
0
 def renderImmutable(self, ctx, key, args, errors):
     converter = iformal.IDateTupleConvertible(self.original)
     namer = self._namer(key)
     year, month, day = converter.fromType(args.get(key))
     return self._renderTag(ctx, year, month, day, namer, True)
Exemple #5
0
class DatePartsInput(object):
    """
    A date entry widget that uses three <input> elements for the day, month and
    year parts.

    The default entry format is the US (month, day, year) but can be switched to
    the more common (day, month, year) by setting the dayFirst attribute to
    True.
    
    By default the widget is designed to only accept unambiguous years, i.e.
    the user must enter 4 character dates.
    
    Many people find it convenient or even necessary to allow a 2 character
    year. This can be allowed by setting the twoCharCutoffYear attribute to an
    integer value between 0 and 99. Anything greater than or equal to the cutoff
    year will be considered part of the 20th century (1900 + year); anything
    less the cutoff year is a 21st century (2000 + year) date.
    
    A typical twoCharCutoffYear value is 70 (i.e. 1970). However, that value is
    somewhat arbitrary. It's the year that time began according to the PC, but
    it doesn't mean much to your non-techie user.

    dayFirst:
        Make the day the first input field, i.e. day, month, year
    twoCharCutoffYear:
        Allow 2 char years and set the year where the century flips between
        20th and 21st century.
    """
    implements(iformal.IWidget)

    dayFirst = False
    twoCharCutoffYear = None

    def __init__(self, original, dayFirst=None, twoCharCutoffYear=None):
        self.original = original
        if dayFirst is not None:
            self.dayFirst = dayFirst
        if twoCharCutoffYear is not None:
            self.twoCharCutoffYear = twoCharCutoffYear

    def _namer(self, prefix):
        def _(part):
            return '%s__%s' % (prefix, part)

        return _

    def _renderTag(self, ctx, year, month, day, namer, readonly):
        yearTag = T.input(type="text", name=namer('year'), value=year, size=4)
        monthTag = T.input(type="text",
                           name=namer('month'),
                           value=month,
                           size=2)
        dayTag = T.input(type="text", name=namer('day'), value=day, size=2)
        if readonly:
            tags = (yearTag, monthTag, dayTag)
            for tag in tags:
                tag(class_='readonly', readonly='readonly')

        if self.dayFirst:
            return dayTag, ' / ', monthTag, ' / ', yearTag, ' ', _(
                '(day/month/year)')
        else:
            return monthTag, ' / ', dayTag, ' / ', yearTag, ' ', _(
                '(month/day/year)')

    def render(self, ctx, key, args, errors):
        converter = iformal.IDateTupleConvertible(self.original)
        namer = self._namer(key)
        if errors:
            year = args.get(namer('year'), [''])[0]
            month = args.get(namer('month'), [''])[0]
            day = args.get(namer('day'), [''])[0]
        else:
            year, month, day = converter.fromType(args.get(key))

        return self._renderTag(ctx, year, month, day, namer, False)

    def renderImmutable(self, ctx, key, args, errors):
        converter = iformal.IDateTupleConvertible(self.original)
        namer = self._namer(key)
        year, month, day = converter.fromType(args.get(key))
        return self._renderTag(ctx, year, month, day, namer, True)

    def processInput(self, ctx, key, args):
        namer = self._namer(key)
        # Get the form field values as a (y,m,d) tuple
        ymd = [
            args.get(namer(part), [''])[0].strip()
            for part in ('year', 'month', 'day')
        ]
        # Remove parts that were not entered.
        ymd = [p for p in ymd if p]
        # Nothing entered means None otherwise we need all three.
        if not ymd:
            ymd = None
        elif len(ymd) != 3:
            raise validation.FieldValidationError("Invalid date")
        # So, we have what looks like a good attempt to enter a date.
        if ymd is not None:
            # If a 2-char year is allowed then prepend the century.
            if self.twoCharCutoffYear is not None and len(ymd[0]) == 2:
                try:
                    if int(ymd[0]) >= self.twoCharCutoffYear:
                        century = '19'
                    else:
                        century = '20'
                    ymd[0] = century + ymd[0]
                except ValueError:
                    pass
            # By now, we should have a year of at least 4 characters.
            if len(ymd[0]) < 4:
                if self.twoCharCutoffYear is not None:
                    msg = "Please enter a 2 or 4 digit year"
                else:
                    msg = "Please enter a 4 digit year"
                raise validation.FieldValidationError(msg)
            # Map to integers
            try:
                ymd = [int(p) for p in ymd]
            except ValueError, e:
                raise validation.FieldValidationError("Invalid date")
        ymd = iformal.IDateTupleConvertible(self.original).toType(ymd)
        return self.original.validate(ymd)
Exemple #6
0
class DatePartsSelect(object):
    """
    A date entry widget that uses three <input> elements for the day, month and
    year parts.

    The default entry format is the US (month, day, year) but can be switched to
    the more common (day, month, year) by setting the dayFirst attribute to
    True.
    
    The start and end year can be passed through but default to 1970 and 2070.
    
    The months default to non-zero prefixed numerics but can be passed as a list
    of label, value pairs
    """    
    implements( iformal.IWidget )

    dayFirst = False
    days = [ (d,d) for d in xrange(1,32) ]
    months = [ (m,m) for m in xrange(1,13) ]
    yearFrom = 1970
    yearTo = 2070
    noneOption = ('', '')

    def __init__(self, original, dayFirst=None, yearFrom=None, yearTo=None, months=None, noneOption=_UNSET):
        self.original = original
        if dayFirst is not None:
            self.dayFirst = dayFirst
        if yearFrom is not None:
            self.yearFrom = yearFrom
        if yearTo is not None:
            self.yearTo = yearTo
        if months is not None:
            self.months = months
        if noneOption is not _UNSET:
            self.noneOption = noneOption

    def _namer(self, prefix):
        def _(part):
            return '%s__%s' % (prefix,part)
        return _

    def _renderTag(self, ctx, year, month, day, namer, readonly):
        years = [(v,v) for v in xrange(self.yearFrom,self.yearTo)]
        months = self.months
        days = self.days

        options = []
        if self.noneOption is not None:
            options.append( T.option(value=self.noneOption[0])[self.noneOption[1]] )
        for value in years:
            if str(value[0]) == str(year):
                options.append( T.option(value=value[0],selected='selected')[value[1]] )
            else:
                options.append( T.option(value=value[0])[value[1]] )
        yearTag = T.select(name=namer('year'))[ options ]
        
        options = []
        if self.noneOption is not None:
            options.append( T.option(value=self.noneOption[0])[self.noneOption[1]] )
        for value in months:
            if str(value[0]) == str(month):
                options.append( T.option(value=value[0],selected='selected')[value[1]] )
            else:
                options.append( T.option(value=value[0])[value[1]] )
        monthTag = T.select(name=namer('month'))[ options ]
        
        options = []
        if self.noneOption is not None:
            options.append( T.option(value=self.noneOption[0])[self.noneOption[1]] )
        for value in days:
            if str(value[0]) == str(day):
                options.append( T.option(value=value[0],selected='selected')[value[1]] )
            else:
                options.append( T.option(value=value[0])[value[1]] )
        dayTag = T.select(name=namer('day'))[ options ]
        
        if readonly:
            tags = (yearTag, monthTag, dayTag)
            for tag in tags:
                tag(class_='readonly', readonly='readonly')

        if self.dayFirst:
            return dayTag, ' / ', monthTag, ' / ', yearTag, ' ', _('(day/month/year)')
        else:
            return monthTag, ' / ', dayTag, ' / ', yearTag, ' ', _('(month/day/year)')

    def render(self, ctx, key, args, errors):
        converter = iformal.IDateTupleConvertible(self.original)
        namer = self._namer(key)
        if errors:
            year = args.get(namer('year'), [''])[0]
            month = args.get(namer('month'), [''])[0]
            day = args.get(namer('day'), [''])[0]
        else:
            year, month, day = converter.fromType(args.get(key))

        return self._renderTag(ctx, year, month, day, namer, False)

    def renderImmutable(self, ctx, key, args, errors):
        converter = iformal.IDateTupleConvertible(self.original)
        namer = self._namer(key)
        year, month, day = converter.fromType(args.get(key))
        return self._renderTag(ctx, year, month, day, namer, True)

    def processInput(self, ctx, key, args):
        namer = self._namer(key)
        # Get the form field values as a (y,m,d) tuple
        ymd = [args.get(namer(part), [''])[0].strip() for part in ('year', 'month', 'day')]
        # Remove parts that were not entered.
        ymd = [p for p in ymd if p]
        # Nothing entered means None otherwise we need all three.
        if not ymd:
            ymd = None
        elif len(ymd) != 3:
            raise validation.FieldValidationError("Invalid date")
        # So, we have what looks like a good attempt to enter a date.
        if ymd is not None:
            # Map to integers
            try:
                ymd = [int(p) for p in ymd]
            except ValueError, e:
                raise validation.FieldValidationError("Invalid date")
        ymd = iformal.IDateTupleConvertible(self.original).toType(ymd)
        return self.original.validate(ymd)