[gen] Calendar field: added the possibility to define a start and or end date for defining a specific date range; also added param 'defaultDate' (by default=now): when the calendar is shown for the 1st time, it shows the month where this date is included.
This commit is contained in:
parent
856cda9031
commit
614ce576af
|
@ -17,7 +17,8 @@ class Calendar(Type):
|
||||||
specificWritePermission=False, width=None, height=300,
|
specificWritePermission=False, width=None, height=300,
|
||||||
colspan=1, master=None, masterValue=None, focus=False,
|
colspan=1, master=None, masterValue=None, focus=False,
|
||||||
mapping=None, label=None, maxEventLength=50,
|
mapping=None, label=None, maxEventLength=50,
|
||||||
otherCalendars=None):
|
otherCalendars=None, startDate=None, endDate=None,
|
||||||
|
defaultDate=None):
|
||||||
Type.__init__(self, validator, (0,1), None, default, False, False,
|
Type.__init__(self, validator, (0,1), None, default, False, False,
|
||||||
show, page, group, layouts, move, False, False,
|
show, page, group, layouts, move, False, False,
|
||||||
specificReadPermission, specificWritePermission,
|
specificReadPermission, specificWritePermission,
|
||||||
|
@ -51,6 +52,19 @@ class Calendar(Type):
|
||||||
# leading "#" when relevant) into which events of the calendar must
|
# leading "#" when relevant) into which events of the calendar must
|
||||||
# appear.
|
# appear.
|
||||||
self.otherCalendars = otherCalendars
|
self.otherCalendars = otherCalendars
|
||||||
|
# One may limit event encoding and viewing to a limited period of time,
|
||||||
|
# via p_startDate and p_endDate. Those parameters, if given, must hold
|
||||||
|
# methods accepting no arg and returning a Zope DateTime instance.
|
||||||
|
self.startDate = startDate
|
||||||
|
# Beware: specify an end date with an hour like
|
||||||
|
# DateTime('2012/10/13 23:59:59') to avoid surprises.
|
||||||
|
self.endDate = endDate
|
||||||
|
# If a default date is specified, it must be a method accepting no arg
|
||||||
|
# and returning a DateTime instance. As soon as the calendar is shown,
|
||||||
|
# the month where this date is included will be shown. If not default
|
||||||
|
# date is specified, it will be 'now' at the moment the calendar is
|
||||||
|
# shown.
|
||||||
|
self.defaultDate = defaultDate
|
||||||
|
|
||||||
def getSiblingMonth(self, month, prevNext):
|
def getSiblingMonth(self, month, prevNext):
|
||||||
'''Gets the next or previous month (depending of p_prevNext) relative
|
'''Gets the next or previous month (depending of p_prevNext) relative
|
||||||
|
@ -171,6 +185,22 @@ class Calendar(Type):
|
||||||
else:
|
else:
|
||||||
return obj.translate('%s_event_%s' % (self.labelId, eventType))
|
return obj.translate('%s_event_%s' % (self.labelId, eventType))
|
||||||
|
|
||||||
|
def getStartDate(self, obj):
|
||||||
|
'''Get the start date for this calendar if defined.'''
|
||||||
|
if self.startDate: return self.startDate(obj.appy())
|
||||||
|
|
||||||
|
def getEndDate(self, obj):
|
||||||
|
'''Get the end date for this calendar if defined.'''
|
||||||
|
if self.endDate: return self.endDate(obj.appy())
|
||||||
|
|
||||||
|
def getDefaultDate(self, obj):
|
||||||
|
'''Get the default date that must appear as soon as the calendar is
|
||||||
|
shown.'''
|
||||||
|
if self.defaultDate:
|
||||||
|
return self.defaultDate(obj.appy())
|
||||||
|
else:
|
||||||
|
return DateTime() # Now
|
||||||
|
|
||||||
def createEvent(self, obj, date, handleEventSpan=True):
|
def createEvent(self, obj, date, handleEventSpan=True):
|
||||||
'''Create a new event in the calendar, at some p_date (day). If
|
'''Create a new event in the calendar, at some p_date (day). If
|
||||||
p_handleEventSpan is True, we will use rq["eventSpan"] and also
|
p_handleEventSpan is True, we will use rq["eventSpan"] and also
|
||||||
|
|
|
@ -5,13 +5,16 @@
|
||||||
month request/month;
|
month request/month;
|
||||||
monthDayOne python: DateTime('%s/01' % month);
|
monthDayOne python: DateTime('%s/01' % month);
|
||||||
today python: DateTime('00:00');
|
today python: DateTime('00:00');
|
||||||
todayMonth python: today.strftime('%Y/%m');
|
defaultDate python: contextObj.callField(fieldName, 'getDefaultDate', contextObj);
|
||||||
|
defaultDateMonth python: defaultDate.strftime('%Y/%m');
|
||||||
grid python: contextObj.callField(fieldName, 'getMonthGrid', month);
|
grid python: contextObj.callField(fieldName, 'getMonthGrid', month);
|
||||||
previousMonth python: contextObj.callField(fieldName, 'getSiblingMonth', month, 'previous');
|
previousMonth python: contextObj.callField(fieldName, 'getSiblingMonth', month, 'previous');
|
||||||
nextMonth python: contextObj.callField(fieldName, 'getSiblingMonth', month, 'next');
|
nextMonth python: contextObj.callField(fieldName, 'getSiblingMonth', month, 'next');
|
||||||
widget python: contextObj.getAppyType(fieldName, asDict=True);
|
widget python: contextObj.getAppyType(fieldName, asDict=True);
|
||||||
mayEdit python: contextObj.allows(widget['writePermission']);
|
mayEdit python: contextObj.allows(widget['writePermission']);
|
||||||
objUrl contextObj/absolute_url;
|
objUrl contextObj/absolute_url;
|
||||||
|
startDate python: contextObj.callField(fieldName, 'getStartDate', contextObj);
|
||||||
|
endDate python: contextObj.callField(fieldName, 'getEndDate', contextObj);
|
||||||
otherCalendars python: contextObj.callField(fieldName, 'getOtherCalendars', contextObj);"
|
otherCalendars python: contextObj.callField(fieldName, 'getOtherCalendars', contextObj);"
|
||||||
tal:attributes="id ajaxHookId">
|
tal:attributes="id ajaxHookId">
|
||||||
|
|
||||||
|
@ -19,15 +22,25 @@
|
||||||
tal:content="python: 'var %s_maxEventLength = %d;' % (fieldName, widget['maxEventLength'])">
|
tal:content="python: 'var %s_maxEventLength = %d;' % (fieldName, widget['maxEventLength'])">
|
||||||
</script>
|
</script>
|
||||||
<tal:comment replace="nothing">Month chooser</tal:comment>
|
<tal:comment replace="nothing">Month chooser</tal:comment>
|
||||||
<div style="margin-bottom: 5px">
|
<div style="margin-bottom: 5px"
|
||||||
<img style="cursor:pointer"
|
tal:define="fmt python: '%Y/%m/%d';
|
||||||
|
goBack python: not startDate or (startDate.strftime(fmt) < grid[0][0].strftime(fmt));
|
||||||
|
goForward python: not endDate or (endDate.strftime(fmt) > grid[-1][-1].strftime(fmt))">
|
||||||
|
<tal:comment replace="nothing">Go to the previous month</tal:comment>
|
||||||
|
<img style="cursor:pointer" tal:condition="goBack"
|
||||||
tal:attributes="src string: $appUrl/ui/arrowLeftSimple.png;
|
tal:attributes="src string: $appUrl/ui/arrowLeftSimple.png;
|
||||||
onclick python: 'askMonthView(\'%s\',\'%s\',\'%s\',\'%s\')' % (ajaxHookId,objUrl,fieldName,previousMonth)"/>
|
onclick python: 'askMonthView(\'%s\',\'%s\',\'%s\',\'%s\')' % (ajaxHookId,objUrl,fieldName,previousMonth)"/>
|
||||||
<input type="button"
|
<tal:comment replace="nothing">Go back to the default date</tal:comment>
|
||||||
tal:attributes="value python: _('today');
|
<tal:button condition="python: goBack or goForward">
|
||||||
onclick python: 'askMonthView(\'%s\',\'%s\',\'%s\',\'%s\')' % (ajaxHookId,objUrl,fieldName,todayMonth);
|
<input type="button"
|
||||||
disabled monthDayOne/isCurrentMonth"/>
|
tal:define="fmt python: '%Y/%m';
|
||||||
<img style="cursor:pointer"
|
label python: test(defaultDate.strftime(fmt) == today.strftime(fmt), 'today', 'goto_source')"
|
||||||
|
tal:attributes="value python: _(label);
|
||||||
|
onclick python: 'askMonthView(\'%s\',\'%s\',\'%s\',\'%s\')' % (ajaxHookId,objUrl,fieldName,defaultDateMonth);
|
||||||
|
disabled python: defaultDate.strftime(fmt) == monthDayOne.strftime(fmt)"/>
|
||||||
|
</tal:button>
|
||||||
|
<tal:comment replace="nothing">Go to the next month</tal:comment>
|
||||||
|
<img style="cursor:pointer" tal:condition="goForward"
|
||||||
tal:attributes="src string: $appUrl/ui/arrowRightSimple.png;
|
tal:attributes="src string: $appUrl/ui/arrowRightSimple.png;
|
||||||
onclick python: 'askMonthView(\'%s\',\'%s\',\'%s\',\'%s\')' % (ajaxHookId,objUrl,fieldName,nextMonth)"/>
|
onclick python: 'askMonthView(\'%s\',\'%s\',\'%s\',\'%s\')' % (ajaxHookId,objUrl,fieldName,nextMonth)"/>
|
||||||
<span tal:content="python: _('month_%s' % monthDayOne.aMonth())"></span>
|
<span tal:content="python: _('month_%s' % monthDayOne.aMonth())"></span>
|
||||||
|
@ -46,44 +59,55 @@
|
||||||
<tal:comment replace="nothing">The calendar in itself</tal:comment>
|
<tal:comment replace="nothing">The calendar in itself</tal:comment>
|
||||||
<tr tal:repeat="row grid" valign="top" tal:attributes="height rowHeight">
|
<tr tal:repeat="row grid" valign="top" tal:attributes="height rowHeight">
|
||||||
<tal:cell repeat="date row">
|
<tal:cell repeat="date row">
|
||||||
<td tal:define="events python: contextObj.callField(fieldName, 'getEventsAt', contextObj, date);
|
<tal:cel define="tooEarly python: startDate and (date < startDate);
|
||||||
spansDays python: contextObj.callField(fieldName, 'hasEventsAt', contextObj, date+1, events);
|
tooLate python: endDate and not tooEarly and (date > endDate);
|
||||||
mayCreate python: mayEdit and not events;
|
inRange python: not tooEarly and not tooLate">
|
||||||
mayDelete python: mayEdit and events;"
|
<tal:comment replace="nothing">Dump an empty cell if we are out of the supported date range</tal:comment>
|
||||||
tal:attributes="style python: test(date.isCurrentDay(), 'font-weight:bold', 'font-weight:normal');
|
<td tal:condition="not: inRange"
|
||||||
class python: test(date < today, 'even', 'odd');
|
tal:attributes="class python: test(date < today, 'even', 'odd');">
|
||||||
onmouseover python: test(mayEdit, 'this.getElementsByTagName(\'img\')[0].style.visibility=\'visible\'', '');
|
</td>
|
||||||
onmouseout python: test(mayEdit, 'this.getElementsByTagName(\'img\')[0].style.visibility=\'hidden\'', '')">
|
<tal:comment replace="nothing">Dump a normal cell if we are in range</tal:comment>
|
||||||
<tal:day define="day date/day;
|
<tal:td condition="inRange">
|
||||||
dayString python: date.strftime('%Y/%m/%d')">
|
<td tal:define="events python: contextObj.callField(fieldName, 'getEventsAt', contextObj, date);
|
||||||
<span tal:content="day"></span>
|
spansDays python: contextObj.callField(fieldName, 'hasEventsAt', contextObj, date+1, events);
|
||||||
<span tal:condition="python: day == 1"
|
mayCreate python: mayEdit and not events;
|
||||||
tal:content="python: _('month_%s_short' % date.aMonth())"></span>
|
mayDelete python: mayEdit and events;"
|
||||||
<tal:comment replace="nothing">Icon for adding an event</tal:comment>
|
tal:attributes="style python: test(date.isCurrentDay(), 'font-weight:bold', 'font-weight:normal');
|
||||||
<img tal:condition="mayCreate" style="visibility:hidden; cursor:pointer"
|
class python: test(date < today, 'even', 'odd');
|
||||||
tal:attributes="src string: $appUrl/ui/plus.png;
|
onmouseover python: test(mayEdit, 'this.getElementsByTagName(\'img\')[0].style.visibility=\'visible\'', '');
|
||||||
|
onmouseout python: test(mayEdit, 'this.getElementsByTagName(\'img\')[0].style.visibility=\'hidden\'', '')">
|
||||||
|
<tal:day define="day date/day;
|
||||||
|
dayString python: date.strftime('%Y/%m/%d')">
|
||||||
|
<span tal:content="day"></span>
|
||||||
|
<span tal:condition="python: day == 1"
|
||||||
|
tal:content="python: _('month_%s_short' % date.aMonth())"></span>
|
||||||
|
<tal:comment replace="nothing">Icon for adding an event</tal:comment>
|
||||||
|
<img tal:condition="mayCreate" style="visibility:hidden; cursor:pointer"
|
||||||
|
tal:attributes="src string: $appUrl/ui/plus.png;
|
||||||
onclick python: 'openEventPopup(\'new\',\'%s\',\'%s\')' % (fieldName, dayString)"/>
|
onclick python: 'openEventPopup(\'new\',\'%s\',\'%s\')' % (fieldName, dayString)"/>
|
||||||
<tal:comment replace="nothing">Icon for deleting an event</tal:comment>
|
<tal:comment replace="nothing">Icon for deleting an event</tal:comment>
|
||||||
<img tal:condition="mayDelete" style="visibility:hidden; cursor:pointer"
|
<img tal:condition="mayDelete" style="visibility:hidden; cursor:pointer"
|
||||||
tal:attributes="src string: $appUrl/ui/delete.png;
|
tal:attributes="src string: $appUrl/ui/delete.png;
|
||||||
onclick python: 'openEventPopup(\'del\',\'%s\',\'%s\',\'%s\')' % (fieldName, dayString, str(spansDays))"/>
|
onclick python: 'openEventPopup(\'del\',\'%s\',\'%s\',\'%s\')' % (fieldName, dayString, str(spansDays))"/>
|
||||||
<tal:events condition="events">
|
<tal:events condition="events">
|
||||||
<tal:comment replace="nothing">A single event is allowed for the moment</tal:comment>
|
<tal:comment replace="nothing">A single event is allowed for the moment</tal:comment>
|
||||||
<div tal:define="eventType python: events[0]['eventType']">
|
<div tal:define="eventType python: events[0]['eventType']">
|
||||||
<span style="color: grey"
|
<span style="color: grey"
|
||||||
tal:content="python: contextObj.callField(fieldName, 'getEventName', contextObj, eventType)"></span>
|
tal:content="python: contextObj.callField(fieldName, 'getEventName', contextObj, eventType)"></span>
|
||||||
</div>
|
</div>
|
||||||
</tal:events>
|
</tal:events>
|
||||||
<tal:comment replace="nothing">Events from other calendars</tal:comment>
|
<tal:comment replace="nothing">Events from other calendars</tal:comment>
|
||||||
<tal:others condition="otherCalendars">
|
<tal:others condition="otherCalendars">
|
||||||
<tal:e define="otherEvents python: contextObj.callField(fieldName,'getOtherEventsAt',contextObj,date,otherCalendars)"
|
<tal:e define="otherEvents python: contextObj.callField(fieldName,'getOtherEventsAt',contextObj,date,otherCalendars)"
|
||||||
condition="otherEvents">
|
condition="otherEvents">
|
||||||
<div tal:repeat="event otherEvents" tal:content="event/name"
|
<div tal:repeat="event otherEvents" tal:content="event/name"
|
||||||
tal:attributes="style python: 'color: %s;; font-style: italic' % event['color']"></div>
|
tal:attributes="style python: 'color: %s;; font-style: italic' % event['color']"></div>
|
||||||
</tal:e>
|
</tal:e>
|
||||||
</tal:others>
|
</tal:others>
|
||||||
</tal:day>
|
</tal:day>
|
||||||
</td>
|
</td>
|
||||||
|
</tal:td>
|
||||||
|
</tal:cel>
|
||||||
</tal:cell>
|
</tal:cell>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
@ -157,9 +181,9 @@
|
||||||
|
|
||||||
<tal:comment replace="nothing">View macro</tal:comment>
|
<tal:comment replace="nothing">View macro</tal:comment>
|
||||||
<metal:view define-macro="view"
|
<metal:view define-macro="view"
|
||||||
tal:define="now python: DateTime();
|
tal:define="defaultDate python: contextObj.callField(widget['name'], 'getDefaultDate', contextObj);
|
||||||
dummy python: request.set('fieldName', widget['name']);
|
dummy python: request.set('fieldName', widget['name']);
|
||||||
dummy python: request.set('month', now.strftime('%Y/%m'))">
|
dummy python: request.set('month', defaultDate.strftime('%Y/%m'))">
|
||||||
<metal:call use-macro="app/ui/widgets/calendar/macros/viewMonth"/>
|
<metal:call use-macro="app/ui/widgets/calendar/macros/viewMonth"/>
|
||||||
</metal:view>
|
</metal:view>
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue