src/source/dev_guide/new-form.rst
branchdoc-dc
changeset 122 7e69ecc9fd43
parent 120 38e841475613
equal deleted inserted replaced
121:98a84761634f 122:7e69ecc9fd43
       
     1 .. _newform:
       
     2 
       
     3 Understanding PyAMS form
       
     4 ========================
       
     5 
       
     6 
       
     7 The forms are based on ZC3.form framework. It provide HTML and Json
       
     8 
       
     9 
       
    10 .. seealso::
       
    11 
       
    12 	https://z3cform.readthedocs.io/en/latest/
       
    13 
       
    14 
       
    15 
       
    16 
       
    17 
       
    18 .. _formhowto:
       
    19 
       
    20 
       
    21 How to create a form to a component
       
    22 -----------------------------------
       
    23 
       
    24 
       
    25 The standard form creation with Z3C is described in the following link.
       
    26 
       
    27 	https://z3cform.readthedocs.io/en/latest/mustread/form.html
       
    28 
       
    29 
       
    30 PyAMS Form Integration
       
    31 ----------------------
       
    32 
       
    33 
       
    34 When creating a new object to the zodb, the construction of the form can't be based on an object passed context.
       
    35 To build the form we use a default factory that is attached to the container of the element.
       
    36 
       
    37 
       
    38 1) Add Form
       
    39 ^^^^^^^^^^^
       
    40 
       
    41 .. code-block:: python
       
    42 
       
    43 
       
    44     @pagelet_config(name='add-contact-phone-paragraph.html', context=IParagraphContainerTarget, layer=IPyAMSLayer,
       
    45                     permission=MANAGE_CONTENT_PERMISSION)
       
    46     class ContactPhoneParagraphAddForm(AdminDialogAddForm):
       
    47         """Contact paragraph add form"""
       
    48 
       
    49         legend = _("Add new phone contact card")
       
    50         dialog_class = 'modal-large'
       
    51         icon_css_class = 'fa fa-fw fa-phone'
       
    52         edit_permission = MANAGE_CONTENT_PERMISSION
       
    53 
       
    54         #Retrieve fields from the interface of the component
       
    55         fields = field.Fields(IContactPhoneParagraph).omit('__parent__', '__name__', 'visible')
       
    56 
       
    57 
       
    58         def create(self, data):
       
    59             """Create one instance of the component"""
       
    60             return ContactPhoneParagraph()
       
    61 
       
    62         def add(self, object):
       
    63             """Add the new component to the container that implement the interface `IParagraphContainer` """
       
    64             IParagraphContainer(self.context).append(object)
       
    65 
       
    66 The associate form field are generated automatically based on this interface attributes
       
    67 
       
    68 
       
    69 2) Ajax Form
       
    70 ^^^^^^^^^^^^
       
    71 
       
    72 The decorator :py:function:`@ajax_config()` allows the form is working with ajax requests by providing `json` content.
       
    73 
       
    74 .. code-block:: python
       
    75 
       
    76     from pyams_form.form import ajax_config
       
    77 
       
    78 
       
    79     @pagelet_config(name='add-contact-phone-paragraph.html', context=IParagraphContainerTarget, layer=IPyAMSLayer,
       
    80                     permission=MANAGE_CONTENT_PERMISSION)
       
    81     @ajax_config(name='add-contact-phone-paragraph.json', context=IParagraphContainerTarget, layer=IPyAMSLayer,
       
    82                  base=BaseParagraphAJAXAddForm)
       
    83     class ContactPhoneParagraphAddForm(AdminDialogAddForm):
       
    84         """Contact paragraph add form"""
       
    85 
       
    86         legend = _("Add new phone contact card"
       
    87 		...
       
    88 
       
    89 
       
    90 
       
    91 3) Edit form
       
    92 ^^^^^^^^^^^^
       
    93 
       
    94 .. code-block:: python
       
    95 
       
    96     @adapter_config(context=(IContactPhoneParagraph, IPyAMSLayer), provides=IParagraphInnerEditor)
       
    97                 permission=MANAGE_CONTENT_PERMISSION)
       
    98     @ajax_config(name='inner-properties.json', context=IContactPhoneParagraph, layer=IPyAMSLayer,
       
    99              base=BaseParagraphAJAXEditForm)
       
   100     @implementer(IInnerForm)
       
   101     class ContactPhoneParagraphInnerEditForm(ContactPhoneParagraphPropertiesEditForm):
       
   102         """Contact paragraph inner edit form"""
       
   103 
       
   104         legend = None
       
   105 
       
   106         @property
       
   107         def buttons(self):
       
   108             if self.mode == INPUT_MODE:
       
   109                 return button.Buttons(IParagraphEditFormButtons)
       
   110             else:
       
   111                 return button.Buttons()
       
   112 
       
   113         def get_ajax_output(self, changes):
       
   114             output = super(ContactParagraphInnerAJAXEditForm, self).get_ajax_output(changes)
       
   115             updated = changes.get(IBaseParagraph, ())
       
   116             if 'title' in updated:
       
   117                 output.setdefault('events', []).append(get_json_paragraph_refresh_event(self.context, self.request))
       
   118             updated = changes.get(IContactParagraph, ())
       
   119             if ('photo' in updated) or ('renderer' in updated):
       
   120                 # we have to commit transaction to be able to handle blobs...
       
   121                 if 'photo' in updated:
       
   122                     ITransactionManager(self.context).get().commit()
       
   123                 output.setdefault('events', []).append(get_json_form_refresh_event(self.context, self.request,
       
   124                                                                                    ContactParagraphInnerEditForm))
       
   125             return output
       
   126 
       
   127 
       
   128 
       
   129