--- a/web/views/editforms.py Mon Oct 19 20:22:01 2009 +0200
+++ b/web/views/editforms.py Wed Oct 21 17:32:20 2009 +0200
@@ -19,10 +19,9 @@
from cubicweb import neg_role
from cubicweb.selectors import (match_kwargs, one_line_rset, non_final_entity,
specified_etype_implements, yes)
-from cubicweb.utils import make_uid
from cubicweb.view import EntityView
from cubicweb.common import tags
-from cubicweb.web import INTERNAL_FIELD_VALUE, RequestError, stdmsgs, eid_param
+from cubicweb.web import stdmsgs, eid_param
from cubicweb.web import uicfg
from cubicweb.web.form import FormViewMixIn, FieldNotFound
from cubicweb.web.formfields import guess_field
@@ -111,14 +110,103 @@
# FIXME editableField class could be toggleable from userprefs
_onclick = u"showInlineEditionForm(%(eid)s, '%(rtype)s', '%(divid)s')"
- _defaultlandingzone = (u'<img title="%(msg)s" '
- 'src="data/accessories-text-editor.png" '
+ _onsubmit = ("return inlineValidateRelationForm('%(rtype)s', '%(role)s', '%(eid)s', "
+ "'%(divid)s', %(reload)s, '%(vid)s', '%(default)s', '%(lzone)s');")
+ _cancelclick = "hideInlineEdit(%s,\'%s\',\'%s\')"
+ _defaultlandingzone = (u'<img title="%(msg)s" src="data/file.gif" '
'alt="%(msg)s"/>')
_landingzonemsg = _('click to edit this field')
# default relation vids according to cardinality
_one_rvid = 'incontext'
_many_rvid = 'csv'
+
+ def cell_call(self, row, col, rtype=None, role='subject',
+ reload=False, # controls reloading the whole page after change
+ rvid=None, # vid to be applied to other side of rtype (non final relations only)
+ default=None, # default value
+ landing_zone=None # prepend value with a separate html element to click onto
+ # (esp. needed when values are links)
+ ):
+ """display field to edit entity's `rtype` relation on click"""
+ assert rtype
+ assert role in ('subject', 'object'), '%s is not an acceptable role value' % role
+ self.req.add_js('cubicweb.edition.js')
+ self.req.add_css('cubicweb.form.css')
+ if default is None:
+ default = xml_escape(self._cw._('<no value>'))
+ schema = self._cw.vreg.schema
+ entity = self.cw_rset.get_entity(row, col)
+ rschema = schema.rschema(rtype)
+ lzone = self._build_landing_zone(landing_zone)
+ # compute value, checking perms, build form
+ if rschema.final:
+ form = self._build_form(entity, rtype, role, 'edition', default, reload, lzone)
+ if not self.should_edit_attribute(entity, rschema, role, form):
+ self.w(entity.printable_value(rtype))
+ return
+ value = entity.printable_value(rtype) or default
+ self.relation_form(lzone, value, form,
+ self._build_renderer(entity, rtype, role))
+ else:
+ if rvid is None:
+ rvid = self._compute_best_vid(entity.e_schema, rschema, role)
+ rset = entity.related(rtype, role)
+ if rset:
+ value = self._cw.view(rvid, rset)
+ else:
+ value = default
+ if not self.should_edit_relation(entity, rschema, role, rvid):
+ if rset:
+ self.w(value)
+ return
+ form = self._build_form(entity, rtype, role, 'base', default, reload, lzone,
+ dict(vid=rvid, lzone=lzone))
+ field = guess_field(entity.e_schema, entity.schema.rschema(rtype), role)
+ form.append_field(field)
+ self.relation_form(lzone, value, form,
+ self._build_renderer(entity, rtype, role))
+
+ def should_edit_attribute(self, entity, rschema, role, form):
+ rtype = str(rschema)
+ ttype = rschema.targets(entity.id, role)[0]
+ afs = uicfg.autoform_section.etype_get(entity.id, rtype, role, ttype)
+ if 'main_hidden' in afs or not entity.has_perm('update'):
+ return False
+ try:
+ form.field_by_name(rtype, role)
+ except FieldNotFound:
+ return False
+ return True
+
+ def should_edit_relation(self, entity, rschema, role, rvid):
+ if ((role == 'subject' and not rschema.has_perm(self._cw, 'add',
+ fromeid=entity.eid))
+ or
+ (role == 'object' and not rschema.has_perm(self._cw, 'add',
+ toeid=entity.eid))):
+ return False
+ return True
+
+ def relation_form(self, lzone, value, form, renderer):
+ """xxx-reledit div (class=field)
+ +-xxx div (class="editableField")
+ | +-landing zone
+ +-xxx-value div
+ +-xxx-form div
+ """
+ w = self.w
+ divid = form.event_args['divid']
+ w(u'<div id="%s-reledit" class="field">' % form.event_args['divid'])
+ w(u'<div id="%s" class="editableField" onclick="%s" title="%s">' % (
+ divid, xml_escape(self._onclick % form.event_args),
+ self.req._(self._landingzonemsg)))
+ w(lzone)
+ w(u'</div>')
+ w(u'<div id="%s-value" class="editableFieldValue">%s</div>' % (divid, value))
+ w(form.form_render(renderer=renderer))
+ w(u'</div>')
+
def _compute_best_vid(self, eschema, rschema, role):
if eschema.cardinality(rschema, role) in '+*':
return self._many_rvid
@@ -134,139 +222,45 @@
display_help=False, table_class='',
button_bar_class='buttonbar', display_progress_div=False)
- def _build_form(self, entity, rtype, role, default, onsubmit, reload,
- extradata=None, **formargs):
- divid = 'd%s' % make_uid('%s-%s' % (rtype, entity.eid))
- event_data = {'divid' : divid, 'eid' : entity.eid, 'rtype' : rtype,
- 'reload' : dumps(reload), 'default' : default}
+ def _build_args(self, entity, rtype, role, formid, default, reload, lzone,
+ extradata=None):
+ divid = '%s-%s-%s' % (rtype, role, entity.eid)
+ event_args = {'divid' : divid, 'eid' : entity.eid, 'rtype' : rtype,
+ 'reload' : dumps(reload), 'default' : default, 'role' : role, 'vid' : u'',
+ 'lzone' : lzone}
if extradata:
- event_data.update(extradata)
- onsubmit %= event_data
- cancelclick = "hideInlineEdit(%s,\'%s\',\'%s\')" % (entity.eid, rtype,
- divid)
+ event_args.update(extradata)
+ return divid, event_args
+
+ def _build_form(self, entity, rtype, role, formid, default, reload, lzone,
+ extradata=None, **formargs):
+ divid, event_args = self._build_args(entity, rtype, role, formid, default,
+ reload, lzone, extradata)
+ onsubmit = self._onsubmit % event_args
+ cancelclick = self._cancelclick % (entity.eid, rtype, divid)
form = self._cw.vreg['forms'].select(
- 'edition', self._cw, entity=entity, domid='%s-form' % divid,
+ formid, self._cw, entity=entity, domid='%s-form' % divid,
cssstyle='display: none', onsubmit=onsubmit, action='#',
- display_fields=[(rtype, role)],
form_buttons=[SubmitButton(), Button(stdmsgs.BUTTON_CANCEL,
onclick=cancelclick)],
**formargs)
- form.event_data = event_data
+ form.event_args = event_args
return form
- def cell_call(self, row, col, rtype=None, role='subject',
- reload=False, # controls reloading the whole page after change
- rvid=None, # vid to be applied to other side of rtype (non final relations only)
- default=None, # default value
- landing_zone=None # prepend value with a separate html element to click onto
- # (esp. needed when values are links)
- ):
- """display field to edit entity's `rtype` relation on click"""
- assert rtype
- assert role in ('subject', 'object')
- if default is None:
- default = xml_escape(self._cw._('<no value>'))
- schema = self._cw.vreg.schema
- entity = self.cw_rset.get_entity(row, col)
- rschema = schema.rschema(rtype)
- lzone = self._build_landing_zone(landing_zone)
- # compute value, checking perms, build form
- if rschema.final:
- onsubmit = ("return inlineValidateAttributeForm('%(rtype)s', '%(eid)s', '%(divid)s', "
- "%(reload)s, '%(default)s');")
- form = self._build_form(
- entity, rtype, role, default, onsubmit, reload)
- if not self.should_edit_attribute(entity, rschema, role, form):
- self.w(entity.printable_value(rtype))
- return
- value = entity.printable_value(rtype) or default
- self.attribute_form(lzone, value, form,
- self._build_renderer(entity, rtype, role))
- else:
- if rvid is None:
- rvid = self._compute_best_vid(entity.e_schema, rschema, role)
- rset = entity.related(rtype, role)
- if rset:
- value = self._cw.view(rvid, rset)
- else:
- value = default
- if not self.should_edit_relation(entity, rschema, role, rvid):
- if rset:
- self.w(value)
- return
- onsubmit = ("return inlineValidateRelationForm('%(rtype)s', '%(role)s', '%(eid)s', "
- "'%(divid)s', %(reload)s, '%(vid)s', '%(default)s', '%(lzone)s');")
- form = self._build_form(
- entity, rtype, role, default, onsubmit, reload,
- dict(vid=rvid, role=role, lzone=lzone))
- self.relation_form(lzone, value, form,
- self._build_renderer(entity, rtype, role))
-
- def should_edit_attribute(self, entity, rschema, role, form):
- rtype = str(rschema)
- ttype = rschema.targets(entity.__regid__, role)[0]
- afs = uicfg.autoform_section.etype_get(entity.__regid__, rtype, role, ttype)
- if 'main_hidden' in afs or not entity.has_perm('update'):
- self.w(entity.printable_value(rtype))
- return False
- try:
- field = form.field_by_name(rtype, role)
- except FieldNotFound:
- self.w(entity.printable_value(rtype))
- return False
- return True
-
- def should_edit_relation(self, entity, rschema, role, rvid):
- if ((role == 'subject' and not rschema.has_perm(self._cw, 'add',
- fromeid=entity.eid))
- or
- (role == 'object' and not rschema.has_perm(self._cw, 'add',
- toeid=entity.eid))):
- self.wview(rvid, entity.related(str(rschema), role), 'null')
- return False
- return True
-
- def attribute_form(self, lzone, value, form, renderer):
- """div (class=field)
- +-xxx div
- | +-xxx div (class=editableField)
- | | +-landing zone
- | +-value-xxx div
- | +-value
- +-form-xxx div
- """
- w = self.w
- w(u'<div class="field">')
- w(u'<div id="%s" style="display: inline">' % form.event_data['divid'])
- w(tags.div(lzone, klass='editableField',
- onclick=self._onclick % form.event_data))
- w(u'<div id="value-%s" style="display: inline">%s</div>' %
- (form.event_data['divid'], value))
- w(u'</div>')
- w(form.form_render(renderer=renderer))
- w(u'</div>')
-
- def relation_form(self, lzone, value, form, renderer):
- """xxx-reledit div (class=field)
- +-xxx div (class="editableField")
- | +-landing zone
- +-value
- +-form-xxx div
- """
- w = self.w
- w(u'<div id="%s-reledit" class="field">' % form.event_data['divid'])
- w(tags.div(lzone, klass='editableField', id=form.event_data['divid'],
- onclick=self._onclick % form.event_data))
- w(value)
- w(form.form_render(renderer=renderer))
- w(u'</div>')
-
+class DummyForm(object):
+ __slots__ = ('event_args',)
+ def form_render(self, **_args):
+ return u''
+ def append_field(self, *args):
+ pass
class AutoClickAndEditFormView(ClickAndEditFormView):
"""same as ClickAndEditFormView but checking if the view *should* be applied
by checking uicfg configuration and composite relation property.
"""
__regid__ = 'reledit'
+ _onclick = (u"loadInlineEditionForm(%(eid)s, '%(rtype)s', '%(role)s', "
+ "'%(divid)s', %(reload)s, '%(vid)s', '%(default)s', '%(lzone)s');")
def should_edit_relation(self, entity, rschema, role, rvid):
eschema = entity.e_schema
@@ -283,6 +277,16 @@
return super(AutoClickAndEditFormView, self).should_edit_relation(
entity, rschema, role, rvid)
+ def _build_form(self, entity, rtype, role, formid, default, reload, lzone,
+ extradata=None, **formargs):
+ _divid, event_args = self._build_args(entity, rtype, role, formid, default,
+ reload, lzone, extradata)
+ form = DummyForm()
+ form.event_args = event_args
+ return form
+
+ def _build_renderer(self, entity, rtype, role):
+ pass
class EditionFormView(FormViewMixIn, EntityView):
"""display primary entity edition form"""