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" /> |