@@ -171,6 +170,25 @@ class Ref(Field):
onclick=":ajaxBaseCall.replace('**v**', 'True')"/>
''')
+ # Shows the object number in a numbered list of tied objects.
+ pxNumber = Px('''
+ :objectIndex+1
+
+
+
+
+
+
+
''')
+
# PX that displays referred objects as a list.
pxViewList = Px('''
@@ -215,6 +233,7 @@ class Ref(Field):
var2="columns=ztool.getColumnsSpecifiers(tiedClassName, \
field.shownInfo, dir)">
+
:_(refField.labelId)
@@ -228,8 +247,12 @@ class Ref(Field):
onclick=":'toggleAllRefCbs(%s)' % q(ajaxHookId)"/>
+
+ class=":loop.tied.odd and 'even' or 'odd'"
+ var2="tiedUid=tied.o.id;
+ objectIndex=field.getIndexOf(zobj, tiedUid)|None">
+
:field.pxNumber
@@ -246,8 +269,8 @@ class Ref(Field):
-
+
@@ -287,6 +310,7 @@ class Ref(Field):
(q(ajaxHookId), q(zobj.absolute_url()), \
q(field.name), q(innerRef));
changeOrder=False;
+ changeNumber=False;
checkboxes=field.getAttribute(zobj, 'checkboxes') and \
(totalNumber > 1);
showSubTitles=showSubTitles|\
@@ -340,6 +364,7 @@ class Ref(Field):
info=field.getValue(zobj,startNumber=startNumber,someObjects=True);
objects=info.objects;
totalNumber=info.totalNumber;
+ numberWidth=len(str(totalNumber));
batchSize=info.batchSize;
batchNumber=len(objects);
folder=zobj.getCreateFolder();
@@ -353,6 +378,9 @@ class Ref(Field):
(q(ajaxHookId), q(zobj.absolute_url()), \
q(field.name), q(innerRef));
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');
checkboxes=checkboxesEnabled and (totalNumber > 1);
showSubTitles=req.get('showSubTitles', 'true') == 'true'">
@@ -425,10 +453,11 @@ class Ref(Field):
width=None, height=5, maxChars=None, colspan=1, master=None,
masterValue=None, focus=False, historized=False, mapping=None,
label=None, queryable=False, queryFields=None, queryNbCols=1,
- navigable=False, changeOrder=True, checkboxes=True,
- checkboxesDefault=None, sdefault='', scolspan=1, swidth=None,
- sheight=None, sselect=None, persist=True, render='list',
- menuIdMethod=None, menuInfoMethod=None, menuUrlMethod=None):
+ navigable=False, changeOrder=True, numbered=False,
+ checkboxes=True, checkboxesDefault=None, sdefault='',
+ scolspan=1, swidth=None, sheight=None, sselect=None,
+ persist=True, render='list', menuIdMethod=None,
+ menuInfoMethod=None, menuUrlMethod=None):
self.klass = klass
self.attribute = attribute
# May the user add new objects through this ref ?
@@ -513,12 +542,20 @@ class Ref(Field):
self.queryNbCols = queryNbCols
# Within the portlet, will referred elements appear ?
self.navigable = navigable
- # If "changeOrder" is False, it even if the user has the right to modify
- # the field, it will not be possible to move objects or sort them.
+ # If "changeOrder" is or returns False, it even if the user has the
+ # right to modify the field, it will not be possible to move objects or
+ # sort them.
self.changeOrder = changeOrder
- # If "checkboxes" is True, every linked object will be "selectable" vi
- # a checkbox: global actions will be possible, that will act on the
- # subset of selected objects: delete, unlink, etc.
+ # If "numbered" is or returns True, a leading column will show the
+ # number of every tied object. Moreover, if the user can change order of
+ # 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
# Default value for checkboxes, if enabled.
if checkboxesDefault == None:
@@ -719,6 +756,14 @@ class Ref(Field):
menu.icon = icon
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):
'''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,
@@ -941,9 +986,6 @@ class Ref(Field):
uid = rq['refObjectUid']
uids = getattr(obj.aq_base, self.name)
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':
newIndex = oldIndex - 1
elif move == 'down':
@@ -951,8 +993,17 @@ class Ref(Field):
elif move == 'top':
newIndex = 0
elif move == 'bottom':
- newIndex = len(uids)
- uids.insert(newIndex, uid)
+ 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)
xhtmlToText = re.compile('<.*?>', re.S)
def getReferenceLabel(self, refObject, unlimited=False):
diff --git a/gen/tr/Appy.pot b/gen/tr/Appy.pot
index 9d9a5c8..ef47237 100644
--- a/gen/tr/Appy.pot
+++ b/gen/tr/Appy.pot
@@ -111,6 +111,10 @@ msgstr ""
msgid "move_bottom"
msgstr ""
+#. Default: "Update the hereabove number and click here to move this element to a new position."
+msgid "move_number"
+msgstr ""
+
#. Default: "create"
msgid "query_create"
msgstr ""
diff --git a/gen/tr/ar.po b/gen/tr/ar.po
index e392dfb..cef7ded 100644
--- a/gen/tr/ar.po
+++ b/gen/tr/ar.po
@@ -111,6 +111,10 @@ msgstr ""
msgid "move_bottom"
msgstr ""
+#. Default: "Update the hereabove number and click here to move this element to a new position."
+msgid "move_number"
+msgstr ""
+
#. Default: "create"
msgid "query_create"
msgstr ""
diff --git a/gen/tr/de.po b/gen/tr/de.po
index 0dc5b22..84322f1 100644
--- a/gen/tr/de.po
+++ b/gen/tr/de.po
@@ -111,6 +111,10 @@ msgstr ""
msgid "move_bottom"
msgstr ""
+#. Default: "Update the hereabove number and click here to move this element to a new position."
+msgid "move_number"
+msgstr ""
+
#. Default: "create"
msgid "query_create"
msgstr "Anfertigen"
diff --git a/gen/tr/en.po b/gen/tr/en.po
index 56c4ab9..3a5bd77 100644
--- a/gen/tr/en.po
+++ b/gen/tr/en.po
@@ -112,6 +112,10 @@ msgstr "Move to top"
msgid "move_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"
msgid "query_create"
msgstr "create"
diff --git a/gen/tr/es.po b/gen/tr/es.po
index 4cc7770..05f20fc 100644
--- a/gen/tr/es.po
+++ b/gen/tr/es.po
@@ -111,6 +111,10 @@ msgstr ""
msgid "move_bottom"
msgstr ""
+#. Default: "Update the hereabove number and click here to move this element to a new position."
+msgid "move_number"
+msgstr ""
+
#. Default: "create"
msgid "query_create"
msgstr "Crear"
diff --git a/gen/tr/fr.po b/gen/tr/fr.po
index cee996a..de56336 100644
--- a/gen/tr/fr.po
+++ b/gen/tr/fr.po
@@ -112,6 +112,10 @@ msgstr "Déplacer en première position"
msgid "move_bottom"
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"
msgid "query_create"
msgstr "Créer"
diff --git a/gen/tr/it.po b/gen/tr/it.po
index 7df20b8..75a5e43 100644
--- a/gen/tr/it.po
+++ b/gen/tr/it.po
@@ -111,6 +111,10 @@ msgstr ""
msgid "move_bottom"
msgstr ""
+#. Default: "Update the hereabove number and click here to move this element to a new position."
+msgid "move_number"
+msgstr ""
+
#. Default: "create"
msgid "query_create"
msgstr "Creazione in corso"
diff --git a/gen/tr/nl.po b/gen/tr/nl.po
index a253d41..320b5a8 100644
--- a/gen/tr/nl.po
+++ b/gen/tr/nl.po
@@ -111,6 +111,10 @@ msgstr ""
msgid "move_bottom"
msgstr ""
+#. Default: "Update the hereabove number and click here to move this element to a new position."
+msgid "move_number"
+msgstr ""
+
#. Default: "create"
msgid "query_create"
msgstr "Aanmaken"
diff --git a/gen/ui/appy.js b/gen/ui/appy.js
index 2bbde76..d2b5c4b 100644
--- a/gen/ui/appy.js
+++ b/gen/ui/appy.js
@@ -1,3 +1,5 @@
+var wrongTextInput = '#F9EDBE none';
+
// Functions related to user authentication
function cookiesAreEnabled() {
// 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;
if (action) params['action'] = action;
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';
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 doAskPasswordReinit() {
// Check that the user has typed a login
diff --git a/gen/ui/linkMany.png b/gen/ui/linkMany.png
index e27d136..8b2b1c0 100644
Binary files a/gen/ui/linkMany.png and b/gen/ui/linkMany.png differ
diff --git a/gen/ui/move.png b/gen/ui/move.png
new file mode 100644
index 0000000..f1c2078
Binary files /dev/null and b/gen/ui/move.png differ
diff --git a/gen/ui/unlinkManyUp.png b/gen/ui/unlinkManyUp.png
index 1b61dda..1bdc8b3 100644
Binary files a/gen/ui/unlinkManyUp.png and b/gen/ui/unlinkManyUp.png differ