[gen] Added attribute Ref.numbered allowing to produce numbered lists of tied objects and controls for easily moving objects from one position to another.
This commit is contained in:
parent
036856f07e
commit
5de5372bec
|
@ -78,13 +78,12 @@ class Ref(Field):
|
||||||
# This PX displays icons for triggering actions on a given referenced object
|
# This PX displays icons for triggering actions on a given referenced object
|
||||||
# (edit, delete, etc).
|
# (edit, delete, etc).
|
||||||
pxObjectActions = Px('''
|
pxObjectActions = Px('''
|
||||||
<table class="noStyle" var="tiedUid=tied.o.id">
|
<table class="noStyle">
|
||||||
<tr>
|
<tr>
|
||||||
<!-- Arrows for moving objects up or down -->
|
<!-- Arrows for moving objects up or down -->
|
||||||
<td if="not isBack and (totalNumber >1) and changeOrder and canWrite \
|
<td if="not isBack and (totalNumber >1) and changeOrder and canWrite \
|
||||||
and not inPickList"
|
and not inPickList"
|
||||||
var2="objectIndex=field.getIndexOf(zobj, tiedUid);
|
var2="ajaxBaseCall=navBaseCall.replace('**v**','%s,%s,{%s:%s,%s:%s}'%\
|
||||||
ajaxBaseCall=navBaseCall.replace('**v**','%s,%s,{%s:%s,%s:%s}'%\
|
|
||||||
(q(startNumber), q('doChangeOrder'), q('refObjectUid'),
|
(q(startNumber), q('doChangeOrder'), q('refObjectUid'),
|
||||||
q(tiedUid), q('move'), q('**v**')))">
|
q(tiedUid), q('move'), q('**v**')))">
|
||||||
<!-- Move to top -->
|
<!-- Move to top -->
|
||||||
|
@ -108,9 +107,9 @@ class Ref(Field):
|
||||||
<td if="tied.o.showTransitions('result')"
|
<td if="tied.o.showTransitions('result')"
|
||||||
var2="targetObj=tied.o">:tied.pxTransitions</td>
|
var2="targetObj=tied.o">:tied.pxTransitions</td>
|
||||||
<!-- Edit -->
|
<!-- Edit -->
|
||||||
<td if="not field.noForm and tied.o.mayEdit() and field.delete">
|
<td if="not field.noForm and tied.o.mayEdit()">
|
||||||
<a var="navInfo='ref.%s.%s:%s.%d.%d' % (zobj.UID(), field.name, \
|
<a var="navInfo='ref.%s.%s:%s.%d.%d' % (zobj.id, field.name, \
|
||||||
field.pageName, loop.tied.nb+startNumber, totalNumber)"
|
field.pageName, loop.tied.nb + 1 + startNumber, totalNumber)"
|
||||||
href=":tied.o.getUrl(mode='edit', page='main', nav=navInfo)">
|
href=":tied.o.getUrl(mode='edit', page='main', nav=navInfo)">
|
||||||
<img src=":url('edit')" title=":_('object_edit')"/></a>
|
<img src=":url('edit')" title=":_('object_edit')"/></a>
|
||||||
</td>
|
</td>
|
||||||
|
@ -171,6 +170,25 @@ class Ref(Field):
|
||||||
onclick=":ajaxBaseCall.replace('**v**', 'True')"/>
|
onclick=":ajaxBaseCall.replace('**v**', 'True')"/>
|
||||||
</x>''')
|
</x>''')
|
||||||
|
|
||||||
|
# Shows the object number in a numbered list of tied objects.
|
||||||
|
pxNumber = Px('''
|
||||||
|
<x if="not changeNumber">:objectIndex+1</x>
|
||||||
|
<div if="changeNumber" class="dropdownMenu"
|
||||||
|
var2="id='%s_%d' % (ajaxHookId, objectIndex);
|
||||||
|
dropdownId='%s_dd' % id"
|
||||||
|
onmouseover=":'toggleDropdown(%s)' % q(dropdownId)"
|
||||||
|
onmouseout=":'toggleDropdown(%s,%s)' % (q(dropdownId), q('none'))">
|
||||||
|
<input type="text" size=":numberWidth" id=":id" value=":objectIndex+1"/>
|
||||||
|
<!-- The menu -->
|
||||||
|
<div id=":dropdownId" class="dropdown">
|
||||||
|
<img class="clickable" src=":url('move')" id=":id + '_img'"
|
||||||
|
title=":_('move_number')"
|
||||||
|
onclick=":navBaseCall.replace('**v**','%s,%s,{%s:%s,%s:this}' % \
|
||||||
|
(q(startNumber), q('doChangeOrder'), q('refObjectUid'),
|
||||||
|
q(tiedUid), q('move')))"/>
|
||||||
|
</div>
|
||||||
|
</div>''')
|
||||||
|
|
||||||
# PX that displays referred objects as a list.
|
# PX that displays referred objects as a list.
|
||||||
pxViewList = Px('''
|
pxViewList = Px('''
|
||||||
<!-- Display a simplified widget if at most 1 referenced object. -->
|
<!-- Display a simplified widget if at most 1 referenced object. -->
|
||||||
|
@ -215,6 +233,7 @@ class Ref(Field):
|
||||||
var2="columns=ztool.getColumnsSpecifiers(tiedClassName, \
|
var2="columns=ztool.getColumnsSpecifiers(tiedClassName, \
|
||||||
field.shownInfo, dir)">
|
field.shownInfo, dir)">
|
||||||
<tr if="field.showHeaders">
|
<tr if="field.showHeaders">
|
||||||
|
<th if="not inPickList and numbered" width=":numbered"></th>
|
||||||
<th for="column in columns" width=":column.width"
|
<th for="column in columns" width=":column.width"
|
||||||
align="column.align" var2="refField=column.field">
|
align="column.align" var2="refField=column.field">
|
||||||
<span>:_(refField.labelId)</span>
|
<span>:_(refField.labelId)</span>
|
||||||
|
@ -228,8 +247,12 @@ class Ref(Field):
|
||||||
onclick=":'toggleAllRefCbs(%s)' % q(ajaxHookId)"/>
|
onclick=":'toggleAllRefCbs(%s)' % q(ajaxHookId)"/>
|
||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
|
<!-- Loop on every (tied or selectable) object. -->
|
||||||
<tr for="tied in objects" valign="top"
|
<tr for="tied in objects" valign="top"
|
||||||
class=":loop.tied.odd and 'even' or 'odd'">
|
class=":loop.tied.odd and 'even' or 'odd'"
|
||||||
|
var2="tiedUid=tied.o.id;
|
||||||
|
objectIndex=field.getIndexOf(zobj, tiedUid)|None">
|
||||||
|
<td if="not inPickList and numbered">:field.pxNumber</td>
|
||||||
<td for="column in columns" width=":column.width" align=":column.align"
|
<td for="column in columns" width=":column.width" align=":column.align"
|
||||||
var2="refField=column.field">
|
var2="refField=column.field">
|
||||||
<!-- The "title" field -->
|
<!-- The "title" field -->
|
||||||
|
@ -246,8 +269,8 @@ class Ref(Field):
|
||||||
</x>
|
</x>
|
||||||
</td>
|
</td>
|
||||||
<td if="checkboxes" class="cbCell">
|
<td if="checkboxes" class="cbCell">
|
||||||
<input var="tiedUid=tied.uid" type="checkbox" name=":ajaxHookId"
|
<input type="checkbox" name=":ajaxHookId" checked="checked"
|
||||||
checked="checked" value=":tiedUid" onclick="toggleRefCb(this)"/>
|
value=":tiedUid" onclick="toggleRefCb(this)"/>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
@ -287,6 +310,7 @@ class Ref(Field):
|
||||||
(q(ajaxHookId), q(zobj.absolute_url()), \
|
(q(ajaxHookId), q(zobj.absolute_url()), \
|
||||||
q(field.name), q(innerRef));
|
q(field.name), q(innerRef));
|
||||||
changeOrder=False;
|
changeOrder=False;
|
||||||
|
changeNumber=False;
|
||||||
checkboxes=field.getAttribute(zobj, 'checkboxes') and \
|
checkboxes=field.getAttribute(zobj, 'checkboxes') and \
|
||||||
(totalNumber > 1);
|
(totalNumber > 1);
|
||||||
showSubTitles=showSubTitles|\
|
showSubTitles=showSubTitles|\
|
||||||
|
@ -340,6 +364,7 @@ class Ref(Field):
|
||||||
info=field.getValue(zobj,startNumber=startNumber,someObjects=True);
|
info=field.getValue(zobj,startNumber=startNumber,someObjects=True);
|
||||||
objects=info.objects;
|
objects=info.objects;
|
||||||
totalNumber=info.totalNumber;
|
totalNumber=info.totalNumber;
|
||||||
|
numberWidth=len(str(totalNumber));
|
||||||
batchSize=info.batchSize;
|
batchSize=info.batchSize;
|
||||||
batchNumber=len(objects);
|
batchNumber=len(objects);
|
||||||
folder=zobj.getCreateFolder();
|
folder=zobj.getCreateFolder();
|
||||||
|
@ -353,6 +378,9 @@ class Ref(Field):
|
||||||
(q(ajaxHookId), q(zobj.absolute_url()), \
|
(q(ajaxHookId), q(zobj.absolute_url()), \
|
||||||
q(field.name), q(innerRef));
|
q(field.name), q(innerRef));
|
||||||
changeOrder=field.getAttribute(zobj, 'changeOrder');
|
changeOrder=field.getAttribute(zobj, 'changeOrder');
|
||||||
|
numbered=field.isNumbered(zobj);
|
||||||
|
changeNumber=not inPickList and numbered and canWrite and \
|
||||||
|
changeOrder and (totalNumber > 3);
|
||||||
checkboxesEnabled=field.getAttribute(zobj, 'checkboxes');
|
checkboxesEnabled=field.getAttribute(zobj, 'checkboxes');
|
||||||
checkboxes=checkboxesEnabled and (totalNumber > 1);
|
checkboxes=checkboxesEnabled and (totalNumber > 1);
|
||||||
showSubTitles=req.get('showSubTitles', 'true') == 'true'">
|
showSubTitles=req.get('showSubTitles', 'true') == 'true'">
|
||||||
|
@ -425,10 +453,11 @@ class Ref(Field):
|
||||||
width=None, height=5, maxChars=None, colspan=1, master=None,
|
width=None, height=5, maxChars=None, colspan=1, master=None,
|
||||||
masterValue=None, focus=False, historized=False, mapping=None,
|
masterValue=None, focus=False, historized=False, mapping=None,
|
||||||
label=None, queryable=False, queryFields=None, queryNbCols=1,
|
label=None, queryable=False, queryFields=None, queryNbCols=1,
|
||||||
navigable=False, changeOrder=True, checkboxes=True,
|
navigable=False, changeOrder=True, numbered=False,
|
||||||
checkboxesDefault=None, sdefault='', scolspan=1, swidth=None,
|
checkboxes=True, checkboxesDefault=None, sdefault='',
|
||||||
sheight=None, sselect=None, persist=True, render='list',
|
scolspan=1, swidth=None, sheight=None, sselect=None,
|
||||||
menuIdMethod=None, menuInfoMethod=None, menuUrlMethod=None):
|
persist=True, render='list', menuIdMethod=None,
|
||||||
|
menuInfoMethod=None, menuUrlMethod=None):
|
||||||
self.klass = klass
|
self.klass = klass
|
||||||
self.attribute = attribute
|
self.attribute = attribute
|
||||||
# May the user add new objects through this ref ?
|
# May the user add new objects through this ref ?
|
||||||
|
@ -513,12 +542,20 @@ class Ref(Field):
|
||||||
self.queryNbCols = queryNbCols
|
self.queryNbCols = queryNbCols
|
||||||
# Within the portlet, will referred elements appear ?
|
# Within the portlet, will referred elements appear ?
|
||||||
self.navigable = navigable
|
self.navigable = navigable
|
||||||
# If "changeOrder" is False, it even if the user has the right to modify
|
# If "changeOrder" is or returns False, it even if the user has the
|
||||||
# the field, it will not be possible to move objects or sort them.
|
# right to modify the field, it will not be possible to move objects or
|
||||||
|
# sort them.
|
||||||
self.changeOrder = changeOrder
|
self.changeOrder = changeOrder
|
||||||
# If "checkboxes" is True, every linked object will be "selectable" vi
|
# If "numbered" is or returns True, a leading column will show the
|
||||||
# a checkbox: global actions will be possible, that will act on the
|
# number of every tied object. Moreover, if the user can change order of
|
||||||
# subset of selected objects: delete, unlink, etc.
|
# tied objects, an input field will allow him to enter a new number for
|
||||||
|
# the tied object. If "numbered" is or returns a string, it will be used
|
||||||
|
# as width for the column containing the number. Else, a default width
|
||||||
|
# will be used.
|
||||||
|
self.numbered = numbered
|
||||||
|
# If "checkboxes" is or returns True, every linked object will be
|
||||||
|
# "selectable" via a checkbox. Global actions will be activated and will
|
||||||
|
# act on the subset of selected objects: delete, unlink, etc.
|
||||||
self.checkboxes = checkboxes
|
self.checkboxes = checkboxes
|
||||||
# Default value for checkboxes, if enabled.
|
# Default value for checkboxes, if enabled.
|
||||||
if checkboxesDefault == None:
|
if checkboxesDefault == None:
|
||||||
|
@ -719,6 +756,14 @@ class Ref(Field):
|
||||||
menu.icon = icon
|
menu.icon = icon
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
def isNumbered(self, obj):
|
||||||
|
'''Must we show the order number of every tied object?'''
|
||||||
|
res = self.getAttribute(obj, 'numbered')
|
||||||
|
if not res: return res
|
||||||
|
# Returns the column width.
|
||||||
|
if not isinstance(res, basestring): return '15px'
|
||||||
|
return res
|
||||||
|
|
||||||
def getMenuUrl(self, zobj, tied):
|
def getMenuUrl(self, zobj, tied):
|
||||||
'''We must provide the URL of the p_tied object, when shown in a Ref
|
'''We must provide the URL of the p_tied object, when shown in a Ref
|
||||||
field in render mode 'menus'. If self.menuUrlMethod is specified,
|
field in render mode 'menus'. If self.menuUrlMethod is specified,
|
||||||
|
@ -941,9 +986,6 @@ class Ref(Field):
|
||||||
uid = rq['refObjectUid']
|
uid = rq['refObjectUid']
|
||||||
uids = getattr(obj.aq_base, self.name)
|
uids = getattr(obj.aq_base, self.name)
|
||||||
oldIndex = uids.index(uid)
|
oldIndex = uids.index(uid)
|
||||||
# Remove the object from its previous position.
|
|
||||||
uids.remove(uid)
|
|
||||||
# Re-insert the object at its new position.
|
|
||||||
if move == 'up':
|
if move == 'up':
|
||||||
newIndex = oldIndex - 1
|
newIndex = oldIndex - 1
|
||||||
elif move == 'down':
|
elif move == 'down':
|
||||||
|
@ -951,7 +993,16 @@ class Ref(Field):
|
||||||
elif move == 'top':
|
elif move == 'top':
|
||||||
newIndex = 0
|
newIndex = 0
|
||||||
elif move == 'bottom':
|
elif move == 'bottom':
|
||||||
newIndex = len(uids)
|
newIndex = len(uids) - 1
|
||||||
|
elif move.startswith('index'):
|
||||||
|
# New index starts at 1 (oldIndex starts at 0).
|
||||||
|
try:
|
||||||
|
newIndex = int(move.split('_')[1]) - 1
|
||||||
|
except ValueError:
|
||||||
|
newIndex = -1
|
||||||
|
# If newIndex is negative, it means that the move can't occur.
|
||||||
|
if newIndex > -1:
|
||||||
|
uids.remove(uid)
|
||||||
uids.insert(newIndex, uid)
|
uids.insert(newIndex, uid)
|
||||||
|
|
||||||
xhtmlToText = re.compile('<.*?>', re.S)
|
xhtmlToText = re.compile('<.*?>', re.S)
|
||||||
|
|
|
@ -111,6 +111,10 @@ msgstr ""
|
||||||
msgid "move_bottom"
|
msgid "move_bottom"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#. Default: "Update the hereabove number and click here to move this element to a new position."
|
||||||
|
msgid "move_number"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#. Default: "create"
|
#. Default: "create"
|
||||||
msgid "query_create"
|
msgid "query_create"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
|
@ -111,6 +111,10 @@ msgstr ""
|
||||||
msgid "move_bottom"
|
msgid "move_bottom"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#. Default: "Update the hereabove number and click here to move this element to a new position."
|
||||||
|
msgid "move_number"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#. Default: "create"
|
#. Default: "create"
|
||||||
msgid "query_create"
|
msgid "query_create"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
|
@ -111,6 +111,10 @@ msgstr ""
|
||||||
msgid "move_bottom"
|
msgid "move_bottom"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#. Default: "Update the hereabove number and click here to move this element to a new position."
|
||||||
|
msgid "move_number"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#. Default: "create"
|
#. Default: "create"
|
||||||
msgid "query_create"
|
msgid "query_create"
|
||||||
msgstr "Anfertigen"
|
msgstr "Anfertigen"
|
||||||
|
|
|
@ -112,6 +112,10 @@ msgstr "Move to top"
|
||||||
msgid "move_bottom"
|
msgid "move_bottom"
|
||||||
msgstr "Move to bottom"
|
msgstr "Move to bottom"
|
||||||
|
|
||||||
|
#. Default: "Update the hereabove number and click here to move this element to a new position."
|
||||||
|
msgid "move_number"
|
||||||
|
msgstr "Update the hereabove number and click here to move this element to a new position."
|
||||||
|
|
||||||
#. Default: "create"
|
#. Default: "create"
|
||||||
msgid "query_create"
|
msgid "query_create"
|
||||||
msgstr "create"
|
msgstr "create"
|
||||||
|
|
|
@ -111,6 +111,10 @@ msgstr ""
|
||||||
msgid "move_bottom"
|
msgid "move_bottom"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#. Default: "Update the hereabove number and click here to move this element to a new position."
|
||||||
|
msgid "move_number"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#. Default: "create"
|
#. Default: "create"
|
||||||
msgid "query_create"
|
msgid "query_create"
|
||||||
msgstr "Crear"
|
msgstr "Crear"
|
||||||
|
|
|
@ -112,6 +112,10 @@ msgstr "Déplacer en première position"
|
||||||
msgid "move_bottom"
|
msgid "move_bottom"
|
||||||
msgstr "Déplacer en dernière position"
|
msgstr "Déplacer en dernière position"
|
||||||
|
|
||||||
|
#. Default: "Update the hereabove number and click here to move this element to a new position."
|
||||||
|
msgid "move_number"
|
||||||
|
msgstr "Modifiez le numéro ci-dessus et cliquez ici pour déplacer l'élément à une nouvelle position."
|
||||||
|
|
||||||
#. Default: "create"
|
#. Default: "create"
|
||||||
msgid "query_create"
|
msgid "query_create"
|
||||||
msgstr "Créer"
|
msgstr "Créer"
|
||||||
|
|
|
@ -111,6 +111,10 @@ msgstr ""
|
||||||
msgid "move_bottom"
|
msgid "move_bottom"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#. Default: "Update the hereabove number and click here to move this element to a new position."
|
||||||
|
msgid "move_number"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#. Default: "create"
|
#. Default: "create"
|
||||||
msgid "query_create"
|
msgid "query_create"
|
||||||
msgstr "Creazione in corso"
|
msgstr "Creazione in corso"
|
||||||
|
|
|
@ -111,6 +111,10 @@ msgstr ""
|
||||||
msgid "move_bottom"
|
msgid "move_bottom"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#. Default: "Update the hereabove number and click here to move this element to a new position."
|
||||||
|
msgid "move_number"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#. Default: "create"
|
#. Default: "create"
|
||||||
msgid "query_create"
|
msgid "query_create"
|
||||||
msgstr "Aanmaken"
|
msgstr "Aanmaken"
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
var wrongTextInput = '#F9EDBE none';
|
||||||
|
|
||||||
// Functions related to user authentication
|
// Functions related to user authentication
|
||||||
function cookiesAreEnabled() {
|
function cookiesAreEnabled() {
|
||||||
// Test whether cookies are enabled by attempting to set a cookie and then
|
// Test whether cookies are enabled by attempting to set a cookie and then
|
||||||
|
@ -240,7 +242,20 @@ function askRefField(hookId, objectUrl, fieldName, innerRef, startNumber,
|
||||||
params[startKey] = startNumber;
|
params[startKey] = startNumber;
|
||||||
if (action) params['action'] = action;
|
if (action) params['action'] = action;
|
||||||
if (actionParams) {
|
if (actionParams) {
|
||||||
for (key in actionParams) { params[key] = actionParams[key]; };
|
for (key in actionParams) {
|
||||||
|
if ((key == 'move') && (typeof actionParams[key] == 'object')) {
|
||||||
|
// Get the new index from an input field
|
||||||
|
var id = actionParams[key].id;
|
||||||
|
id = id.substr(0, id.length-4);
|
||||||
|
var input = document.getElementById(id);
|
||||||
|
if (isNaN(input.value)) {
|
||||||
|
input.style.background = wrongTextInput;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
params[key] = 'index_' + input.value;
|
||||||
|
}
|
||||||
|
else params[key] = actionParams[key];
|
||||||
|
};
|
||||||
}
|
}
|
||||||
var px = (scope == 'objs')? ':pxView': ':pxViewPickList';
|
var px = (scope == 'objs')? ':pxView': ':pxViewPickList';
|
||||||
askAjaxChunk(hookId, 'GET', objectUrl, fieldName + px, params, null,
|
askAjaxChunk(hookId, 'GET', objectUrl, fieldName + px, params, null,
|
||||||
|
@ -735,7 +750,6 @@ function doConfirm() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var wrongTextInput = '#F9EDBE none';
|
|
||||||
// Function triggered when the user asks password reinitialisation
|
// Function triggered when the user asks password reinitialisation
|
||||||
function doAskPasswordReinit() {
|
function doAskPasswordReinit() {
|
||||||
// Check that the user has typed a login
|
// Check that the user has typed a login
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 322 B After Width: | Height: | Size: 327 B |
BIN
gen/ui/move.png
Normal file
BIN
gen/ui/move.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 233 B |
Binary file not shown.
Before Width: | Height: | Size: 321 B After Width: | Height: | Size: 316 B |
Loading…
Reference in a new issue