[gen] Ref field: first cmplete version of Ref with link='popup'.
This commit is contained in:
parent
0bcd0055a3
commit
a45dfa8dd0
5 changed files with 93 additions and 45 deletions
|
@ -168,6 +168,23 @@ class Ref(Field):
|
|||
navBaseCall, startNumber)"/>
|
||||
</form>''')
|
||||
|
||||
# Displays the button allowing to select from a popup objects to be linked
|
||||
# via the Ref field.
|
||||
pxLink = Px('''
|
||||
<a target="appyIFrame"
|
||||
var="tiedClassName=ztool.getPortalType(field.klass);
|
||||
className=ztool.getPortalType(obj.klass)"
|
||||
href=":'%s/query?className=%s&search=%s:%s:%s&popup=1' % \
|
||||
(ztool.absolute_url(), tiedClassName, obj.uid, field.name, \
|
||||
popupMode)">
|
||||
<input type="button" class="buttonSmall button"
|
||||
var="labelId= (popupMode=='repl') and 'search_button' or 'add_ref';
|
||||
icon= (popupMode=='repl') and 'search' or 'add';
|
||||
label=_(labelId)" value=":label"
|
||||
style=":'%s;%s' % (url(icon,bg=True), ztool.getButtonWidth(label))"
|
||||
onclick="openPopup('iframePopup')"/>
|
||||
</a>''')
|
||||
|
||||
# This PX displays, in a cell header from a ref table, icons for sorting the
|
||||
# ref field according to the field that corresponds to this column.
|
||||
pxSortIcons = Px('''
|
||||
|
@ -202,10 +219,13 @@ class Ref(Field):
|
|||
|
||||
# PX that displays referred objects as a list.
|
||||
pxViewList = Px('''
|
||||
<div if="not innerRef or mayAdd" style="margin-bottom: 4px">
|
||||
<div if="not innerRef or mayAdd or mayLink" style="margin-bottom: 4px">
|
||||
<span if="subLabel" class="discreet">:_(subLabel)</span>
|
||||
(<span class="discreet">:totalNumber</span>)
|
||||
<x>:field.pxAdd</x>
|
||||
<!-- This button opens a popup for linking additional objects -->
|
||||
<x if="mayLink and not inPickList"
|
||||
var2="popupMode='add'">:field.pxLink</x>
|
||||
<!-- The search button if field is queryable -->
|
||||
<input if="objects and field.queryable" type="button"
|
||||
class="buttonSmall button"
|
||||
|
@ -308,9 +328,9 @@ class Ref(Field):
|
|||
not field.isBack and zobj.mayEdit(field.writePermission);
|
||||
mayUnlink=False;
|
||||
mayAdd=False;
|
||||
navBaseCall='askRefField(%s,%s,%s,%s,**v**)' % \
|
||||
(q(ajaxHookId), q(zobj.absolute_url()), \
|
||||
q(field.name), q(innerRef));
|
||||
mayLink=False;
|
||||
navBaseCall='askRefField(%s,%s,%s,**v**)' % \
|
||||
(q(ajaxHookId), q(zobj.absolute_url()), q(innerRef));
|
||||
changeOrder=False;
|
||||
changeNumber=False;
|
||||
checkboxes=field.getAttribute(zobj, 'checkboxes') and \
|
||||
|
@ -404,11 +424,12 @@ class Ref(Field):
|
|||
mayEdit=not field.isBack and zobj.mayEdit(field.writePermission);
|
||||
mayUnlink=mayEdit and field.getAttribute(zobj, 'unlink');
|
||||
mayAdd=mayEdit and field.mayAdd(zobj, checkMayEdit=False);
|
||||
mayLink=mayEdit and field.mayAdd(zobj, mode='link', \
|
||||
checkMayEdit=False);
|
||||
addConfirmMsg=field.addConfirm and \
|
||||
_('%s_addConfirm' % field.labelId) or '';
|
||||
navBaseCall='askRefField(%s,%s,%s,%s,**v**)' % \
|
||||
(q(ajaxHookId), q(zobj.absolute_url()), \
|
||||
q(field.name), q(innerRef));
|
||||
navBaseCall='askRefField(%s,%s,%s,**v**)' % \
|
||||
(q(ajaxHookId), q(zobj.absolute_url()), q(innerRef));
|
||||
changeOrder=mayEdit and field.getAttribute(zobj, 'changeOrder');
|
||||
numbered=field.isNumbered(zobj);
|
||||
changeNumber=not inPickList and numbered and changeOrder and \
|
||||
|
@ -446,17 +467,7 @@ class Ref(Field):
|
|||
</select>
|
||||
<div if="not objects">-</div>
|
||||
<!-- The button for opening the popup -->
|
||||
<a target="appyIFrame"
|
||||
var="tiedClassName=ztool.getPortalType(field.klass);
|
||||
className=ztool.getPortalType(obj.klass)"
|
||||
href=":'%s/query?className=%s&search=%s:%s&popup=1' % \
|
||||
(ztool.absolute_url(), tiedClassName, obj.uid, field.name)">
|
||||
<input type="button" class="buttonSmall button"
|
||||
var="label=_('search_button')" value=":label"
|
||||
style=":'%s; %s' % (url('search', bg=True), \
|
||||
ztool.getButtonWidth(label))"
|
||||
onclick="openPopup('iframePopup')"/></a>
|
||||
</x>''')
|
||||
<x var="popupMode='repl'">:field.pxLink</x></x>''')
|
||||
|
||||
pxEdit = Px('''
|
||||
<x if="(field.link) and (field.link != 'list')">
|
||||
|
@ -1079,17 +1090,21 @@ class Ref(Field):
|
|||
# Link new objects
|
||||
if objects: self.linkObject(appyObj, objects)
|
||||
|
||||
def mayAdd(self, obj, checkMayEdit=True):
|
||||
'''May the user create a new referred object from p_obj via this Ref?
|
||||
If p_checkMayEdit is False, it means that the condition of being
|
||||
def mayAdd(self, obj, mode='create', checkMayEdit=True):
|
||||
'''May the user create (if p_mode == "create") or link
|
||||
(if mode == "link") (a) new referred object(s) from p_obj via this
|
||||
Ref? If p_checkMayEdit is False, it means that the condition of being
|
||||
allowed to edit this Ref field has already been checked somewhere
|
||||
else (it is always required, we just want to avoid checking it
|
||||
twice).'''
|
||||
# We can't (yet) do that on back references.
|
||||
if self.isBack: return gutils.No('is_back')
|
||||
# Check if this Ref is addable
|
||||
add = self.getAttribute(obj, 'add')
|
||||
if not add: return gutils.No('no_add')
|
||||
# Check if this Ref is addable/linkable.
|
||||
if mode == 'create':
|
||||
add = self.getAttribute(obj, 'add')
|
||||
if not add: return gutils.No('no_add')
|
||||
elif mode == 'link':
|
||||
if (self.link != 'popup') or not self.isMultiValued(): return
|
||||
# Have we reached the maximum number of referred elements?
|
||||
if self.multiplicity[1] != None:
|
||||
refCount = len(getattr(obj, self.name, ()))
|
||||
|
@ -1099,8 +1114,9 @@ class Ref(Field):
|
|||
if not obj.mayEdit(self.writePermission):
|
||||
return gutils.No('no_write_perm')
|
||||
# May the user create instances of the referred class?
|
||||
if not obj.getTool().userMayCreate(self.klass):
|
||||
return gutils.No('no_create_perm')
|
||||
if mode == 'create':
|
||||
if not obj.getTool().userMayCreate(self.klass):
|
||||
return gutils.No('no_create_perm')
|
||||
return True
|
||||
|
||||
def checkAdd(self, obj):
|
||||
|
@ -1294,6 +1310,14 @@ class Ref(Field):
|
|||
res.append(tool.getObject(uid))
|
||||
return res
|
||||
|
||||
def onSelectFromPopup(self, obj):
|
||||
'''This method is called on Ref fields with link="popup", when a user
|
||||
has selected objects from the popup, to be added to existing tied
|
||||
objects, from the view widget.'''
|
||||
obj = obj.appy()
|
||||
for tied in self.getPopupObjects(obj, obj.request, None):
|
||||
self.linkObject(obj, tied, noSecurity=False)
|
||||
|
||||
def onUiRequest(self, obj, rq):
|
||||
'''This method is called when an action tied to this Ref field is
|
||||
triggered from the user interface (link, unlink, link_many,
|
||||
|
|
|
@ -189,11 +189,23 @@ class UiSearch:
|
|||
self.translated = label and _(label) or ''
|
||||
self.translatedDescr = labelDescr and _(labelDescr) or ''
|
||||
|
||||
def setInitiator(self, initiator, field):
|
||||
def setInitiator(self, initiator, field, mode):
|
||||
'''If the search is defined in an attribute Ref.select, we receive here
|
||||
the p_initiator object and its Ref p_field.'''
|
||||
the p_initiator object, its Ref p_field and the p_mode, that can be:
|
||||
- "repl" if the objects selected in the popup will replace already
|
||||
tied objects;
|
||||
- "add" if those objects will be added to the already tied ones.
|
||||
.'''
|
||||
self.initiator = initiator
|
||||
self.initiatorField = field
|
||||
self.initiatorMode = mode
|
||||
# "initiatorHook" is the ID of the initiator field's XHTML tag.
|
||||
self.initiatorHook = '%s_%s' % (initiator.uid, field.name)
|
||||
|
||||
def getRootHookId(self):
|
||||
'''If an initiator field is there, return the initiator hook.
|
||||
Else, simply return the name of the search.'''
|
||||
return getattr(self, 'initiatorHook', self.name)
|
||||
|
||||
def showCheckboxes(self):
|
||||
'''If checkboxes are enabled for this search (and if an initiator field
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue