110 # add metadata to allow edition of metadata attributes (not considered by |
110 # add metadata to allow edition of metadata attributes (not considered by |
111 # edition form by default) |
111 # edition form by default) |
112 attrcategories = ('primary', 'secondary', 'metadata') |
112 attrcategories = ('primary', 'secondary', 'metadata') |
113 |
113 |
114 _onclick = u"showInlineEditionForm(%(eid)s, '%(rtype)s', '%(divid)s')" |
114 _onclick = u"showInlineEditionForm(%(eid)s, '%(rtype)s', '%(divid)s')" |
|
115 _onsubmit = ("return inlineValidateRelationForm('%(rtype)s', '%(role)s', '%(eid)s', " |
|
116 "'%(divid)s', %(reload)s, '%(vid)s', '%(default)s', '%(lzone)s');") |
|
117 _cancelclick = "hideInlineEdit(%s,\'%s\',\'%s\')" |
115 _defaultlandingzone = (u'<img title="%(msg)s" ' |
118 _defaultlandingzone = (u'<img title="%(msg)s" ' |
116 'src="data/accessories-text-editor.png" ' |
119 'src="data/accessories-text-editor.png" ' |
117 'alt="%(msg)s"/>') |
120 'alt="%(msg)s"/>') |
118 _landingzonemsg = _('click to edit this field') |
121 _landingzonemsg = _('click to edit this field') |
119 # default relation vids according to cardinality |
122 # default relation vids according to cardinality |
132 return self.vreg['formrenderers'].select( |
135 return self.vreg['formrenderers'].select( |
133 'base', self.req, entity=entity, display_label=False, |
136 'base', self.req, entity=entity, display_label=False, |
134 display_help=False, display_fields=[(rtype, role)], table_class='', |
137 display_help=False, display_fields=[(rtype, role)], table_class='', |
135 button_bar_class='buttonbar', display_progress_div=False) |
138 button_bar_class='buttonbar', display_progress_div=False) |
136 |
139 |
137 def _build_form(self, entity, rtype, role, formid, default, onsubmit, reload, |
140 def _build_form(self, entity, rtype, role, formid, default, reload, |
138 extradata=None, **formargs): |
141 extradata=None, **formargs): |
139 divid = 'd%s' % make_uid('%s-%s' % (rtype, entity.eid)) |
142 divid = '%s-%s-%s' % (entity.eid, rtype, role) |
140 event_data = {'divid' : divid, 'eid' : entity.eid, 'rtype' : rtype, |
143 event_data = {'divid' : divid, 'eid' : entity.eid, 'rtype' : rtype, |
141 'reload' : dumps(reload), 'default' : default} |
144 'reload' : dumps(reload), 'default' : default, 'role' : role, 'vid' : u'', |
|
145 'lzone' : self._build_landing_zone(None)} |
142 if extradata: |
146 if extradata: |
143 event_data.update(extradata) |
147 event_data.update(extradata) |
144 onsubmit %= event_data |
148 onsubmit = self._onsubmit % event_data |
145 cancelclick = "hideInlineEdit(%s,\'%s\',\'%s\')" % (entity.eid, rtype, |
149 cancelclick = self._cancelclick % (entity.eid, rtype, divid) |
146 divid) |
|
147 form = self.vreg['forms'].select( |
150 form = self.vreg['forms'].select( |
148 formid, self.req, entity=entity, domid='%s-form' % divid, |
151 formid, self.req, entity=entity, domid='%s-form' % divid, |
149 cssstyle='display: none', onsubmit=onsubmit, action='#', |
152 cssstyle='display: none', onsubmit=onsubmit, action='#', |
150 form_buttons=[SubmitButton(), Button(stdmsgs.BUTTON_CANCEL, |
153 form_buttons=[SubmitButton(), Button(stdmsgs.BUTTON_CANCEL, |
151 onclick=cancelclick)], |
154 onclick=cancelclick)], |
160 landing_zone=None # prepend value with a separate html element to click onto |
163 landing_zone=None # prepend value with a separate html element to click onto |
161 # (esp. needed when values are links) |
164 # (esp. needed when values are links) |
162 ): |
165 ): |
163 """display field to edit entity's `rtype` relation on click""" |
166 """display field to edit entity's `rtype` relation on click""" |
164 assert rtype |
167 assert rtype |
165 assert role in ('subject', 'object') |
168 assert role in ('subject', 'object'), '%s is not an acceptable role value' % role |
166 if default is None: |
169 if default is None: |
167 default = xml_escape(self.req._('<no value>')) |
170 default = xml_escape(self.req._('<no value>')) |
168 entity = self.entity(row, col) |
171 entity = self.entity(row, col) |
169 rschema = entity.schema.rschema(rtype) |
172 rschema = entity.schema.rschema(rtype) |
170 lzone = self._build_landing_zone(landing_zone) |
173 lzone = self._build_landing_zone(landing_zone) |
171 # compute value, checking perms, build form |
174 # compute value, checking perms, build form |
172 if rschema.final: |
175 if rschema.final: |
173 onsubmit = ("return inlineValidateAttributeForm('%(rtype)s', '%(eid)s', '%(divid)s', " |
176 form = self._build_form(entity, rtype, role, 'edition', default, reload, |
174 "%(reload)s, '%(default)s');") |
177 attrcategories=self.attrcategories) |
175 form = self._build_form( |
|
176 entity, rtype, role, 'edition', default, onsubmit, reload, |
|
177 attrcategories=self.attrcategories) |
|
178 if not self.should_edit_attribute(entity, rschema, role, form): |
178 if not self.should_edit_attribute(entity, rschema, role, form): |
179 self.w(entity.printable_value(rtype)) |
179 self.w(entity.printable_value(rtype)) |
180 return |
180 return |
181 value = entity.printable_value(rtype) or default |
181 value = entity.printable_value(rtype) or default |
182 self.attribute_form(lzone, value, form, |
182 self.relation_form(lzone, value, form, |
183 self._build_renderer(entity, rtype, role)) |
183 self._build_renderer(entity, rtype, role)) |
184 else: |
184 else: |
185 if rvid is None: |
185 if rvid is None: |
186 rvid = self._compute_best_vid(entity.e_schema, rschema, role) |
186 rvid = self._compute_best_vid(entity.e_schema, rschema, role) |
187 rset = entity.related(rtype, role) |
187 rset = entity.related(rtype, role) |
188 if rset: |
188 if rset: |
191 value = default |
191 value = default |
192 if not self.should_edit_relation(entity, rschema, role, rvid): |
192 if not self.should_edit_relation(entity, rschema, role, rvid): |
193 if rset: |
193 if rset: |
194 self.w(value) |
194 self.w(value) |
195 return |
195 return |
196 onsubmit = ("return inlineValidateRelationForm('%(rtype)s', '%(role)s', '%(eid)s', " |
196 form = self._build_form(entity, rtype, role, 'base', default, reload, |
197 "'%(divid)s', %(reload)s, '%(vid)s', '%(default)s', '%(lzone)s');") |
197 dict(vid=rvid, lzone=lzone)) |
198 form = self._build_form( |
|
199 entity, rtype, role, 'base', default, onsubmit, reload, |
|
200 dict(vid=rvid, role=role, lzone=lzone)) |
|
201 field = guess_field(entity.e_schema, entity.schema.rschema(rtype), role) |
198 field = guess_field(entity.e_schema, entity.schema.rschema(rtype), role) |
202 form.append_field(field) |
199 form.append_field(field) |
203 self.relation_form(lzone, value, form, |
200 self.relation_form(lzone, value, form, |
204 self._build_renderer(entity, rtype, role)) |
201 self._build_renderer(entity, rtype, role)) |
205 |
202 |
224 (role == 'object' and not rschema.has_perm(self.req, 'add', |
221 (role == 'object' and not rschema.has_perm(self.req, 'add', |
225 toeid=entity.eid))): |
222 toeid=entity.eid))): |
226 self.wview(rvid, entity.related(str(rschema), role), 'null') |
223 self.wview(rvid, entity.related(str(rschema), role), 'null') |
227 return False |
224 return False |
228 return True |
225 return True |
229 |
|
230 def attribute_form(self, lzone, value, form, renderer): |
|
231 """div (class=field) |
|
232 +-xxx div |
|
233 | +-xxx div (class=editableField) |
|
234 | | +-landing zone |
|
235 | +-value-xxx div |
|
236 | +-value |
|
237 +-form-xxx div |
|
238 """ |
|
239 w = self.w |
|
240 w(u'<div class="field">') |
|
241 w(u'<div id="%s" style="display: inline">' % form.event_data['divid']) |
|
242 w(tags.div(lzone, klass='editableField', |
|
243 onclick=self._onclick % form.event_data)) |
|
244 w(u'<div id="value-%s" style="display: inline">%s</div>' % |
|
245 (form.event_data['divid'], value)) |
|
246 w(u'</div>') |
|
247 w(form.form_render(renderer=renderer)) |
|
248 w(u'</div>') |
|
249 |
226 |
250 def relation_form(self, lzone, value, form, renderer): |
227 def relation_form(self, lzone, value, form, renderer): |
251 """xxx-reledit div (class=field) |
228 """xxx-reledit div (class=field) |
252 +-xxx div (class="editableField") |
229 +-xxx div (class="editableField") |
253 | +-landing zone |
230 | +-landing zone |