Added widget for internal references list
authorThierry Florac <thierry.florac@onf.fr>
Tue, 16 May 2017 11:20:42 +0200
changeset 6 dd0072ed1543
parent 5 fb0de25afaab
child 7 29fcce505afe
Added widget for internal references list
src/pyams_sequence/widget/__init__.py
src/pyams_sequence/widget/interfaces.py
src/pyams_sequence/widget/templates/references-list-display.pt
src/pyams_sequence/widget/templates/references-list-input.pt
--- a/src/pyams_sequence/widget/__init__.py	Thu Oct 08 12:21:45 2015 +0200
+++ b/src/pyams_sequence/widget/__init__.py	Tue May 16 11:20:42 2017 +0200
@@ -21,8 +21,8 @@
 from pyams_form.interfaces.form import IFormLayer
 from pyams_i18n.interfaces import II18n
 from pyams_sequence.interfaces import ISequentialIntIds, ISequentialIdInfo
-from pyams_sequence.schema import IInternalReference
-from pyams_sequence.widget.interfaces import IInternalReferenceWidget
+from pyams_sequence.schema import IInternalReference, IInternalReferencesList
+from pyams_sequence.widget.interfaces import IInternalReferenceWidget, IInternalReferencesListWidget
 
 try:
     from pyams_workflow.interfaces import IWorkflowVersions, IWorkflowVersion, IWorkflowManagedContent
@@ -31,17 +31,18 @@
 else:
     handle_workflow = True
 
-from z3c.form.interfaces import IFieldWidget
+from z3c.form.interfaces import IFieldWidget, IDataConverter
 
 # import packages
 from hypatia.catalog import CatalogQuery
-from hypatia.query import Eq
+from hypatia.query import Eq, Any
 from pyams_catalog.query import CatalogResultSet
 from pyams_form.widget import widgettemplate_config
 from pyams_sequence.utility import get_last_version
 from pyams_utils.adapter import adapter_config
 from pyams_utils.registry import get_utility
 from z3c.form.browser.widget import HTMLInputWidget
+from z3c.form.converter import BaseDataConverter
 from z3c.form.widget import Widget, FieldWidget
 from zope.interface import implementer_only
 
@@ -58,9 +59,11 @@
 class InternalReferenceWidget(HTMLInputWidget, Widget):
     """Internal reference widget"""
 
+    content_type = None
+
     @property
     def query_params(self):
-        return json.dumps({'content_type': self.field.content_type})
+        return json.dumps({'content_type': self.content_type or self.field.content_type})
 
     @property
     def values_map(self):
@@ -81,3 +84,57 @@
 def InternalReferenceFieldWidget(field, request):
     """Internal reference field widget factory"""
     return FieldWidget(field, InternalReferenceWidget(request))
+
+
+#
+# Internal references list widget
+#
+
+@adapter_config(context=(IInternalReferencesList, IInternalReferencesListWidget), provides=IDataConverter)
+class InternalReferencesListDataConverter(BaseDataConverter):
+    """Internal references list data converter"""
+
+    def toWidgetValue(self, value):
+        if not value:
+            return ''
+        return ','.join(value)
+
+    def toFieldValue(self, value):
+        if not value:
+            return []
+        return value.split(',')
+
+
+@widgettemplate_config(mode='input', template='templates/references-list-input.pt', layer=IFormLayer)
+@widgettemplate_config(mode='display', template='templates/references-list-display.pt', layer=IFormLayer)
+@implementer_only(IInternalReferencesListWidget)
+class InternalReferencesListWidget(HTMLInputWidget, Widget):
+    """Internal references list widget"""
+
+    content_type = None
+
+    @property
+    def query_params(self):
+        return json.dumps({'content_type': self.content_type or self.field.content_type})
+
+    @property
+    def values_map(self):
+        catalog = get_utility(ICatalog)
+        sequence = get_utility(ISequentialIntIds)
+        values = self.value
+        if isinstance(values, str):
+            values = values.split(',')
+        params = Any(catalog['oid'], values)
+        results = {}
+        for item in map(get_last_version, CatalogResultSet(CatalogQuery(catalog).query(params))):
+            oid_info = ISequentialIdInfo(item)
+            results.update({oid_info.hex_oid: '{0} ({1})'.format(II18n(item).query_attribute('title',
+                                                                                             request=self.request),
+                                                                 sequence.get_short_oid(oid_info.oid))})
+        return json.dumps(results)
+
+
+@adapter_config(context=(IInternalReferencesList, IFormLayer), provides=IFieldWidget)
+def InternalReferencesListFieldWidget(field, request):
+    """Internal references list field widget factory"""
+    return FieldWidget(field, InternalReferencesListWidget(request))
--- a/src/pyams_sequence/widget/interfaces.py	Thu Oct 08 12:21:45 2015 +0200
+++ b/src/pyams_sequence/widget/interfaces.py	Tue May 16 11:20:42 2017 +0200
@@ -19,7 +19,16 @@
 from z3c.form.interfaces import IWidget
 
 # import packages
