|
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 |