web/views/ajaxedit.py
changeset 11057 0b59724cb3f2
parent 11052 058bb3dc685f
child 11058 23eb30449fe5
equal deleted inserted replaced
11052:058bb3dc685f 11057:0b59724cb3f2
     1 # copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
       
     2 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
       
     3 #
       
     4 # This file is part of CubicWeb.
       
     5 #
       
     6 # CubicWeb is free software: you can redistribute it and/or modify it under the
       
     7 # terms of the GNU Lesser General Public License as published by the Free
       
     8 # Software Foundation, either version 2.1 of the License, or (at your option)
       
     9 # any later version.
       
    10 #
       
    11 # CubicWeb is distributed in the hope that it will be useful, but WITHOUT
       
    12 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
       
    13 # FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
       
    14 # details.
       
    15 #
       
    16 # You should have received a copy of the GNU Lesser General Public License along
       
    17 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
       
    18 """Set of views allowing edition of entities/relations using ajax"""
       
    19 
       
    20 __docformat__ = "restructuredtext en"
       
    21 
       
    22 from cubicweb import role
       
    23 from cubicweb.view import View
       
    24 from cubicweb.predicates import match_form_params, match_kwargs
       
    25 from cubicweb.web import component, stdmsgs, formwidgets as fw
       
    26 
       
    27 class AddRelationView(component.EditRelationMixIn, View):
       
    28     """base class for view which let add entities linked by a given relation
       
    29 
       
    30     subclasses should define at least id, rtype and target class attributes.
       
    31     """
       
    32     __registry__ = 'views'
       
    33     __regid__ = 'xaddrelation'
       
    34     __select__ = (match_form_params('rtype', 'target')
       
    35                   | match_kwargs('rtype', 'target'))
       
    36     cw_property_defs = {} # don't want to inherit this from Box
       
    37     expected_kwargs = form_params = ('rtype', 'target')
       
    38 
       
    39     def cell_call(self, row, col, rtype=None, target=None, etype=None):
       
    40         self.rtype = rtype or self._cw.form['rtype']
       
    41         self.target = target or self._cw.form['target']
       
    42         self.etype = etype or self._cw.form.get('etype')
       
    43         entity = self.cw_rset.get_entity(row, col)
       
    44         rschema = self._cw.vreg.schema.rschema(self.rtype)
       
    45         if not self.etype:
       
    46             if self.target == 'object':
       
    47                 etypes = rschema.objects(entity.e_schema)
       
    48             else:
       
    49                 etypes = rschema.subjects(entity.e_schema)
       
    50             if len(etypes) == 1:
       
    51                 self.etype = etypes[0]
       
    52         self.w(u'<div id="%s">' % self.domid)
       
    53         self.w(u'<h1>%s</h1>' % self._cw._('relation %(relname)s of %(ent)s')
       
    54                % {'relname': rschema.display_name(self._cw, role(self)),
       
    55                   'ent': entity.view('incontext')})
       
    56         self.w(u'<ul class="list-unstyled">')
       
    57         for boxitem in self.unrelated_boxitems(entity):
       
    58             self.w('<li>%s</li>' % boxitem)
       
    59         self.w(u'</ul></div>')
       
    60 
       
    61     def unrelated_entities(self, entity):
       
    62         """returns the list of unrelated entities
       
    63 
       
    64         if etype is not defined on the Box's class, the default
       
    65         behaviour is to use the entity's appropraite vocabulary function
       
    66         """
       
    67         # use entity.unrelated if we've been asked for a particular etype
       
    68         if getattr(self, 'etype', None):
       
    69             rset = entity.unrelated(self.rtype, self.etype, role(self),
       
    70                                     ordermethod='fetch_order')
       
    71             self.paginate(self._cw, rset=rset, w=self.w)
       
    72             return rset.entities()
       
    73         super(AddRelationView, self).unrelated_entities(self)
       
    74 
       
    75 
       
    76 def ajax_composite_form(container, entity, rtype, okjs, canceljs,
       
    77                         entityfkwargs=None):
       
    78     """
       
    79     * if entity is None, edit container (assert container.has_eid())
       
    80     * if entity has not eid, will be created
       
    81     * if container has not eid, will be created (see vcreview InsertionPoint)
       
    82     """
       
    83     req = container._cw
       
    84     parentexists = entity is None or container.has_eid()
       
    85     buttons = [fw.Button(onclick=okjs),
       
    86                fw.Button(stdmsgs.BUTTON_CANCEL, onclick=canceljs)]
       
    87     freg = req.vreg['forms']
       
    88     # main form kwargs
       
    89     mkwargs = dict(action='#', domid='%sForm%s' % (rtype, container.eid),
       
    90                    form_buttons=buttons,
       
    91                    onsubmit='javascript: %s; return false' % okjs)
       
    92     # entity form kwargs
       
    93     # use formtype=inlined to skip the generic relations edition section
       
    94     fkwargs = dict(entity=entity or container, formtype='inlined')
       
    95     if entityfkwargs is not None:
       
    96         fkwargs.update(entityfkwargs)
       
    97     # form values
       
    98     formvalues = {}
       
    99     if entity is not None: # creation
       
   100         formvalues[rtype] = container.eid
       
   101     if parentexists: # creation / edition
       
   102         mkwargs.update(fkwargs)
       
   103         # use formtype=inlined to avoid viewing the relation edition section
       
   104         form = freg.select('edition', req, **mkwargs)
       
   105     else: # creation of both container and comment entities
       
   106         form = freg.select('composite', req, form_renderer_id='default',
       
   107                             **mkwargs)
       
   108         form.add_subform(freg.select('edition', req, entity=container,
       
   109                                       mainform=False, mainentity=True))
       
   110         form.add_subform(freg.select('edition', req, mainform=False, **fkwargs))
       
   111     return form, formvalues