26 from cubicweb.web.form import FormViewMixIn, FieldNotFound |
26 from cubicweb.web.form import FormViewMixIn, FieldNotFound |
27 from cubicweb.web.formfields import guess_field |
27 from cubicweb.web.formfields import guess_field |
28 from cubicweb.web.formwidgets import Button, SubmitButton, ResetButton |
28 from cubicweb.web.formwidgets import Button, SubmitButton, ResetButton |
29 from cubicweb.web.views import forms |
29 from cubicweb.web.views import forms |
30 |
30 |
|
31 _pvdc = uicfg.primaryview_display_ctrl |
31 |
32 |
32 def relation_id(eid, rtype, role, reid): |
33 def relation_id(eid, rtype, role, reid): |
33 """return an identifier for a relation between two entities""" |
34 """return an identifier for a relation between two entities""" |
34 if role == 'subject': |
35 if role == 'subject': |
35 return u'%s:%s:%s' % (eid, rtype, reid) |
36 return u'%s:%s:%s' % (eid, rtype, reid) |
94 # don't use outofcontext view or any other that may contain inline |
95 # don't use outofcontext view or any other that may contain inline |
95 # edition form |
96 # edition form |
96 w(u'<li>%s</li>' % tags.a(entity.view('textoutofcontext'), |
97 w(u'<li>%s</li>' % tags.a(entity.view('textoutofcontext'), |
97 href=entity.absolute_url())) |
98 href=entity.absolute_url())) |
98 w(u'</ul>\n') |
99 w(u'</ul>\n') |
99 w(form.form_render()) |
100 w(form.render()) |
100 |
101 |
101 |
102 |
102 class ClickAndEditFormView(FormViewMixIn, EntityView): |
103 class ClickAndEditFormView(FormViewMixIn, EntityView): |
103 """form used to permit ajax edition of a relation or attribute of an entity |
104 """form used to permit ajax edition of a relation or attribute of an entity |
104 in a view, if logged user have the permission to edit it. |
105 in a view, if logged user have the permission to edit it. |
147 return |
148 return |
148 value = entity.printable_value(rtype) or default |
149 value = entity.printable_value(rtype) or default |
149 self.relation_form(lzone, value, form, |
150 self.relation_form(lzone, value, form, |
150 self._build_renderer(entity, rtype, role)) |
151 self._build_renderer(entity, rtype, role)) |
151 else: |
152 else: |
152 if rvid is None: |
153 rvid = self._compute_best_vid(entity.e_schema, rschema, role) |
153 rvid = self._compute_best_vid(entity.e_schema, rschema, role) |
|
154 rset = entity.related(rtype, role) |
154 rset = entity.related(rtype, role) |
155 if rset: |
155 if rset: |
156 value = self._cw.view(rvid, rset) |
156 value = self._cw.view(rvid, rset) |
157 else: |
157 else: |
158 value = default |
158 value = default |
200 w(u'<div id="%s-reledit" class="field" ' |
200 w(u'<div id="%s-reledit" class="field" ' |
201 u'onmouseout="addElementClass(jQuery(\'#%s\'), \'hidden\')" ' |
201 u'onmouseout="addElementClass(jQuery(\'#%s\'), \'hidden\')" ' |
202 u'onmouseover="removeElementClass(jQuery(\'#%s\'), \'hidden\')">' |
202 u'onmouseover="removeElementClass(jQuery(\'#%s\'), \'hidden\')">' |
203 % (divid, divid, divid)) |
203 % (divid, divid, divid)) |
204 w(u'<div id="%s-value" class="editableFieldValue">%s</div>' % (divid, value)) |
204 w(u'<div id="%s-value" class="editableFieldValue">%s</div>' % (divid, value)) |
205 w(form.form_render(renderer=renderer)) |
205 w(form.render(renderer=renderer)) |
206 w(u'<div id="%s" class="editableField hidden" onclick="%s" title="%s">' % ( |
206 w(u'<div id="%s" class="editableField hidden" onclick="%s" title="%s">' % ( |
207 divid, xml_escape(self._onclick % form.event_args), |
207 divid, xml_escape(self._onclick % form.event_args), |
208 self.req._(self._landingzonemsg))) |
208 self.req._(self._landingzonemsg))) |
209 w(lzone) |
209 w(lzone) |
210 w(u'</div>') |
210 w(u'</div>') |
211 w(u'</div>') |
211 w(u'</div>') |
212 |
212 |
213 def _compute_best_vid(self, eschema, rschema, role): |
213 def _compute_best_vid(self, eschema, rschema, role): |
|
214 dispctrl = _pvdc.etype_get(eschema, rschema, role) |
|
215 if dispctrl.get('rvid'): |
|
216 return dispctrl['rvid'] |
214 if eschema.cardinality(rschema, role) in '+*': |
217 if eschema.cardinality(rschema, role) in '+*': |
215 return self._many_rvid |
218 return self._many_rvid |
216 return self._one_rvid |
219 return self._one_rvid |
217 |
220 |
218 def _build_landing_zone(self, lzone): |
221 def _build_landing_zone(self, lzone): |
252 |
255 |
253 class DummyForm(object): |
256 class DummyForm(object): |
254 __slots__ = ('event_args',) |
257 __slots__ = ('event_args',) |
255 def form_render(self, **_args): |
258 def form_render(self, **_args): |
256 return u'' |
259 return u'' |
|
260 def render(self, **_args): |
|
261 return u'' |
257 def append_field(self, *args): |
262 def append_field(self, *args): |
258 pass |
263 pass |
259 |
264 |
260 class AutoClickAndEditFormView(ClickAndEditFormView): |
265 class AutoClickAndEditFormView(ClickAndEditFormView): |
261 """same as ClickAndEditFormView but checking if the view *should* be applied |
266 """same as ClickAndEditFormView but checking if the view *should* be applied |
267 |
272 |
268 def should_edit_relation(self, entity, rschema, role, rvid): |
273 def should_edit_relation(self, entity, rschema, role, rvid): |
269 eschema = entity.e_schema |
274 eschema = entity.e_schema |
270 rtype = str(rschema) |
275 rtype = str(rschema) |
271 # XXX check autoform_section. what if 'generic'? |
276 # XXX check autoform_section. what if 'generic'? |
272 dispctrl = uicfg.primaryview_display_ctrl.etype_get(eschema, rtype, role) |
277 dispctrl = _pvdc.etype_get(eschema, rtype, role) |
273 vid = dispctrl.get('vid', 'reledit') |
278 vid = dispctrl.get('vid', 'reledit') |
274 if vid != 'reledit': # reledit explicitly disabled |
279 if vid != 'reledit': # reledit explicitly disabled |
275 return False |
280 return False |
276 if eschema.role_rproperty(role, rschema, 'composite') == role: |
281 if eschema.role_rproperty(role, rschema, 'composite') == role: |
277 return False |
282 return False |
308 form = self._cw.vreg['forms'].select('edition', self._cw, rset=entity.cw_rset, |
313 form = self._cw.vreg['forms'].select('edition', self._cw, rset=entity.cw_rset, |
309 row=entity.cw_row, col=entity.cw_col, |
314 row=entity.cw_row, col=entity.cw_col, |
310 entity=entity, |
315 entity=entity, |
311 submitmsg=self.submited_message()) |
316 submitmsg=self.submited_message()) |
312 self.init_form(form, entity) |
317 self.init_form(form, entity) |
313 self.w(form.form_render(formvid=u'edition')) |
318 self.w(form.render(rendervalues=dict(formvid=u'edition'))) |
314 |
319 |
315 def init_form(self, form, entity): |
320 def init_form(self, form, entity): |
316 """customize your form before rendering here""" |
321 """customize your form before rendering here""" |
317 pass |
322 pass |
318 |
323 |
445 """ |
450 """ |
446 #self.form_title(entity) |
451 #self.form_title(entity) |
447 form = self._cw.vreg['forms'].select(self.__regid__, self._cw, |
452 form = self._cw.vreg['forms'].select(self.__regid__, self._cw, |
448 rset=self.cw_rset, |
453 rset=self.cw_rset, |
449 copy_nav_params=True) |
454 copy_nav_params=True) |
450 self.w(form.form_render()) |
455 self.w(form.render()) |
451 |
456 |
452 |
457 |
453 class InlineEntityEditionFormView(FormViewMixIn, EntityView): |
458 class InlineEntityEditionFormView(FormViewMixIn, EntityView): |
454 """ |
459 """ |
455 :attr peid: the parent entity's eid hosting the inline form |
460 :attr peid: the parent entity's eid hosting the inline form |
477 def form(self): |
482 def form(self): |
478 entity = self._entity() |
483 entity = self._entity() |
479 form = self.vreg['forms'].select('edition', self._cw, |
484 form = self.vreg['forms'].select('edition', self._cw, |
480 entity=entity, |
485 entity=entity, |
481 form_renderer_id='inline', |
486 form_renderer_id='inline', |
482 mainform=False, copy_nav_params=False, |
487 copy_nav_params=False, |
|
488 mainform=False, |
|
489 parent_form=self.pform, |
483 **self.extra_kwargs) |
490 **self.extra_kwargs) |
484 form.parent_form = self.pform |
491 if self.pform is None: |
|
492 form.restore_previous_post(form.session_key()) |
|
493 #assert form.parent_form |
485 self.add_hiddens(form, entity) |
494 self.add_hiddens(form, entity) |
486 return form |
495 return form |
487 |
496 |
488 def cell_call(self, row, col, i18nctx, **kwargs): |
497 def cell_call(self, row, col, i18nctx, **kwargs): |
489 """ |
498 """ |
498 |
507 |
499 def render_form(self, i18nctx, **kwargs): |
508 def render_form(self, i18nctx, **kwargs): |
500 """fetch and render the form""" |
509 """fetch and render the form""" |
501 entity = self._entity() |
510 entity = self._entity() |
502 divid = '%s-%s-%s' % (self.peid, self.rtype, entity.eid) |
511 divid = '%s-%s-%s' % (self.peid, self.rtype, entity.eid) |
503 title = self.req.pgettext(i18nctx, 'This %s' % entity.e_schema) |
512 title = self.form_title(entity, i18nctx) |
504 removejs = self.removejs % (self.peid, self.rtype, entity.eid) |
513 removejs = self.removejs and self.removejs % ( |
|
514 self.peid, self.rtype, entity.eid) |
505 countkey = '%s_count' % self.rtype |
515 countkey = '%s_count' % self.rtype |
506 try: |
516 try: |
507 self._cw.data[countkey] += 1 |
517 self._cw.data[countkey] += 1 |
508 except: |
518 except KeyError: |
509 self._cw.data[countkey] = 1 |
519 self._cw.data[countkey] = 1 |
510 self.w(self.form.form_render( |
520 self.w(self.form.form.render( |
511 divid=divid, title=title, removejs=removejs, i18nctx=i18nctx, |
521 divid=divid, title=title, removejs=removejs, i18nctx=i18nctx, |
512 counter=self.req.data[countkey], **kwargs)) |
522 counter=self.req.data[countkey], **kwargs)) |
|
523 self.w(self.form.render( |
|
524 rendervalues=dict(divid=divid, title=title, removejs=removejs, |
|
525 i18nctx=i18nctx, counter=self._cw.data[countkey]), |
|
526 formvalues=kwargs)) |
|
527 |
|
528 def form_title(self, entity, i18nctx): |
|
529 return self.req.pgettext(i18nctx, 'This %s' % entity.e_schema) |
513 |
530 |
514 def add_hiddens(self, form, entity): |
531 def add_hiddens(self, form, entity): |
515 """to ease overriding (see cubes.vcsfile.views.forms for instance)""" |
532 """to ease overriding (see cubes.vcsfile.views.forms for instance)""" |
516 iid = 'rel-%s-%s-%s' % (self.peid, self.rtype, entity.eid) |
533 iid = 'rel-%s-%s-%s' % (self.peid, self.rtype, entity.eid) |
517 # * str(self.rtype) in case it's a schema object |
534 # * str(self.rtype) in case it's a schema object |
538 """ |
555 """ |
539 __regid__ = 'inline-creation' |
556 __regid__ = 'inline-creation' |
540 __select__ = (match_kwargs('peid', 'rtype') |
557 __select__ = (match_kwargs('peid', 'rtype') |
541 & specified_etype_implements('Any')) |
558 & specified_etype_implements('Any')) |
542 _select_attrs = InlineEntityEditionFormView._select_attrs + ('etype',) |
559 _select_attrs = InlineEntityEditionFormView._select_attrs + ('etype',) |
543 removejs = "removeInlineForm('%s', '%s', '%s')" |
560 |
|
561 @property |
|
562 def removejs(self): |
|
563 entity = self._entity() |
|
564 card = entity.e_schema.role_rproperty(neg_role(self.role), self.rtype, 'cardinality') |
|
565 card = card[self.role == 'object'] |
|
566 # when one is adding an inline entity for a relation of a single card, |
|
567 # the 'add a new xxx' link disappears. If the user then cancel the addition, |
|
568 # we have to make this link appears back. This is done by giving add new link |
|
569 # id to removeInlineForm. |
|
570 if card not in '?1': |
|
571 return "removeInlineForm('%s', '%s', '%s')" |
|
572 divid = "addNew%s%s%s:%s" % (self.etype, self.rtype, self.role, self.peid) |
|
573 return "removeInlineForm('%%s', '%%s', '%%s', '%s')" % divid |
544 |
574 |
545 @cached |
575 @cached |
546 def _entity(self): |
576 def _entity(self): |
547 try: |
577 try: |
548 cls = self._cw.vreg['etypes'].etype_class(self.etype) |
578 cls = self._cw.vreg['etypes'].etype_class(self.etype) |