Commit 5c8071b1 authored by Sylvain Thénault's avatar Sylvain Thénault
Browse files

Override autoform and ajax function retrieving inline creation form to propagate container's eid

Monkey-patch autoform to add an hidden input on the main form (we can't use
'formtype' since it's not appropriate (may be either 'main' or 'inlined'),
rather check if 'peid' is in kwargs to detect if this is the root form or a sub
form.

Then, propagate value found there as a form param when calling the ajax function
to render an inline creation form. Overriding is not necessary for edition form,
since in that case we already have the information.

Doing so allows to simplify the parent_and_container implementation, and some
place are we can now expect the container to be always detectable.
parent ee6b7e0d1c52
// overwrite CW's addInlineCreationForm function to propagate container eid information
function addInlineCreationForm(peid, petype, ttype, rtype, role, i18nctx, insertBefore) {
insertBefore = insertBefore || cw.getNode('add' + rtype + ':' + peid + 'link').parentNode;
var ceid = $('#sedaContainerEID');
if (ceid.length == 1) {
form = {'sedaContainerEID': ceid.attr('value')}
} else {
form = null;
}
var args = ajaxFuncArgs('inline_creation_form', form, peid, petype, ttype, rtype, role, i18nctx);
var d = loadRemote(AJAX_BASE_URL, args);
d.addCallback(function(response) {
var dom = getDomFromResponse(response);
loadAjaxHtmlHead(dom);
var form = jQuery(dom);
form.css('display', 'none');
form.insertBefore(insertBefore).slideDown('fast');
updateInlinedEntitiesCounters(rtype, role);
reorderTabindex(null, $(insertBefore).closest('form')[0]);
jQuery(cw).trigger('inlinedform-added', form);
// if the inlined form contains a file input, we must force
// the form enctype to multipart/form-data
if (form.find('input:file').length) {
// NOTE: IE doesn't support dynamic enctype modification, we have
// to set encoding too.
form.closest('form').attr('enctype', 'multipart/form-data').attr('encoding', 'multipart/form-data');
}
_postAjaxLoad(dom);
});
d.addErrback(function(xxx) {
cw.log('xxx =', xxx);
});
}
......@@ -48,24 +48,10 @@ def parent_and_container(entity):
# ajax created form
try:
parent_eid = int(json.loads(req.form['arg'][0]))
except KeyError:
# direct inlined form (not through ajax) - eid may not be the direct parent, but
# this is enough to get the container
try:
eid = int(req.form['eid'])
except KeyError:
# unable to get parent eid for now :(
return None, None
else:
ancestor = req.entity_from_eid(eid)
icontainer = ancestor.cw_adapt_to('IContainer')
if icontainer is None:
container = ancestor.cw_adapt_to('IContained').container
else:
container = icontainer.container
# unable to get parent eid for now :(
except (KeyError, ValueError):
if 'sedaContainerEID' in req.form:
container = req.entity_from_eid(int(req.form['sedaContainerEID']))
return None, container
except ValueError:
# unable to get parent eid for now :(
return None, None
parent = req.entity_from_eid(parent_eid)
......
......@@ -8577,6 +8577,3 @@ msgstr ""
#, python-brace-format
msgid "you must specify a scheme for {0} to select a value"
msgstr ""
msgid "you must validate first to select a possible value"
msgstr ""
......@@ -8598,5 +8598,3 @@ msgstr "sans date de départ"
msgid "you must specify a scheme for {0} to select a value"
msgstr "spécifiez d'abord un vocabulaire pour \"{0}\""
msgid "you must validate first to select a possible value"
msgstr "validez avant de pouvoir sélectionner une valeur"
......@@ -195,7 +195,7 @@ class ParentAndContainerTC(CubicWebTC):
def test_eid(self):
with self.admin_access.web_request() as req:
transfer = req.cnx.create_entity('SEDAArchiveTransfer', title=u'test profile')
req.form['eid'] = text_type(transfer.eid)
req.form['sedaContainerEID'] = text_type(transfer.eid)
parent, container = parent_and_container(attrdict(_cw=req, has_eid=lambda: False))
self.assertIsNone(parent)
self.assertEqual(container.eid, transfer.eid)
......
......@@ -46,28 +46,26 @@ class ContainedRelationFacetWidget(rwdg.RelationFacetWidget):
def _render_triggers(self, w, domid, form, field, rtype):
parent, container = parent_and_container(form.edited_entity)
assert container is not None
req = form._cw
if container is None:
w(req._('you must validate first to select a possible value'))
else:
try:
constraint = RDEF_CONSTRAINTS[(form.edited_entity.cw_etype, field.name)]
except KeyError:
constraint = RDEF_CONSTRAINTS[field.name]
rql = 'Any CS WHERE ' + (
constraint.replace('O in_scheme CS, ', '').replace(', S container AT', ''))
rql += ', AT eid %(at)s'
if not req.execute(rql, {'at': container.eid}):
scheme_relations = [x for x in rql.split() if x.startswith('seda_')]
if len(scheme_relations) == 1:
scheme_relation = req._(scheme_relations[0])
else:
scheme_relation = req.__(scheme_relations[0] + '_object')
w(req._('you must specify a scheme for {0} to select a value').format(
scheme_relation))
try:
constraint = RDEF_CONSTRAINTS[(form.edited_entity.cw_etype, field.name)]
except KeyError:
constraint = RDEF_CONSTRAINTS[field.name]
rql = 'Any CS WHERE ' + (
constraint.replace('O in_scheme CS, ', '').replace(', S container AT', ''))
rql += ', AT eid %(at)s'
if not req.execute(rql, {'at': container.eid}):
scheme_relations = [x for x in rql.split() if x.startswith('seda_')]
if len(scheme_relations) == 1:
scheme_relation = req._(scheme_relations[0])
else:
return super(ContainedRelationFacetWidget, self)._render_triggers(
w, domid, form, field, rtype)
scheme_relation = req.__(scheme_relations[0] + '_object')
w(req._('you must specify a scheme for {0} to select a value').format(
scheme_relation))
else:
return super(ContainedRelationFacetWidget, self)._render_triggers(
w, domid, form, field, rtype)
def trigger_search_url(self, entity, url_params):
"""Overriden to add information about who is the container
......
......@@ -39,10 +39,7 @@ def rule_ref_vocabulary(form, field):
"""
req = form._cw
parent, container = parent_and_container(form.edited_entity)
if container is None:
# missing parent information
msg = req._('you must validate first to select a possible value')
return [(msg, INTERNAL_FIELD_VALUE)]
assert container is not None
parent_etype = form.edited_entity.cw_etype
if parent_etype == 'SEDARefNonRuleId':
if parent is not None:
......
......@@ -17,6 +17,36 @@
from logilab.common.decorators import monkeypatch
from cubicweb.web.views import autoform # noqa
# monkey patch autoform to add an hidden field container the parent container eid that may be used
# in parent_and_container (see entities/__init__.py)
orig_autoform_init = autoform.AutomaticEntityForm.__init__
@monkeypatch(autoform.AutomaticEntityForm)
def __init__(self, *args, **kwargs):
orig_autoform_init(self, *args, **kwargs)
if 'peid' not in kwargs: # main form
parent = None
if self.edited_entity.has_eid():
parent = self.edited_entity
elif '__linkto' in self._cw.form:
parent = self._cw.entity_from_eid(int(self._cw.form['__linkto'].split(':')[1]))
if parent is not None:
if parent.cw_adapt_to('IContainer') is not None:
container = parent
else:
container = parent.cw_adapt_to('IContained').container
self.add_hidden(name='sedaContainerEID', value=container.eid, id='sedaContainerEID')
# this js file contains a custom implementation of addInlineCreationForm that propage
# sedaContainerEID
autoform.AutomaticEntityForm.needs_js += ('cubes.seda.form.js',)
# fix unexpected redirect after clicking on cancel in reledit ######################################
# (https://www.cubicweb.org/ticket/13120795)
......@@ -82,7 +112,6 @@ def field_by_name(cls_or_self, name, role=None, eschema=None):
# (https://www.cubicweb.org/ticket/15755515)
from logilab.common.decorators import cached # noqa
from cubicweb.web.views import autoform # noqa
autoform.InlineEntityEditionFormView.form_renderer_id = 'inline'
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment