diff -r d7dd088ed557 -r 097b0c025eec src/source/developer_guide/howto-form.rst --- a/src/source/developer_guide/howto-form.rst Tue Dec 11 16:43:45 2018 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,103 +0,0 @@ -.. _formhowto: - - -How to create a form to a component -=================================== - - -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) Container factory --------------------- - -Declaration of the **factory** of `ContactPhoneParagraph` - -.. code-block:: python - - @utility_config(name=CONTACT_PHONE_PARAGRAPH_TYPE, provides=IParagraphFactory) - class ContactPhoneParagraphFactory(BaseParagraphFactory): - """Contact paragraph factory""" - - name = _("Contact Phone card") - content_type = ContactPhoneParagraph - secondary_menu = True - - - -For example :py:class:`IParagraphContainerTarget`, it's a marker interface for paragraph containers. -We could use this interface as context to declare a new pagelet. - - -.. 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") - 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 - -:py:function:`@ajax_config()` allows the form is working with ajax requests by providing `json` content. - - - -2) 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 -