+from zope.interface import Attribute
 
 
 class IInternalReferenceWidget(IWidget):
-    """Single term widget"""
+    """Internal reference widget interface"""
+
+    content_type = Attribute("Content type selector")
+
+
+class IInternalReferencesListWidget(IWidget):
+    """Internal references list widget interface"""
+
+    content_type = Attribute("Content type selector")
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_sequence/widget/templates/references-list-display.pt	Tue May 16 11:20:42 2017 +0200
@@ -0,0 +1,25 @@
+<input type="hidden" autocomplete="off" readonly
+	tal:attributes="id view/id;
+					name view/name;
+					class string:select2 ${view/klass};
+					style view/style;
+					title view/title;
+					value view/value | nothing;
+					lang view/lang;
+					onclick view/onclick;
+					ondblclick view/ondblclick;
+					onmousedown view/onmousedown;
+					onmouseup view/onmouseup;
+					onmouseover view/onmouseover;
+					onmousemove view/onmousemove;
+					onmouseout view/onmouseout;
+					onkeypress view/onkeypress;
+					onkeydown view/onkeydown;
+					onkeyup view/onkeyup;
+					disabled view/disabled;
+					tabindex view/tabindex;
+					onfocus view/onfocus;
+					onblur view/onblur;
+					onchange view/onchange;
+					accesskey view/accesskey;
+					onselect view/onselect;" />
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_sequence/widget/templates/references-list-input.pt	Tue May 16 11:20:42 2017 +0200
@@ -0,0 +1,45 @@
+<label class="input bordered with-icon"
+	   tal:omit-tag="view/required" i18n:domain="pyams_sequence">
+	<i class="icon-append fa fa-trash-o hint opaque"
+		title="Clear selected value" i18n:attributes="title"
+		tal:omit-tag="view/required"
+		data-ams-hint-gravity="se"
+		data-ams-click-handler="MyAMS.helpers.select2ClearSelection"
+		tal:attributes="data-ams-select2-target view/name"></i>
+	<div class="select2-parent"
+		 tal:omit-tag="view/required">
+		<input type="hidden" autocomplete="off"
+			data-ams-select2-minimum-input-length="2"
+			data-ams-select2-allow-clear="true"
+			data-ams-select2-multiple="true"
+			data-ams-select2-query-method="findReferences"
+			data-ams-select2-method-target="/api/sequence/json"
+			tal:attributes="id view/id;
+							name view/name;
+							class string:select2 ordered ${view/klass};
+							style view/style;
+							title view/title;
+							value view/value | nothing;
+							lang view/lang;
+							onclick view/onclick;
+							ondblclick view/ondblclick;
+							onmousedown view/onmousedown;
+							onmouseup view/onmouseup;
+							onmouseover view/onmouseover;
+							onmousemove view/onmousemove;
+							onmouseout view/onmouseout;
+							onkeypress view/onkeypress;
+							onkeydown view/onkeydown;
+							onkeyup view/onkeyup;
+							disabled view/disabled;
+							tabindex view/tabindex;
+							onfocus view/onfocus;
+							onblur view/onblur;
+							onchange view/onchange;
+							readonly view/readonly;
+							accesskey view/accesskey;
+							onselect view/onselect;
+							data-ams-select2-values view/values_map;
+							data-ams-select2-query-params view/query_params;" />
+	</div>
+</label>