19 from cubicweb import neg_role |
19 from cubicweb import neg_role |
20 from cubicweb.selectors import (match_kwargs, one_line_rset, non_final_entity, |
20 from cubicweb.selectors import (match_kwargs, one_line_rset, non_final_entity, |
21 specified_etype_implements, yes) |
21 specified_etype_implements, yes) |
22 from cubicweb.view import EntityView |
22 from cubicweb.view import EntityView |
23 from cubicweb import tags |
23 from cubicweb import tags |
24 from cubicweb.web import uicfg, stdmsgs, eid_param |
24 from cubicweb.web import uicfg, stdmsgs, eid_param, \ |
|
25 formfields as ff, formwidgets as fw |
25 from cubicweb.web.form import FormViewMixIn, FieldNotFound |
26 from cubicweb.web.form import FormViewMixIn, FieldNotFound |
26 from cubicweb.web.formfields import guess_field |
|
27 from cubicweb.web.formwidgets import Button, SubmitButton, ResetButton |
|
28 from cubicweb.web.views import forms |
27 from cubicweb.web.views import forms |
29 |
28 |
30 _pvdc = uicfg.primaryview_display_ctrl |
29 _pvdc = uicfg.primaryview_display_ctrl |
31 |
30 |
32 |
31 |
34 __regid__ = 'deleteconf' |
33 __regid__ = 'deleteconf' |
35 __select__ = non_final_entity() |
34 __select__ = non_final_entity() |
36 |
35 |
37 domid = 'deleteconf' |
36 domid = 'deleteconf' |
38 copy_nav_params = True |
37 copy_nav_params = True |
39 form_buttons = [Button(stdmsgs.BUTTON_DELETE, cwaction='delete'), |
38 form_buttons = [fw.Button(stdmsgs.BUTTON_DELETE, cwaction='delete'), |
40 Button(stdmsgs.BUTTON_CANCEL, cwaction='cancel')] |
39 fw.Button(stdmsgs.BUTTON_CANCEL, cwaction='cancel')] |
41 @property |
40 @property |
42 def action(self): |
41 def action(self): |
43 return self._cw.build_url('edit') |
42 return self._cw.build_url('edit') |
44 |
43 |
45 def __init__(self, *args, **kwargs): |
44 def __init__(self, *args, **kwargs): |
228 onsubmit = self._onsubmit % event_args |
227 onsubmit = self._onsubmit % event_args |
229 cancelclick = self._cancelclick % (entity.eid, rtype, divid) |
228 cancelclick = self._cancelclick % (entity.eid, rtype, divid) |
230 form = self._cw.vreg['forms'].select( |
229 form = self._cw.vreg['forms'].select( |
231 formid, self._cw, entity=entity, domid='%s-form' % divid, |
230 formid, self._cw, entity=entity, domid='%s-form' % divid, |
232 cssstyle='display: none', onsubmit=onsubmit, action='#', |
231 cssstyle='display: none', onsubmit=onsubmit, action='#', |
233 form_buttons=[SubmitButton(), Button(stdmsgs.BUTTON_CANCEL, |
232 form_buttons=[fw.SubmitButton(), |
234 onclick=cancelclick)], |
233 fw.Button(stdmsgs.BUTTON_CANCEL, onclick=cancelclick)], |
235 **formargs) |
234 **formargs) |
236 form.event_args = event_args |
235 form.event_args = event_args |
237 return form |
236 return form |
238 |
237 |
239 |
238 |
408 |
407 |
409 class TableEditForm(forms.CompositeForm): |
408 class TableEditForm(forms.CompositeForm): |
410 __regid__ = 'muledit' |
409 __regid__ = 'muledit' |
411 domid = 'entityForm' |
410 domid = 'entityForm' |
412 onsubmit = "return validateForm('%s', null);" % domid |
411 onsubmit = "return validateForm('%s', null);" % domid |
413 form_buttons = [SubmitButton(_('validate modifications on selected items')), |
412 form_buttons = [fw.SubmitButton(_('validate modifications on selected items')), |
414 ResetButton(_('revert changes'))] |
413 fw.ResetButton(_('revert changes'))] |
415 |
414 |
416 def __init__(self, req, rset, **kwargs): |
415 def __init__(self, req, rset, **kwargs): |
417 kwargs.setdefault('__redirectrql', rset.printable_rql()) |
416 kwargs.setdefault('__redirectrql', rset.printable_rql()) |
418 super(TableEditForm, self).__init__(req, rset=rset, **kwargs) |
417 super(TableEditForm, self).__init__(req, rset=rset, **kwargs) |
419 for row in xrange(len(self.cw_rset)): |
418 for row in xrange(len(self.cw_rset)): |
448 # telling which form the edit controller should select (eg difffers |
447 # telling which form the edit controller should select (eg difffers |
449 # between html generation / post handling form) |
448 # between html generation / post handling form) |
450 self.w(form.render(formvid='edition')) |
449 self.w(form.render(formvid='edition')) |
451 |
450 |
452 |
451 |
|
452 # inlined form handling ######################################################## |
|
453 |
|
454 class InlinedFormField(ff.Field): |
|
455 def __init__(self, view=None, **kwargs): |
|
456 if view.role == 'object': |
|
457 fieldset = u'%s_object%s' % view.rtype |
|
458 else: |
|
459 fieldset = view.rtype |
|
460 #kwargs.setdefault('fieldset', fieldset) |
|
461 kwargs.setdefault('label', None) |
|
462 super(InlinedFormField, self).__init__(name=view.rtype, role=view.role, |
|
463 eidparam=True, **kwargs) |
|
464 self.view = view |
|
465 |
|
466 def render(self, form, renderer): |
|
467 """render this field, which is part of form, using the given form |
|
468 renderer |
|
469 """ |
|
470 view = self.view |
|
471 i18nctx = 'inlined:%s.%s.%s' % (form.edited_entity.e_schema, |
|
472 view.rtype, view.role) |
|
473 return u'<div class="inline-%s-%s-slot">%s</div>' % ( |
|
474 view.rtype, view.role, |
|
475 view.render(i18nctx=i18nctx, row=view.cw_row, col=view.cw_col)) |
|
476 |
|
477 def form_init(self, form): |
|
478 """method called before by build_context to trigger potential field |
|
479 initialization requiring the form instance |
|
480 """ |
|
481 if self.view.form: |
|
482 self.view.form.build_context(form.formvalues) |
|
483 |
|
484 @property |
|
485 def needs_multipart(self): |
|
486 if self.view.form: |
|
487 # take a look at inlined forms to check (recursively) if they need |
|
488 # multipart handling. |
|
489 return self.view.form.needs_multipart |
|
490 return False |
|
491 |
|
492 def has_been_modified(self, form): |
|
493 return False |
|
494 |
|
495 def process_posted(self, form): |
|
496 pass # handled by the subform |
|
497 |
|
498 |
453 class InlineEntityEditionFormView(FormViewMixIn, EntityView): |
499 class InlineEntityEditionFormView(FormViewMixIn, EntityView): |
454 """ |
500 """ |
455 :attr peid: the parent entity's eid hosting the inline form |
501 :attr peid: the parent entity's eid hosting the inline form |
456 :attr rtype: the relation bridging `etype` and `peid` |
502 :attr rtype: the relation bridging `etype` and `peid` |
457 :attr role: the role played by the `peid` in the relation |
503 :attr role: the role played by the `peid` in the relation |
458 :attr pform: the parent form where this inlined form is being displayed |
504 :attr pform: the parent form where this inlined form is being displayed |
459 """ |
505 """ |
460 __regid__ = 'inline-edition' |
506 __regid__ = 'inline-edition' |
461 __select__ = non_final_entity() & match_kwargs('peid', 'rtype') |
507 __select__ = non_final_entity() & match_kwargs('peid', 'rtype') |
462 |
508 |
463 _select_attrs = ('peid', 'rtype', 'role', 'pform') |
509 _select_attrs = ('peid', 'rtype', 'role', 'pform', 'etype') |
464 removejs = "removeInlinedEntity('%s', '%s', '%s')" |
510 removejs = "removeInlinedEntity('%s', '%s', '%s')" |
465 |
511 |
466 def __init__(self, *args, **kwargs): |
512 def __init__(self, *args, **kwargs): |
467 for attr in self._select_attrs: |
513 for attr in self._select_attrs: |
468 setattr(self, attr, kwargs.pop(attr, None)) |
514 setattr(self, attr, kwargs.pop(attr, None)) |
546 :attr etype: the entity type being created in the inline form |
592 :attr etype: the entity type being created in the inline form |
547 """ |
593 """ |
548 __regid__ = 'inline-creation' |
594 __regid__ = 'inline-creation' |
549 __select__ = (match_kwargs('peid', 'rtype') |
595 __select__ = (match_kwargs('peid', 'rtype') |
550 & specified_etype_implements('Any')) |
596 & specified_etype_implements('Any')) |
551 _select_attrs = InlineEntityEditionFormView._select_attrs + ('etype',) |
|
552 |
597 |
553 @property |
598 @property |
554 def removejs(self): |
599 def removejs(self): |
555 entity = self._entity() |
600 entity = self._entity() |
556 card = entity.e_schema.rdef(self.rtype, neg_role(self.role)).role_cardinality(self.role) |
601 card = entity.e_schema.rdef(self.rtype, neg_role(self.role)).role_cardinality(self.role) |
557 # when one is adding an inline entity for a relation of a single card, |
602 # when one is adding an inline entity for a relation of a single card, |
558 # the 'add a new xxx' link disappears. If the user then cancel the addition, |
603 # the 'add a new xxx' link disappears. If the user then cancel the addition, |
559 # we have to make this link appears back. This is done by giving add new link |
604 # we have to make this link appears back. This is done by giving add new link |
560 # id to removeInlineForm. |
605 # id to removeInlineForm. |
561 if card not in '?1': |
606 if card not in '?1': |
562 return "removeInlineForm('%s', '%s', '%s')" |
607 return "removeInlineForm('%%s', '%%s', '%s', '%%s')" % self.role |
563 divid = "addNew%s%s%s:%s" % (self.etype, self.rtype, self.role, self.peid) |
608 divid = "addNew%s%s%s:%s" % ( |
564 return "removeInlineForm('%%s', '%%s', '%%s', '%s')" % divid |
609 self.etype, self.rtype, self.role, self.peid) |
|
610 return "removeInlineForm('%%s', '%%s', '%s', '%%s', '%s')" % ( |
|
611 self.role, divid) |
565 |
612 |
566 @cached |
613 @cached |
567 def _entity(self): |
614 def _entity(self): |
568 try: |
615 try: |
569 cls = self._cw.vreg['etypes'].etype_class(self.etype) |
616 cls = self._cw.vreg['etypes'].etype_class(self.etype) |