web/formwidgets.py
changeset 4163 b2747ed057e6
parent 4160 3fbdeef9a610
child 4169 341d19ef7b7c
equal deleted inserted replaced
4162:d2663bcf5306 4163:b2747ed057e6
    49         """render the widget for the given `field` of `form`.
    49         """render the widget for the given `field` of `form`.
    50         To override in concrete class
    50         To override in concrete class
    51         """
    51         """
    52         raise NotImplementedError
    52         raise NotImplementedError
    53 
    53 
    54     def _render_attrs(self, form, field):
    54     def values_and_attributes(self, form, field):
    55         """return html tag name, attributes and a list of values for the field
    55         values = field.display_value(form)
    56         """
       
    57         name = form.context[field]['name']
       
    58         values = form.context[field]['value']
       
    59         if not isinstance(values, (tuple, list)):
    56         if not isinstance(values, (tuple, list)):
    60             values = (values,)
    57             values = (values,)
    61         attrs = dict(self.attrs)
    58         attrs = dict(self.attrs)
    62         if self.setdomid:
    59         if self.setdomid:
    63             attrs['id'] = field.dom_id(form)
    60             attrs['id'] = field.dom_id(form)
    64         if self.settabindex and not 'tabindex' in attrs:
    61         if self.settabindex and not 'tabindex' in attrs:
    65             attrs['tabindex'] = form._cw.next_tabindex()
    62             attrs['tabindex'] = form._cw.next_tabindex()
    66         return name, values, attrs
    63         return values, attrs
    67 
    64 
    68     def process_field_data(self, form, field):
    65     def process_field_data(self, form, field):
    69         formkey = form.form_field_name(field)
       
    70         posted = form._cw.form
    66         posted = form._cw.form
    71         return posted.get(formkey)
    67         val = posted.get(field.input_name(form))
       
    68         return val
       
    69 
       
    70     @deprecated('[3.6] use values_and_attributes')
       
    71     def _render_attrs(self, form, field):
       
    72         """return html tag name, attributes and a list of values for the field
       
    73         """
       
    74         values, attrs = self.values_and_attributes(form, field)
       
    75         return field.input_name(form), values, attrs
       
    76 
    72 
    77 
    73 class Input(FieldWidget):
    78 class Input(FieldWidget):
    74     """abstract widget class for <input> tag based widgets"""
    79     """abstract widget class for <input> tag based widgets"""
    75     type = None
    80     type = None
    76 
    81 
    78         """render the widget for the given `field` of `form`.
    83         """render the widget for the given `field` of `form`.
    79 
    84 
    80         Generate one <input> tag for each field's value
    85         Generate one <input> tag for each field's value
    81         """
    86         """
    82         self.add_media(form)
    87         self.add_media(form)
    83         name, values, attrs = self._render_attrs(form, field)
    88         values, attrs = self.values_and_attributes(form, field)
    84         # ensure something is rendered
    89         # ensure something is rendered
    85         if not values:
    90         if not values:
    86             values = (INTERNAL_FIELD_VALUE,)
    91             values = (INTERNAL_FIELD_VALUE,)
    87         inputs = [tags.input(name=field.input_name(form), type=self.type,
    92         inputs = [tags.input(name=field.input_name(form), type=self.type,
    88                              value=value, **attrs)
    93                              value=value, **attrs)
   103     """
   108     """
   104     type = 'password'
   109     type = 'password'
   105 
   110 
   106     def render(self, form, field, renderer):
   111     def render(self, form, field, renderer):
   107         self.add_media(form)
   112         self.add_media(form)
   108         name, values, attrs = self._render_attrs(form, field)
   113         values, attrs = self.values_and_attributes(form, field)
   109         assert len(values) == 1
   114         assert len(values) == 1
   110         id = attrs.pop('id')
   115         id = attrs.pop('id')
   111         inputs = [tags.input(name=field.input_name(form),
   116         inputs = [tags.input(name=field.input_name(form),
   112                              value=values[0], type=self.type, id=id, **attrs),
   117                              value=values[0], type=self.type, id=id, **attrs),
   113                   '<br/>',
   118                   '<br/>',
   140 
   145 
   141 class FileInput(Input):
   146 class FileInput(Input):
   142     """<input type='file'>"""
   147     """<input type='file'>"""
   143     type = 'file'
   148     type = 'file'
   144 
   149 
   145     def _render_attrs(self, form, field):
   150     def values_and_attributes(self, form, field):
   146         # ignore value which makes no sense here (XXX even on form validation error?)
   151         # ignore value which makes no sense here (XXX even on form validation error?)
   147         name, values, attrs = super(FileInput, self)._render_attrs(form, field)
   152         values, attrs = super(FileInput, self).values_and_attributes(form, field)
   148         return name, ('',), attrs
   153         return ('',), attrs
   149 
   154 
   150 
   155 
   151 class HiddenInput(Input):
   156 class HiddenInput(Input):
   152     """<input type='hidden'>"""
   157     """<input type='hidden'>"""
   153     type = 'hidden'
   158     type = 'hidden'
   166 
   171 
   167 class TextArea(FieldWidget):
   172 class TextArea(FieldWidget):
   168     """<textarea>"""
   173     """<textarea>"""
   169 
   174 
   170     def render(self, form, field, renderer):
   175     def render(self, form, field, renderer):
   171         name, values, attrs = self._render_attrs(form, field)
   176         values, attrs = self.values_and_attributes(form, field)
   172         attrs.setdefault('onkeyup', 'autogrow(this)')
   177         attrs.setdefault('onkeyup', 'autogrow(this)')
   173         if not values:
   178         if not values:
   174             value = u''
   179             value = u''
   175         elif len(values) == 1:
   180         elif len(values) == 1:
   176             value = values[0]
   181             value = values[0]
   203     def __init__(self, attrs=None, multiple=False):
   208     def __init__(self, attrs=None, multiple=False):
   204         super(Select, self).__init__(attrs)
   209         super(Select, self).__init__(attrs)
   205         self._multiple = multiple
   210         self._multiple = multiple
   206 
   211 
   207     def render(self, form, field, renderer):
   212     def render(self, form, field, renderer):
   208         name, curvalues, attrs = self._render_attrs(form, field)
   213         curvalues, attrs = self.values_and_attributes(form, field)
   209         if not 'size' in attrs:
   214         if not 'size' in attrs:
   210             attrs['size'] = self._multiple and '5' or '1'
   215             attrs['size'] = self._multiple and '5' or '1'
   211         options = []
   216         options = []
   212         optgroup_opened = False
   217         optgroup_opened = False
   213         for option in field.vocabulary(form):
   218         for option in field.vocabulary(form):
   240     """
   245     """
   241     type = 'checkbox'
   246     type = 'checkbox'
   242     vocabulary_widget = True
   247     vocabulary_widget = True
   243 
   248 
   244     def render(self, form, field, renderer):
   249     def render(self, form, field, renderer):
   245         name, curvalues, attrs = self._render_attrs(form, field)
   250         curvalues, attrs = self.values_and_attributes(form, field)
   246         domid = attrs.pop('id', None)
   251         domid = attrs.pop('id', None)
   247         sep = attrs.pop('separator', u'<br/>\n')
   252         sep = attrs.pop('separator', u'<br/>\n')
   248         options = []
   253         options = []
   249         for i, option in enumerate(field.vocabulary(form)):
   254         for i, option in enumerate(field.vocabulary(form)):
   250             try:
   255             try:
   381         if inputid is not None:
   386         if inputid is not None:
   382             self.attrs['cubicweb:inputid'] = inputid
   387             self.attrs['cubicweb:inputid'] = inputid
   383 
   388 
   384     def render(self, form, field, renderer):
   389     def render(self, form, field, renderer):
   385         self.add_media(form)
   390         self.add_media(form)
   386         attrs = self._render_attrs(form, field)[-1]
   391         attrs = self.values_and_attributes(form, field)[-1]
   387         return tags.div(**attrs)
   392         return tags.div(**attrs)
   388 
   393 
   389 
   394 
   390 class AutoCompletionWidget(TextInput):
   395 class AutoCompletionWidget(TextInput):
   391     """ajax widget for StringField, proposing matching existing values as you
   396     """ajax widget for StringField, proposing matching existing values as you
   405                  'the entity class' % self.__class__.__name__,
   410                  'the entity class' % self.__class__.__name__,
   406                  DeprecationWarning)
   411                  DeprecationWarning)
   407             self.autocomplete_initfunc = None
   412             self.autocomplete_initfunc = None
   408         super(AutoCompletionWidget, self).__init__(*args, **kwargs)
   413         super(AutoCompletionWidget, self).__init__(*args, **kwargs)
   409 
   414 
   410     def _render_attrs(self, form, field):
   415     def values_and_attributes(self, form, field):
   411         name, values, attrs = super(AutoCompletionWidget, self)._render_attrs(form, field)
   416         values, attrs = super(AutoCompletionWidget, self).values_and_attributes(form, field)
   412         init_ajax_attributes(attrs, self.wdgtype, self.loadtype)
   417         init_ajax_attributes(attrs, self.wdgtype, self.loadtype)
   413         # XXX entity form specific
   418         # XXX entity form specific
   414         attrs['cubicweb:dataurl'] = self._get_url(form.edited_entity, field)
   419         attrs['cubicweb:dataurl'] = self._get_url(form.edited_entity, field)
   415         if not values:
   420         if not values:
   416             values = ('',)
   421             values = ('',)
   417         return name, values, attrs
   422         return values, attrs
   418 
   423 
   419     def _get_url(self, entity, field):
   424     def _get_url(self, entity, field):
   420         if self.autocomplete_initfunc is None:
   425         if self.autocomplete_initfunc is None:
   421             # XXX for bw compat
   426             # XXX for bw compat
   422             fname = entity.autocomplete_initfuncs[field.name]
   427             fname = entity.autocomplete_initfuncs[field.name]
   443     """XXX describe me"""
   448     """XXX describe me"""
   444     wdgtype = 'RestrictedSuggestField'
   449     wdgtype = 'RestrictedSuggestField'
   445 
   450 
   446 
   451 
   447 class AddComboBoxWidget(Select):
   452 class AddComboBoxWidget(Select):
   448     def _render_attrs(self, form, field):
   453     def values_and_attributes(self, form, field):
   449         name, values, attrs = super(AddComboBoxWidget, self)._render_attrs(form, field)
   454         values, attrs = super(AddComboBoxWidget, self).values_and_attributes(form, field)
   450         init_ajax_attributes(self.attrs, 'AddComboBox')
   455         init_ajax_attributes(self.attrs, 'AddComboBox')
   451         # XXX entity form specific
   456         # XXX entity form specific
   452         entity = form.edited_entity
   457         entity = form.edited_entity
   453         attrs['cubicweb:etype_to'] = entity.e_schema
   458         attrs['cubicweb:etype_to'] = entity.e_schema
   454         etype_from = entity.e_schema.subjrels[field.name].objects(entity.e_schema)[0]
   459         etype_from = entity.e_schema.subjrels[field.name].objects(entity.e_schema)[0]
   455         attrs['cubicweb:etype_from'] = etype_from
   460         attrs['cubicweb:etype_from'] = etype_from
   456         return name, values, attrs
   461         return values, attrs
   457 
   462 
   458     def render(self, form, field, renderer):
   463     def render(self, form, field, renderer):
   459         return super(AddComboBoxWidget, self).render(form, field, renderer) + u'''
   464         return super(AddComboBoxWidget, self).render(form, field, renderer) + u'''
   460 <div id="newvalue">
   465 <div id="newvalue">
   461   <input type="text" id="newopt" />
   466   <input type="text" id="newopt" />