[gen] Calendar field: began work on the 'timeline' calendar view.
This commit is contained in:
parent
1f34156437
commit
302556192b
|
@ -14,59 +14,11 @@ class Calendar(Field):
|
||||||
jsFiles = {'view': ('calendar.js',)}
|
jsFiles = {'view': ('calendar.js',)}
|
||||||
DateTime = DateTime
|
DateTime = DateTime
|
||||||
|
|
||||||
# Month view for a calendar. Called by pxView, and directly from the UI,
|
# Timeline view for a calendar
|
||||||
# via Ajax, when the user selects another month.
|
pxViewTimeline = Px('''<p>Hello timeline</p>''')
|
||||||
|
|
||||||
|
# Month view for a calendar
|
||||||
pxViewMonth = Px('''
|
pxViewMonth = Px('''
|
||||||
<div var="ajaxHookId=zobj.id + field.name;
|
|
||||||
month=req['month'];
|
|
||||||
monthDayOne=field.DateTime('%s/01' % month);
|
|
||||||
today=field.DateTime('00:00');
|
|
||||||
grid=field.getMonthGrid(month);
|
|
||||||
allEventTypes=field.getEventTypes(zobj);
|
|
||||||
preComputed=field.getPreComputedInfo(zobj, monthDayOne, grid);
|
|
||||||
defaultDate=field.getDefaultDate(zobj);
|
|
||||||
defaultDateMonth=defaultDate.strftime('%Y/%m');
|
|
||||||
previousMonth=field.getSiblingMonth(month, 'previous');
|
|
||||||
nextMonth=field.getSiblingMonth(month, 'next');
|
|
||||||
mayEdit=zobj.mayEdit(field.writePermission);
|
|
||||||
objUrl=zobj.absolute_url();
|
|
||||||
startDate=field.getStartDate(zobj);
|
|
||||||
endDate=field.getEndDate(zobj);
|
|
||||||
otherCalendars=field.getOtherCalendars(zobj, preComputed)"
|
|
||||||
id=":ajaxHookId">
|
|
||||||
|
|
||||||
<script>:'var %s_maxEventLength = %d;' % \
|
|
||||||
(field.name, field.maxEventLength)</script>
|
|
||||||
|
|
||||||
<!-- Month chooser -->
|
|
||||||
<div style="margin-bottom: 5px"
|
|
||||||
var="fmt='%Y/%m/%d';
|
|
||||||
goBack=not startDate or (startDate.strftime(fmt) < \
|
|
||||||
grid[0][0].strftime(fmt));
|
|
||||||
goForward=not endDate or (endDate.strftime(fmt) > \
|
|
||||||
grid[-1][-1].strftime(fmt))">
|
|
||||||
<!-- Go to the previous month -->
|
|
||||||
<img class="clickable" if="goBack" src=":url('arrowLeft')"
|
|
||||||
onclick=":'askMonthView(%s,%s,%s,%s)' % \
|
|
||||||
(q(ajaxHookId),q(objUrl),q(field.name),q(previousMonth))"/>
|
|
||||||
<!-- Go back to the default date -->
|
|
||||||
<input type="button" if="goBack or goForward"
|
|
||||||
var="fmt='%Y/%m';
|
|
||||||
label=(defaultDate.strftime(fmt)==today.strftime(fmt)) and \
|
|
||||||
'today' or 'goto_source'"
|
|
||||||
value=":_(label)"
|
|
||||||
onclick=":'askMonthView(%s, %s, %s, %s)' % (q(ajaxHookId), \
|
|
||||||
q(objUrl), q(field.name), q(defaultDateMonth))"
|
|
||||||
disabled=":defaultDate.strftime(fmt)==monthDayOne.strftime(fmt)"/>
|
|
||||||
<!-- Go to the next month -->
|
|
||||||
<img class="clickable" if="goForward" src=":url('arrowRight')"
|
|
||||||
onclick=":'askMonthView(%s, %s, %s, %s)' % (q(ajaxHookId), \
|
|
||||||
q(objUrl), q(field.name), q(nextMonth))"/>
|
|
||||||
<span>:_('month_%s' % monthDayOne.aMonth())</span>
|
|
||||||
<span>:month.split('/')[0]</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Calendar month view -->
|
|
||||||
<table cellpadding="0" cellspacing="0" width="100%" class="list"
|
<table cellpadding="0" cellspacing="0" width="100%" class="list"
|
||||||
style="font-size: 95%"
|
style="font-size: 95%"
|
||||||
var="rowHeight=int(field.height/float(len(grid)))">
|
var="rowHeight=int(field.height/float(len(grid)))">
|
||||||
|
@ -104,7 +56,7 @@ class Calendar(Field):
|
||||||
<img class="clickable" style="visibility:hidden"
|
<img class="clickable" style="visibility:hidden"
|
||||||
var="info=field.getApplicableEventsTypesAt(zobj, date, \
|
var="info=field.getApplicableEventsTypesAt(zobj, date, \
|
||||||
allEventTypes, preComputed, True)"
|
allEventTypes, preComputed, True)"
|
||||||
if="info.eventTypes" src=":url('plus')"
|
if="info and info.eventTypes" src=":url('plus')"
|
||||||
onclick=":'openEventPopup(%s, %s, %s, null, %s, %s)' % \
|
onclick=":'openEventPopup(%s, %s, %s, null, %s, %s)' % \
|
||||||
(q('new'), q(field.name), q(dayString), q(info.eventTypes),\
|
(q('new'), q(field.name), q(dayString), q(info.eventTypes),\
|
||||||
q(info.message))"/>
|
q(info.message))"/>
|
||||||
|
@ -134,7 +86,8 @@ class Calendar(Field):
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<!-- Popup for creating a calendar event -->
|
<!-- Popup for creating a calendar event -->
|
||||||
<div var="prefix='%s_newEvent' % field.name;
|
<div if="allEventTypes"
|
||||||
|
var="prefix='%s_newEvent' % field.name;
|
||||||
popupId=prefix + 'Popup'"
|
popupId=prefix + 'Popup'"
|
||||||
id=":popupId" class="popup" align="center">
|
id=":popupId" class="popup" align="center">
|
||||||
<form id=":prefix + 'Form'" method="post">
|
<form id=":prefix + 'Form'" method="post">
|
||||||
|
@ -198,13 +151,59 @@ class Calendar(Field):
|
||||||
<input type="button" value=":_('no')"
|
<input type="button" value=":_('no')"
|
||||||
onclick=":'closePopup(%s)' % q(popupId)"/>
|
onclick=":'closePopup(%s)' % q(popupId)"/>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
|
||||||
</div>''')
|
</div>''')
|
||||||
|
|
||||||
pxView = pxCell = Px('''
|
pxView = pxCell = Px('''
|
||||||
<x var="defaultDate=field.getDefaultDate(zobj);
|
<div var="defaultDate=field.getDefaultDate(zobj);
|
||||||
x=req.set('month', defaultDate.strftime('%Y/%m'));
|
defaultDateMonth=defaultDate.strftime('%Y/%m');
|
||||||
x=req.set('fieldName', field.name)">:field.pxViewMonth</x>''')
|
ajaxHookId=zobj.id + field.name;
|
||||||
|
month=req.get('month', defaultDate.strftime('%Y/%m'));
|
||||||
|
monthDayOne=field.DateTime('%s/01' % month);
|
||||||
|
render=req.get('render', field.render);
|
||||||
|
today=field.DateTime('00:00');
|
||||||
|
grid=field.getGrid(month, render);
|
||||||
|
allEventTypes=field.getEventTypes(zobj);
|
||||||
|
preComputed=field.getPreComputedInfo(zobj, monthDayOne, grid);
|
||||||
|
previousMonth=field.getSiblingMonth(month, 'previous');
|
||||||
|
nextMonth=field.getSiblingMonth(month, 'next');
|
||||||
|
mayEdit=zobj.mayEdit(field.writePermission);
|
||||||
|
objUrl=zobj.absolute_url();
|
||||||
|
startDate=field.getStartDate(zobj);
|
||||||
|
endDate=field.getEndDate(zobj);
|
||||||
|
otherCalendars=field.getOtherCalendars(zobj, preComputed)"
|
||||||
|
id=":ajaxHookId">
|
||||||
|
<script>:'var %s_maxEventLength = %d;' % \
|
||||||
|
(field.name, field.maxEventLength)</script>
|
||||||
|
|
||||||
|
<!-- Month chooser -->
|
||||||
|
<div style="margin-bottom: 5px"
|
||||||
|
var="fmt='%Y/%m/%d';
|
||||||
|
goBack=not startDate or (startDate.strftime(fmt) < \
|
||||||
|
grid[0][0].strftime(fmt));
|
||||||
|
goForward=not endDate or (endDate.strftime(fmt) > \
|
||||||
|
grid[-1][-1].strftime(fmt))">
|
||||||
|
<!-- Go to the previous month -->
|
||||||
|
<img class="clickable" if="goBack" src=":url('arrowLeft')"
|
||||||
|
onclick=":'askCalendar(%s,%s,%s,%s,%s)' % (q(ajaxHookId), \
|
||||||
|
q(objUrl), q(render), q(field.name), q(previousMonth))"/>
|
||||||
|
<!-- Go back to the default date -->
|
||||||
|
<input type="button" if="goBack or goForward"
|
||||||
|
var="fmt='%Y/%m';
|
||||||
|
label=(defaultDate.strftime(fmt)==today.strftime(fmt)) and \
|
||||||
|
'today' or 'goto_source'"
|
||||||
|
value=":_(label)"
|
||||||
|
onclick=":'askCalendar(%s,%s,%s,%s,%s)' % (q(ajaxHookId), \
|
||||||
|
q(objUrl), q(render), q(field.name), q(defaultDateMonth))"
|
||||||
|
disabled=":defaultDate.strftime(fmt)==monthDayOne.strftime(fmt)"/>
|
||||||
|
<!-- Go to the next month -->
|
||||||
|
<img class="clickable" if="goForward" src=":url('arrowRight')"
|
||||||
|
onclick=":'askCalendar(%s,%s,%s,%s,%s)' % (q(ajaxHookId), \
|
||||||
|
q(objUrl), q(render), q(field.name), q(nextMonth))"/>
|
||||||
|
<span>:_('month_%s' % monthDayOne.aMonth())</span>
|
||||||
|
<span>:month.split('/')[0]</span>
|
||||||
|
</div>
|
||||||
|
<x>:getattr(field, 'pxView%s' % render.capitalize())</x>
|
||||||
|
</div>''')
|
||||||
|
|
||||||
pxEdit = pxSearch = ''
|
pxEdit = pxSearch = ''
|
||||||
|
|
||||||
|
@ -213,7 +212,7 @@ class Calendar(Field):
|
||||||
layouts=None, move=0, specificReadPermission=False,
|
layouts=None, move=0, specificReadPermission=False,
|
||||||
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, render='month',
|
||||||
otherCalendars=None, additionalInfo=None, startDate=None,
|
otherCalendars=None, additionalInfo=None, startDate=None,
|
||||||
endDate=None, defaultDate=None, preCompute=None,
|
endDate=None, defaultDate=None, preCompute=None,
|
||||||
applicableEvents=None, view=None, xml=None, delete=True):
|
applicableEvents=None, view=None, xml=None, delete=True):
|
||||||
|
@ -232,12 +231,17 @@ class Calendar(Field):
|
||||||
# of this event as it must be shown to the user.
|
# of this event as it must be shown to the user.
|
||||||
self.eventTypes = eventTypes
|
self.eventTypes = eventTypes
|
||||||
self.eventNameMethod = eventNameMethod
|
self.eventNameMethod = eventNameMethod
|
||||||
if (type(eventTypes) == types.FunctionType) and not eventNameMethod:
|
if callable(eventTypes) and not eventNameMethod:
|
||||||
raise Exception("When param 'eventTypes' is a method, you must " \
|
raise Exception("When param 'eventTypes' is a method, you must " \
|
||||||
"give another method in param 'eventNameMethod'.")
|
"give another method in param 'eventNameMethod'.")
|
||||||
# It is not possible to create events that span more days than
|
# It is not possible to create events that span more days than
|
||||||
# maxEventLength.
|
# maxEventLength.
|
||||||
self.maxEventLength = maxEventLength
|
self.maxEventLength = maxEventLength
|
||||||
|
# Various render modes exist. Default is the classical "month" view.
|
||||||
|
# It can also be "timeline": in this case, on the x axis, we have one
|
||||||
|
# column per day, and on the y axis, we have one row per calendar (this
|
||||||
|
# one and others as specified in "otherCalendars", see below).
|
||||||
|
self.render = render
|
||||||
# When displaying a given month for this agenda, one may want to
|
# When displaying a given month for this agenda, one may want to
|
||||||
# pre-compute, once for the whole month, some information that will then
|
# pre-compute, once for the whole month, some information that will then
|
||||||
# be given as arg for other methods specified in subsequent parameters.
|
# be given as arg for other methods specified in subsequent parameters.
|
||||||
|
@ -325,10 +329,10 @@ class Calendar(Field):
|
||||||
res.append(obj.translate('day_%s%s' % (day, suffix)))
|
res.append(obj.translate('day_%s%s' % (day, suffix)))
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def getMonthGrid(self, month):
|
def getGrid(self, month, render):
|
||||||
'''Creates a list of lists of DateTime objects representing the calendar
|
'''Creates a list of lists of DateTime objects representing the calendar
|
||||||
grid to render for a given p_month.'''
|
grid to render for a given p_month.'''
|
||||||
# Month is a string "YYYY/mm".
|
# Month is a string "YYYY/mm"
|
||||||
currentDay = DateTime('%s/01 UTC' % month)
|
currentDay = DateTime('%s/01 UTC' % month)
|
||||||
currentMonth = currentDay.month()
|
currentMonth = currentDay.month()
|
||||||
res = [[]]
|
res = [[]]
|
||||||
|
@ -379,9 +383,7 @@ class Calendar(Field):
|
||||||
def getEventTypes(self, obj):
|
def getEventTypes(self, obj):
|
||||||
'''Returns the (dynamic or static) event types as defined in
|
'''Returns the (dynamic or static) event types as defined in
|
||||||
self.eventTypes.'''
|
self.eventTypes.'''
|
||||||
if type(self.eventTypes) == types.FunctionType:
|
if callable(self.eventTypes): return self.eventTypes(obj.appy())
|
||||||
return self.eventTypes(obj.appy())
|
|
||||||
else:
|
|
||||||
return self.eventTypes
|
return self.eventTypes
|
||||||
|
|
||||||
def getApplicableEventsTypesAt(self, obj, date, allEventTypes, preComputed,
|
def getApplicableEventsTypesAt(self, obj, date, allEventTypes, preComputed,
|
||||||
|
@ -393,6 +395,7 @@ class Calendar(Field):
|
||||||
contains a message explaining those event types are
|
contains a message explaining those event types are
|
||||||
not applicable.
|
not applicable.
|
||||||
'''
|
'''
|
||||||
|
if not allEventTypes: return # There may be no event type at all
|
||||||
if not self.applicableEvents:
|
if not self.applicableEvents:
|
||||||
eventTypes = allEventTypes
|
eventTypes = allEventTypes
|
||||||
message = None
|
message = None
|
||||||
|
|
|
@ -8,10 +8,10 @@ function toggleVisibility(node, nodeType){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function askMonthView(hookId, objectUrl, fieldName, month) {
|
function askCalendar(hookId, objectUrl, render, fieldName, month) {
|
||||||
// Sends an Ajax request for getting the view month of a calendar field
|
// Sends an Ajax request for getting the calendar, at p_month
|
||||||
var params = {'month': month};
|
var params = {'month': month, 'render': render};
|
||||||
askAjaxChunk(hookId, 'GET', objectUrl, fieldName+':pxViewMonth', params);
|
askAjaxChunk(hookId, 'GET', objectUrl, fieldName+':pxView', params);
|
||||||
}
|
}
|
||||||
|
|
||||||
function openEventPopup(action, fieldName, day, spansDays,
|
function openEventPopup(action, fieldName, day, spansDays,
|
||||||
|
@ -93,5 +93,5 @@ function triggerCalendarEvent(action, hookId, fieldName, objectUrl,
|
||||||
params[elems[i].name] = elems[i].value;
|
params[elems[i].name] = elems[i].value;
|
||||||
}
|
}
|
||||||
closePopup(prefix + 'Popup');
|
closePopup(prefix + 'Popup');
|
||||||
askAjaxChunk(hookId, 'POST', objectUrl, fieldName+':pxViewMonth', params);
|
askAjaxChunk(hookId, 'POST', objectUrl, fieldName+':pxView', params);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue