SelectFieldWidget uses vocabulary order to display selected items in the edit form (not the field's order). This leads to order being changed accidentally on edit.
Given: A SelectFieldWidget on a RelationList with a Vocabulary that is sorted by Title
from plone.app.z3cform.widget import SelectFieldWidget directives.widget("persons", SelectFieldWidget) persons = RelationList( title=_(u"Persons"), description=_("Choose persons that shall be listed for this location."), required=False, default=, value_type=RelationChoice(vocabulary="my.package.location_persons"), )
Select (and/or) order selected items: PersonC, PersonB, PersonA
SelectWidget displays: PersonA, PersonB, PersonC
Saving the form (w/o even touching the
persons field will change the order of the
in archetypes i previously worked around this by returning the correct order in the vocabulary (pseudo-code)
def SortedPersonVocabulary(context) uids = context.getField('persons').getRaw(context) persons = catalog(portal_type="Person", sort_on="sortable_title") _max = len(uids) def pos(x): try: return uids.index(x.UID) except ValueError: return _max return to_vocab(sorted(persons, key=pos))
of course i can use the same workaround again but i strongly believe this should be fixed on widget level
first i'd have suggested to change
z3c.form.browser.select.SelectWidget.items and make items return the selected items in the correct order prior to the rest of the vocabulary values.
def pos(term): try: return self.value.index(term.token) except ValueError: # keep original pos for all non selected values return len(self.value) terms = self.terms if ISequence.providedBy(self.field) or self.orderable: terms = sorted(self.terms, key=pos) for idx, term in enumerate(terms): addItem(idx, term)
this works, but i'm not sure if a pr like this would be welcomed on zope-level.
browsing through the z3c.form repos i see there is also a
SelectFieldWidget should use this widget instead the plain selectwidget?
i really wonder why this problem did not bite a lot of plone5 users before and exists at all.
to be honest, i'm a bit confused due to the number the different packages involved.
maybe someone more involved in plone.app.z3cform and mockup can shed some light on this.
side note rant: I also tried AjaxSelectWidget with a searchable vocab
person_vocab(context, query=None) or source but ran into the same problems @datar reported in his thread in april 2020. the problem still seems not to be solved.