src/source/dev_guide/new-form.rst
branchdoc-dc
changeset 122 7e69ecc9fd43
parent 120 38e841475613
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/source/dev_guide/new-form.rst	Mon Dec 17 17:19:35 2018 +0100
@@ -0,0 +1,129 @@
+.. _newform:
+
+Understanding PyAMS form
+========================
+
+
+The forms are based on ZC3.form framework. It provide HTML and Json
+
+
+.. seealso::
+
+	https://z3cform.readthedocs.io/en/latest/
+
+
+
+
+
+.. _formhowto:
+
+
+How to create a form to a component
+-----------------------------------
+
+
+The standard form creation with Z3C is described in the following link.
+
+	https://z3cform.readthedocs.io/en/latest/mustread/form.html
+
+
+PyAMS Form Integration
+----------------------
+
+
+When creating a new object to the zodb, the construction of the form can't be based on an object passed context.
+To build the form we use a default factory that is attached to the container of the element.
+
+
+1) Add Form
+^^^^^^^^^^^
+
+.. code-block:: python
+
+
+    @pagelet_config(name='add-contact-phone-paragraph.html', context=IParagraphContainerTarget, layer=IPyAMSLayer,
+                    permission=MANAGE_CONTENT_PERMISSION)
+    class ContactPhoneParagraphAddForm(AdminDialogAddForm):
+        """Contact paragraph add form"""
+
+        legend = _("Add new phone contact card")
+        dialog_class = 'modal-large'
+        icon_css_class = 'fa fa-fw fa-phone'
+        edit_permission = MANAGE_CONTENT_PERMISSION
+
+        #Retrieve fields from the interface of the component
+        fields = field.Fields(IContactPhoneParagraph).omit('__parent__', '__name__', 'visible')
+
+
+        def create(self, data):
+            """Create one instance of the component"""
+            return ContactPhoneParagraph()
+
+        def add(self, object):
+            """Add the new component to the container that implement the interface `IParagraphContainer` """
+            IParagraphContainer(self.context).append(object)
+
+The associate form field are generated automatically based on this interface attributes
+
+
+2) Ajax Form
+^^^^^^^^^^^^
+
+The decorator :py:function:`@ajax_config()` allows the form is working with ajax requests by providing `json` content.
+
+.. code-block:: python
+
+    from pyams_form.form import ajax_config
+
+
+    @pagelet_config(name='add-contact-phone-paragraph.html', context=IParagraphContainerTarget, layer=IPyAMSLayer,
+                    permission=MANAGE_CONTENT_PERMISSION)
+    @ajax_config(name='add-contact-phone-paragraph.json', context=IParagraphContainerTarget, layer=IPyAMSLayer,
+                 base=BaseParagraphAJAXAddForm)
+    class ContactPhoneParagraphAddForm(AdminDialogAddForm):
+        """Contact paragraph add form"""
+
+        legend = _("Add new phone contact card"
+		...
+
+
+
+3) Edit form
+^^^^^^^^^^^^
+
+.. code-block:: python
+
+    @adapter_config(context=(IContactPhoneParagraph, IPyAMSLayer), provides=IParagraphInnerEditor)
+                permission=MANAGE_CONTENT_PERMISSION)
+    @ajax_config(name='inner-properties.json', context=IContactPhoneParagraph, layer=IPyAMSLayer,
+             base=BaseParagraphAJAXEditForm)
+    @implementer(IInnerForm)
+    class ContactPhoneParagraphInnerEditForm(ContactPhoneParagraphPropertiesEditForm):
+        """Contact paragraph inner edit form"""
+
+        legend = None
+
+        @property
+        def buttons(self):
+            if self.mode == INPUT_MODE:
+                return button.Buttons(IParagraphEditFormButtons)
+            else:
+                return button.Buttons()
+
+        def get_ajax_output(self, changes):
+            output = super(ContactParagraphInnerAJAXEditForm, self).get_ajax_output(changes)
+            updated = changes.get(IBaseParagraph, ())
+            if 'title' in updated:
+                output.setdefault('events', []).append(get_json_paragraph_refresh_event(self.context, self.request))
+            updated = changes.get(IContactParagraph, ())
+            if ('photo' in updated) or ('renderer' in updated):
+                # we have to commit transaction to be able to handle blobs...
+                if 'photo' in updated:
+                    ITransactionManager(self.context).get().commit()
+                output.setdefault('events', []).append(get_json_form_refresh_event(self.context, self.request,
+                                                                                   ContactParagraphInnerEditForm))
+            return output
+
+
+
+