Understanding PyAMS form¶
The forms are based on ZC3.form framework. It provide HTML and Json
How to create a form to a component¶
The standard form creation with Z3C is described in the following link.
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¶
@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.
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¶
@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