web/formrenderers.py
branchtls-sprint
changeset 1436 97774eb6443b
parent 1434 42e57dbbc585
child 1576 3bfcf1e4eb26
equal deleted inserted replaced
1435:6cd6172718bb 1436:97774eb6443b
    34     display_fields = None # None -> all fields
    34     display_fields = None # None -> all fields
    35     display_label = True
    35     display_label = True
    36     display_help = True
    36     display_help = True
    37     display_progress_div = True
    37     display_progress_div = True
    38     button_bar_class = u'formButtonBar'
    38     button_bar_class = u'formButtonBar'
    39     
    39 
    40     def __init__(self, **kwargs):
    40     def __init__(self, **kwargs):
    41         if self._set_options(kwargs):
    41         if self._set_options(kwargs):
    42             raise ValueError('unconsumed arguments %s' % kwargs)
    42             raise ValueError('unconsumed arguments %s' % kwargs)
    43 
    43 
    44     def _set_options(self, kwargs):
    44     def _set_options(self, kwargs):
    46             try:
    46             try:
    47                 setattr(self, key, kwargs.pop(key))
    47                 setattr(self, key, kwargs.pop(key))
    48             except KeyError:
    48             except KeyError:
    49                 continue
    49                 continue
    50         return kwargs
    50         return kwargs
    51     
    51 
    52     # renderer interface ######################################################
    52     # renderer interface ######################################################
    53     
    53 
    54     def render(self, form, values):
    54     def render(self, form, values):
    55         self._set_options(values)
    55         self._set_options(values)
    56         form.add_media()
    56         form.add_media()
    57         data = []
    57         data = []
    58         w = data.append
    58         w = data.append
    68         self.render_buttons(w, form)
    68         self.render_buttons(w, form)
    69         w(u'</fieldset>')
    69         w(u'</fieldset>')
    70         w(u'</form>')
    70         w(u'</form>')
    71         errormsg = self.error_message(form)
    71         errormsg = self.error_message(form)
    72         if errormsg:
    72         if errormsg:
    73             data.insert(0, errormsg)          
    73             data.insert(0, errormsg)
    74         return '\n'.join(data)
    74         return '\n'.join(data)
    75 
    75 
    76     def render_label(self, form, field):
    76     def render_label(self, form, field):
    77         label = form.req._(field.label)
    77         label = form.req._(field.label)
    78         attrs = {'for': form.context[field]['id']}
    78         attrs = {'for': form.context[field]['id']}
   106             displayed = req.data['displayederrors']
   106             displayed = req.data['displayederrors']
   107             errors = sorted((field, err) for field, err in errex.errors.items()
   107             errors = sorted((field, err) for field, err in errex.errors.items()
   108                             if not field in displayed)
   108                             if not field in displayed)
   109             if errors:
   109             if errors:
   110                 if len(errors) > 1:
   110                 if len(errors) > 1:
   111                     templstr = '<li>%s</li>\n' 
   111                     templstr = '<li>%s</li>\n'
   112                 else:
   112                 else:
   113                     templstr = '&nbsp;%s\n'
   113                     templstr = '&nbsp;%s\n'
   114                 for field, err in errors:
   114                 for field, err in errors:
   115                     if field is None:
   115                     if field is None:
   116                         errormsg += templstr % err
   116                         errormsg += templstr % err
   118                         errormsg += templstr % '%s: %s' % (req._(field), err)
   118                         errormsg += templstr % '%s: %s' % (req._(field), err)
   119                 if len(errors) > 1:
   119                 if len(errors) > 1:
   120                     errormsg = '<ul>%s</ul>' % errormsg
   120                     errormsg = '<ul>%s</ul>' % errormsg
   121             return u'<div class="errorMessage">%s</div>' % errormsg
   121             return u'<div class="errorMessage">%s</div>' % errormsg
   122         return u''
   122         return u''
   123     
   123 
   124     def open_form(self, form, values):
   124     def open_form(self, form, values):
   125         if form.form_needs_multipart:
   125         if form.form_needs_multipart:
   126             enctype = 'multipart/form-data'
   126             enctype = 'multipart/form-data'
   127         else:
   127         else:
   128             enctype = 'application/x-www-form-urlencoded'
   128             enctype = 'application/x-www-form-urlencoded'
   141         if form.cssclass:
   141         if form.cssclass:
   142             tag += ' class="%s"' % html_escape(form.cssclass)
   142             tag += ' class="%s"' % html_escape(form.cssclass)
   143         if form.cwtarget:
   143         if form.cwtarget:
   144             tag += ' cubicweb:target="%s"' % html_escape(form.cwtarget)
   144             tag += ' cubicweb:target="%s"' % html_escape(form.cwtarget)
   145         return tag + '>'
   145         return tag + '>'
   146     
   146 
   147     def display_field(self, form, field):
   147     def display_field(self, form, field):
   148         return (self.display_fields is None
   148         return (self.display_fields is None
   149                 or field.name in self.display_fields
   149                 or field.name in self.display_fields
   150                 or field.name in form.internal_fields)
   150                 or field.name in form.internal_fields)
   151     
   151 
   152     def render_fields(self, w, form, values):
   152     def render_fields(self, w, form, values):
   153         form.form_build_context(values)
   153         form.form_build_context(values)
   154         fields = self._render_hidden_fields(w, form)
   154         fields = self._render_hidden_fields(w, form)
   155         if fields:
   155         if fields:
   156             self._render_fields(fields, w, form)
   156             self._render_fields(fields, w, form)
   157         self.render_child_forms(w, form, values)
   157         self.render_child_forms(w, form, values)
   158         
   158 
   159     def render_child_forms(self, w, form, values):
   159     def render_child_forms(self, w, form, values):
   160         # render 
   160         # render
   161         for childform in getattr(form, 'forms', []):
   161         for childform in getattr(form, 'forms', []):
   162             self.render_fields(w, childform, values)
   162             self.render_fields(w, childform, values)
   163 
   163 
   164     def _render_hidden_fields(self, w, form):
   164     def _render_hidden_fields(self, w, form):
   165         fields = form.fields[:]
   165         fields = form.fields[:]
   168                 fields.remove(field)
   168                 fields.remove(field)
   169             elif not field.is_visible():
   169             elif not field.is_visible():
   170                 w(field.render(form, self))
   170                 w(field.render(form, self))
   171                 fields.remove(field)
   171                 fields.remove(field)
   172         return fields
   172         return fields
   173     
   173 
   174     def _render_fields(self, fields, w, form):
   174     def _render_fields(self, fields, w, form):
   175         w(u'<table class="attributeForm">')
   175         w(u'<table class="attributeForm">')
   176         for field in fields:
   176         for field in fields:
   177             w(u'<tr>')
   177             w(u'<tr>')
   178             if self.display_label:
   178             if self.display_label:
   201 
   201 
   202     +--------------+--------------+---------+
   202     +--------------+--------------+---------+
   203     | field1 label | field2 label |         |
   203     | field1 label | field2 label |         |
   204     +--------------+--------------+---------+
   204     +--------------+--------------+---------+
   205     | field1 input | field2 input | buttons
   205     | field1 input | field2 input | buttons
   206     +--------------+--------------+---------+ 
   206     +--------------+--------------+---------+
   207     """
   207     """
   208     display_help = False
   208     display_help = False
   209     def _render_fields(self, fields, w, form):
   209     def _render_fields(self, fields, w, form):
   210         w(u'<table border="0">')
   210         w(u'<table border="0">')
   211         w(u'<tr>')
   211         w(u'<tr>')
   212         for field in fields:            
   212         for field in fields:
   213             if self.display_label:
   213             if self.display_label:
   214                 w(u'<th class="labelCol">%s</th>' % self.render_label(form, field))
   214                 w(u'<th class="labelCol">%s</th>' % self.render_label(form, field))
   215             if self.display_help:
   215             if self.display_help:
   216                 w(self.render_help(form, field))
   216                 w(self.render_help(form, field))
   217         # empty slot for buttons
   217         # empty slot for buttons
   218         w(u'<th class="labelCol">&nbsp;</th>')
   218         w(u'<th class="labelCol">&nbsp;</th>')
   219         w(u'</tr>')
   219         w(u'</tr>')
   220         w(u'<tr>')
   220         w(u'<tr>')
   221         for field in fields:                        
   221         for field in fields:
   222             error = form.form_field_error(field)
   222             error = form.form_field_error(field)
   223             if error:
   223             if error:
   224                 w(u'<td class="error" style="width:100%;">')
   224                 w(u'<td class="error" style="width:100%;">')
   225                 w(error)
   225                 w(error)
   226             else:
   226             else:
   234         w(u'</tr>')
   234         w(u'</tr>')
   235         w(u'</table>')
   235         w(u'</table>')
   236 
   236 
   237     def render_buttons(self, w, form):
   237     def render_buttons(self, w, form):
   238         pass
   238         pass
   239     
   239 
   240     
   240 
   241 class EntityCompositeFormRenderer(FormRenderer):
   241 class EntityCompositeFormRenderer(FormRenderer):
   242     """specific renderer for multiple entities edition form (muledit)"""
   242     """specific renderer for multiple entities edition form (muledit)"""
   243     
   243 
   244     def render_fields(self, w, form, values):
   244     def render_fields(self, w, form, values):
   245         if not form.is_subform:
   245         if not form.is_subform:
   246             w(u'<table class="listing">')
   246             w(u'<table class="listing">')
   247         super(EntityCompositeFormRenderer, self).render_fields(w, form, values)
   247         super(EntityCompositeFormRenderer, self).render_fields(w, form, values)
   248         if not form.is_subform:
   248         if not form.is_subform:
   249             w(u'</table>')
   249             w(u'</table>')
   250         
   250 
   251     def _render_fields(self, fields, w, form):
   251     def _render_fields(self, fields, w, form):
   252         if form.is_subform:
   252         if form.is_subform:
   253             entity = form.edited_entity
   253             entity = form.edited_entity
   254             values = form._previous_values
   254             values = form._previous_values
   255             qeid = eid_param('eid', entity.eid)
   255             qeid = eid_param('eid', entity.eid)
   278                            onclick="setCheckboxesState('eid', this.checked)"))
   278                            onclick="setCheckboxesState('eid', this.checked)"))
   279             for field in self.forms[0].fields:
   279             for field in self.forms[0].fields:
   280                 if self.display_field(form, field) and field.is_visible():
   280                 if self.display_field(form, field) and field.is_visible():
   281                     w(u'<th>%s</th>' % form.req._(field.label))
   281                     w(u'<th>%s</th>' % form.req._(field.label))
   282         w(u'</tr>')
   282         w(u'</tr>')
   283             
   283 
   284 
   284 
   285             
   285 
   286 class EntityFormRenderer(FormRenderer):
   286 class EntityFormRenderer(FormRenderer):
   287     """specific renderer for entity edition form (edition)"""
   287     """specific renderer for entity edition form (edition)"""
   288     _options = FormRenderer._options + ('display_relations_form',)
   288     _options = FormRenderer._options + ('display_relations_form',)
   289     display_relations_form = True
   289     display_relations_form = True
   290         
   290 
   291     def render(self, form, values):
   291     def render(self, form, values):
   292         rendered = super(EntityFormRenderer, self).render(form, values)
   292         rendered = super(EntityFormRenderer, self).render(form, values)
   293         return rendered + u'</div>' # close extra div introducted by open_form
   293         return rendered + u'</div>' # close extra div introducted by open_form
   294         
   294 
   295     def open_form(self, form, values):
   295     def open_form(self, form, values):
   296         attrs_fs_label = ('<div class="iformTitle"><span>%s</span></div>'
   296         attrs_fs_label = ('<div class="iformTitle"><span>%s</span></div>'
   297                           % form.req._('main informations'))
   297                           % form.req._('main informations'))
   298         attrs_fs_label += '<div class="formBody">'
   298         attrs_fs_label += '<div class="formBody">'
   299         return attrs_fs_label + super(EntityFormRenderer, self).open_form(form, values)
   299         return attrs_fs_label + super(EntityFormRenderer, self).open_form(form, values)
   300 
   300 
   301     def render_fields(self, w, form, values):
   301     def render_fields(self, w, form, values):
   302         super(EntityFormRenderer, self).render_fields(w, form, values)
   302         super(EntityFormRenderer, self).render_fields(w, form, values)
   303         self.inline_entities_form(w, form)
   303         self.inline_entities_form(w, form)
   304         if form.edited_entity.has_eid() and self.display_relations_table:
   304         if form.edited_entity.has_eid() and self.display_relations_form:
   305             self.relations_form(w, form)
   305             self.relations_form(w, form)
   306 
   306 
   307     def _render_fields(self, fields, w, form):
   307     def _render_fields(self, fields, w, form):
   308         if not form.edited_entity.has_eid() or form.edited_entity.has_perm('update'):
   308         if not form.edited_entity.has_eid() or form.edited_entity.has_perm('update'):
   309             super(EntityFormRenderer, self)._render_fields(fields, w, form)
   309             super(EntityFormRenderer, self)._render_fields(fields, w, form)
   310             
   310 
   311     def render_buttons(self, w, form):
   311     def render_buttons(self, w, form):
   312         if len(form.form_buttons) == 3:
   312         if len(form.form_buttons) == 3:
   313             w("""<table width="100%%">
   313             w("""<table width="100%%">
   314   <tbody>
   314   <tbody>
   315    <tr><td align="center">
   315    <tr><td align="center">
   320    </td></tr>
   320    </td></tr>
   321   </tbody>
   321   </tbody>
   322  </table>""" % tuple(button.render(form) for button in form.form_buttons))
   322  </table>""" % tuple(button.render(form) for button in form.form_buttons))
   323         else:
   323         else:
   324             super(EntityFormRenderer, self).render_buttons(w, form)
   324             super(EntityFormRenderer, self).render_buttons(w, form)
   325         
   325 
   326     def relations_form(self, w, form):
   326     def relations_form(self, w, form):
   327         srels_by_cat = form.srelations_by_category(('generic', 'metadata'), 'add')
   327         srels_by_cat = form.srelations_by_category(('generic', 'metadata'), 'add')
   328         if not srels_by_cat:
   328         if not srels_by_cat:
   329             return u''
   329             return u''
   330         req = form.req
   330         req = form.req
   342                 w(u'<ul>')
   342                 w(u'<ul>')
   343                 for viewparams in related:
   343                 for viewparams in related:
   344                     w(u'<li class="invisible">%s<div id="span%s" class="%s">%s</div></li>'
   344                     w(u'<li class="invisible">%s<div id="span%s" class="%s">%s</div></li>'
   345                       % (viewparams[1], viewparams[0], viewparams[2], viewparams[3]))
   345                       % (viewparams[1], viewparams[0], viewparams[2], viewparams[3]))
   346                 if not form.force_display and form.maxrelitems < len(related):
   346                 if not form.force_display and form.maxrelitems < len(related):
   347                     link = (u'<span class="invisible">' 
   347                     link = (u'<span class="invisible">'
   348                             '[<a href="javascript: window.location.href+=\'&amp;__force_display=1\'">%s</a>]'
   348                             '[<a href="javascript: window.location.href+=\'&amp;__force_display=1\'">%s</a>]'
   349                             '</span>' % form.req._('view all'))
   349                             '</span>' % form.req._('view all'))
   350                     w(u'<li class="invisible">%s</li>' % link)
   350                     w(u'<li class="invisible">%s</li>' % link)
   351                 w(u'</ul>')
   351                 w(u'</ul>')
   352                 w(u'</td>')
   352                 w(u'</td>')
   380         w(u'</th>')
   380         w(u'</th>')
   381         w(u'<td id="unrelatedDivs_%s"></td>' % eid)
   381         w(u'<td id="unrelatedDivs_%s"></td>' % eid)
   382         w(u'</tr>')
   382         w(u'</tr>')
   383         w(u'</table>')
   383         w(u'</table>')
   384         w(u'</fieldset>')
   384         w(u'</fieldset>')
   385         
   385 
   386     def inline_entities_form(self, w, form):
   386     def inline_entities_form(self, w, form):
   387         """create a form to edit entity's inlined relations"""
   387         """create a form to edit entity's inlined relations"""
   388         entity = form.edited_entity
   388         entity = form.edited_entity
   389         __ = form.req.__
   389         __ = form.req.__
   390         for rschema, targettypes, role in form.inlined_relations():
   390         for rschema, targettypes, role in form.inlined_relations():
   399             if form.should_inline_relation_form(rschema, targettype, role):
   399             if form.should_inline_relation_form(rschema, targettype, role):
   400                 w(u'<div id="inline%sslot">' % rschema)
   400                 w(u'<div id="inline%sslot">' % rschema)
   401                 existant = entity.has_eid() and entity.related(rschema)
   401                 existant = entity.has_eid() and entity.related(rschema)
   402                 if existant:
   402                 if existant:
   403                     # display inline-edition view for all existing related entities
   403                     # display inline-edition view for all existing related entities
   404                     w(form.view('inline-edition', existant, rtype=rschema, role=role, 
   404                     w(form.view('inline-edition', existant, rtype=rschema, role=role,
   405                                 ptype=entity.e_schema, peid=entity.eid))
   405                                 ptype=entity.e_schema, peid=entity.eid))
   406                 if role == 'subject':
   406                 if role == 'subject':
   407                     card = rschema.rproperty(entity.e_schema, targettype, 'cardinality')[0]
   407                     card = rschema.rproperty(entity.e_schema, targettype, 'cardinality')[0]
   408                 else:
   408                 else:
   409                     card = rschema.rproperty(targettype, entity.e_schema, 'cardinality')[1]
   409                     card = rschema.rproperty(targettype, entity.e_schema, 'cardinality')[1]
   427                       % (rschema, entity.eid, js, __('add a %s' % targettype)))
   427                       % (rschema, entity.eid, js, __('add a %s' % targettype)))
   428                     w(u'</div>')
   428                     w(u'</div>')
   429                     w(u'<div class="trame_grise">&nbsp;</div>')
   429                     w(u'<div class="trame_grise">&nbsp;</div>')
   430                 w(u'</div>')
   430                 w(u'</div>')
   431 
   431 
   432     
   432 
   433 class EntityInlinedFormRenderer(EntityFormRenderer):
   433 class EntityInlinedFormRenderer(EntityFormRenderer):
   434     """specific renderer for entity inlined edition form
   434     """specific renderer for entity inlined edition form
   435     (inline-[creation|edition])
   435     (inline-[creation|edition])
   436     """
   436     """
   437     def render(self, form, values):
   437     def render(self, form, values):
   452           '[<a href="javascript: %(removejs)s;noop();">%(removemsg)s</a>]</div>'
   452           '[<a href="javascript: %(removejs)s;noop();">%(removemsg)s</a>]</div>'
   453           % values)
   453           % values)
   454         self.render_fields(w, form, values)
   454         self.render_fields(w, form, values)
   455         w(u'</div></div>')
   455         w(u'</div></div>')
   456         return '\n'.join(data)
   456         return '\n'.join(data)
   457     
   457 
   458     def render_fields(self, w, form, values):
   458     def render_fields(self, w, form, values):
   459         form.form_build_context(values)
   459         form.form_build_context(values)
   460         w(u'<fieldset id="fs-%(divid)s">' % values)
   460         w(u'<fieldset id="fs-%(divid)s">' % values)
   461         fields = self._render_hidden_fields(w, form)
   461         fields = self._render_hidden_fields(w, form)
   462         w(u'</fieldset>')
   462         w(u'</fieldset>')
   464         if fields:
   464         if fields:
   465             self._render_fields(fields, w, form)
   465             self._render_fields(fields, w, form)
   466         self.render_child_forms(w, form, values)
   466         self.render_child_forms(w, form, values)
   467         self.inline_entities_form(w, form)
   467         self.inline_entities_form(w, form)
   468         w(u'</fieldset>')
   468         w(u'</fieldset>')
   469     
   469