[gen] List field: bugfix with empty-like values (integer 0 for example). Ref field: bugfix: add a tied object with noForm=True. Calendar: added param 'delete' allowing to define who can delete what event type in the calendar. Added method 'clone' on class appy.Object.
This commit is contained in:
parent
5ba648fbf0
commit
1f34156437
|
@ -40,9 +40,13 @@ class Object:
|
|||
def get(self, name, default=None): return getattr(self, name, default)
|
||||
def __getitem__(self, k): return getattr(self, k)
|
||||
def update(self, other):
|
||||
'''Includes information from p_other into p_self.'''
|
||||
'''Includes information from p_other into p_self'''
|
||||
for k, v in other.__dict__.iteritems():
|
||||
setattr(self, k, v)
|
||||
def clone(self):
|
||||
res = Object()
|
||||
res.update(self)
|
||||
return res
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
class Hack:
|
||||
|
|
|
@ -89,7 +89,7 @@ class Calendar(Field):
|
|||
var2="events=field.getEventsAt(zobj, date);
|
||||
spansDays=field.hasEventsAt(zobj, date+1, events);
|
||||
mayCreate=mayEdit and not events;
|
||||
mayDelete=mayEdit and events;
|
||||
mayDelete=mayEdit and events and field.mayDelete(obj,events);
|
||||
day=date.day();
|
||||
dayString=date.strftime('%Y/%m/%d');
|
||||
js=mayEdit and 'toggleVisibility(this, %s)' % q('img') \
|
||||
|
@ -216,7 +216,7 @@ class Calendar(Field):
|
|||
mapping=None, label=None, maxEventLength=50,
|
||||
otherCalendars=None, additionalInfo=None, startDate=None,
|
||||
endDate=None, defaultDate=None, preCompute=None,
|
||||
applicableEvents=None, view=None, xml=None):
|
||||
applicableEvents=None, view=None, xml=None, delete=True):
|
||||
Field.__init__(self, validator, (0,1), default, show, page, group,
|
||||
layouts, move, False, True, False, specificReadPermission,
|
||||
specificWritePermission, width, height, None, colspan,
|
||||
|
@ -294,6 +294,9 @@ class Calendar(Field):
|
|||
# for explaining him why he can, for this day, only create events of a
|
||||
# sub-set of the possible event types (or even no event at all).
|
||||
self.applicableEvents = applicableEvents
|
||||
# May the user delete events in this calendar? If "delete" is a method,
|
||||
# it must accept an event type as single arg.
|
||||
self.delete = delete
|
||||
|
||||
def getPreComputedInfo(self, obj, monthDayOne, grid):
|
||||
'''Returns the result of calling self.preComputed, or None if no such
|
||||
|
@ -573,9 +576,9 @@ class Calendar(Field):
|
|||
eventSpan = rq.get('eventSpan', None)
|
||||
# Split the p_date into separate parts
|
||||
year, month, day = date.year(), date.month(), date.day()
|
||||
# Check that the "preferences" dict exists or not.
|
||||
# Check that the "preferences" dict exists or not
|
||||
if not hasattr(obj.aq_base, self.name):
|
||||
# 1st level: create a IOBTree whose keys are years.
|
||||
# 1st level: create a IOBTree whose keys are years
|
||||
setattr(obj, self.name, IOBTree())
|
||||
yearsDict = getattr(obj, self.name)
|
||||
# Get the sub-dict storing months for a given year
|
||||
|
@ -593,7 +596,7 @@ class Calendar(Field):
|
|||
events = daysDict[day]
|
||||
else:
|
||||
daysDict[day] = events = PersistentList()
|
||||
# Create and store the event, excepted if an event already exists.
|
||||
# Create and store the event, excepted if an event already exists
|
||||
if not events:
|
||||
event = Object(eventType=eventType)
|
||||
events.append(event)
|
||||
|
@ -604,6 +607,12 @@ class Calendar(Field):
|
|||
date = date + 1
|
||||
self.createEvent(obj, date, handleEventSpan=False)
|
||||
|
||||
def mayDelete(self, obj, events):
|
||||
'''May the user delete p_events?'''
|
||||
if not self.delete: return
|
||||
if callable(self.delete): return self.delete(obj, events[0].eventType)
|
||||
return True
|
||||
|
||||
def deleteEvent(self, obj, date, handleEventSpan=True):
|
||||
'''Deletes an event. It actually deletes all events at p_date.
|
||||
If p_handleEventSpan is True, we will use rq["deleteNext"] to
|
||||
|
|
|
@ -179,7 +179,7 @@ class Group:
|
|||
return uiGroup
|
||||
|
||||
class Column:
|
||||
'''Used for describing a column within a Group like defined above.'''
|
||||
'''Used for describing a column within a Group like defined above'''
|
||||
def __init__(self, width, align="left"):
|
||||
self.width = width
|
||||
self.align = align
|
||||
|
|
|
@ -22,9 +22,11 @@ from appy.gen.layout import Table
|
|||
|
||||
# ------------------------------------------------------------------------------
|
||||
class List(Field):
|
||||
'''A list.'''
|
||||
'''A list, stored as a list of Object instances ~[Object]~. Every object in
|
||||
the list has attributes named according to the sub-fields defined in this
|
||||
List.'''
|
||||
|
||||
# PX for rendering a single row.
|
||||
# PX for rendering a single row
|
||||
pxRow = Px('''
|
||||
<tr valign="top" style=":(rowIndex==-1) and 'display: none' or ''">
|
||||
<td for="info in subFields" if="info[1]" align="center"
|
||||
|
@ -38,7 +40,7 @@ class List(Field):
|
|||
</td>
|
||||
</tr>''')
|
||||
|
||||
# PX for rendering the list (shared between pxView and pxEdit).
|
||||
# PX for rendering the list (shared between pxView and pxEdit)
|
||||
pxTable = Px('''
|
||||
<table var="isEdit=layoutType == 'edit'" if="isEdit or value"
|
||||
id=":'list_%s' % name" class=":isEdit and 'grid' or 'list'"
|
||||
|
@ -177,9 +179,12 @@ class List(Field):
|
|||
if i == -1: return ''
|
||||
if not outerValue: return ''
|
||||
if i >= len(outerValue): return ''
|
||||
# Return the value, or a potential default value.
|
||||
return getattr(outerValue[i], name, '') or \
|
||||
self.getField(name).getValue(obj) or ''
|
||||
# Return the value, or a potential default value
|
||||
value = getattr(outerValue[i], name, None)
|
||||
if value != None: return value
|
||||
value = self.getField(name).getValue(obj)
|
||||
if value != None: return value
|
||||
return ''
|
||||
|
||||
def getCss(self, layoutType, res):
|
||||
'''Gets the CSS required by sub-fields if any.'''
|
||||
|
|
|
@ -248,6 +248,10 @@ class Ref(Field):
|
|||
q('%s/search?className=%s&ref=%s:%s' % \
|
||||
(ztool.absolute_url(), tiedClassName, zobj.id, field.name))"/>
|
||||
</div>
|
||||
<script>:field.getAjaxData(ajaxHookId, zobj, popup=inPopup, \
|
||||
checkboxes=checkboxes, startNumber=startNumber, sourceId=zobj.id, \
|
||||
totalNumber=totalNumber, refFieldName=field.name, \
|
||||
inPickList=inPickList, numbered=numbered)</script>
|
||||
|
||||
<!-- (Top) navigation -->
|
||||
<x>:tool.pxNavigate</x>
|
||||
|
@ -261,11 +265,6 @@ class Ref(Field):
|
|||
var2="columns=ztool.getColumnsSpecifiers(tiedClassName, \
|
||||
field.getAttribute(obj, 'shownInfo'), dir);
|
||||
currentNumber=0">
|
||||
<script>:field.getAjaxData(ajaxHookId, zobj, popup=inPopup, \
|
||||
checkboxes=checkboxes, startNumber=startNumber, \
|
||||
totalNumber=totalNumber, sourceId=zobj.id, \
|
||||
refFieldName=field.name, inPickList=inPickList, \
|
||||
numbered=numbered)</script>
|
||||
|
||||
<tr if="field.showHeaders">
|
||||
<th if="not inPickList and numbered" width=":numbered"></th>
|
||||
|
|
Loading…
Reference in a new issue