0001-forms-add-option-to-use-select2-autocomplete-on-list.patch
tests/test_fields.py | ||
---|---|---|
270 | 270 |
assert str(form.render()).count('<option value="">Bla bla bla</option>') == 1 # --- |
271 | 271 |
assert str(form.render()).count('<option') == 1 |
272 | 272 | |
273 |
def test_item_render_as_autocomplete(): |
|
274 |
field = fields.ItemField( |
|
275 |
id='1', |
|
276 |
label='Foobar', |
|
277 |
items=['aa', 'ab', 'ac'], |
|
278 |
display_mode='autocomplete') |
|
279 |
form = Form(use_tokens=False) |
|
280 |
field.add_to_form(form) |
|
281 |
assert str(form.render()).count('<option') == 3 |
|
282 |
assert 'select2' in str(form.render()) |
|
283 | ||
273 | 284 |
def test_item_render_as_radio(): |
274 | 285 |
items_kwargs = [] |
275 | 286 |
items_kwargs.append({'items': ['aa', 'ab', 'ac']}) |
wcs/fields.py | ||
---|---|---|
1250 | 1250 |
if len(kwargs['options']) > 3 or length_first_items > 40: |
1251 | 1251 |
# TODO: absence/presence of delimitor should be an option |
1252 | 1252 |
kwargs['delim'] = htmltext('<br />') |
1253 |
elif self.display_mode == 'autocomplete': |
|
1254 |
kwargs['select2'] = True |
|
1253 | 1255 | |
1254 | 1256 |
def get_display_value(self, value): |
1255 | 1257 |
real_value = value |
... | ... | |
1341 | 1343 |
value=self.in_filters, advanced=True) |
1342 | 1344 |
options = [('list', _('List')), |
1343 | 1345 |
('radio', _('Radio buttons')), |
1346 |
('autocomplete', _('Autocomplete')), |
|
1344 | 1347 |
] |
1345 | 1348 |
form.add(RadiobuttonsWidget, 'display_mode', |
1346 | 1349 |
title=_('Display Mode'), |
wcs/qommon/form.py | ||
---|---|---|
1522 | 1522 | |
1523 | 1523 |
def __init__(self, name, value=None, **kwargs): |
1524 | 1524 |
self.options_with_attributes = kwargs.pop('options_with_attributes', None) |
1525 |
self.select2 = kwargs.pop('select2', None) |
|
1525 | 1526 |
super(SingleSelectHintWidget, self).__init__(name, value=value, **kwargs) |
1526 | 1527 | |
1528 |
def add_media(self): |
|
1529 |
if self.select2: |
|
1530 |
get_response().add_javascript(['jquery.js', '../../i18n.js', 'qommon.forms.js', 'select2.js']) |
|
1531 |
get_response().add_css_include('../js/select2/select2.css') |
|
1532 | ||
1527 | 1533 |
def separate_hint(self): |
1528 |
return (self.hint and len(self.hint) > 80) |
|
1534 |
return (self.hint and len(self.hint) > 80) or self.select2
|
|
1529 | 1535 | |
1530 | 1536 |
def get_options(self): |
1531 | 1537 |
if self.options_with_attributes: |
wcs/qommon/static/js/qommon.forms.js | ||
---|---|---|
126 | 126 |
$('form div[data-live-source]').parents('form').trigger('wcs:change'); |
127 | 127 | |
128 | 128 |
/* searchable select */ |
129 |
$('select[data-autocomplete]').each(function(i, elem) { |
|
130 |
var required = $(elem).data('required'); |
|
131 |
var options = { |
|
132 |
language: { |
|
133 |
errorLoading: function() { return WCS_I18N.s2_errorloading; }, |
|
134 |
noResults: function () { return WCS_I18N.s2_nomatches; }, |
|
135 |
inputTooShort: function (input, min) { return WCS_I18N.s2_tooshort; }, |
|
136 |
loadingMore: function () { return WCS_I18N.s2_loadmore; }, |
|
137 |
searching: function () { return WCS_I18N.s2_searching; } |
|
138 |
} |
|
139 |
}; |
|
140 |
if (!required) { |
|
141 |
options.placeholder = '...'; |
|
142 |
options.allowClear = true; |
|
143 |
} |
|
144 |
$(elem).select2(options); |
|
145 |
}); |
|
146 | ||
147 |
/* searchable select using a data source */ |
|
129 | 148 |
$('select[data-select2-url]').each(function(i, elem) { |
130 | 149 |
var required = $(elem).data('required'); |
131 | 150 |
// create an additional hidden field to hold the label of the selected |
wcs/qommon/templates/qommon/forms/widgets/select.html | ||
---|---|---|
1 | 1 |
{% extends "qommon/forms/widget.html" %} |
2 | 2 |
{% block widget-control %} |
3 | 3 |
<select id="form_{{widget.name}}" name="{{widget.name}}" |
4 |
{% if widget.select2 %}data-autocomplete="true"{% endif %} |
|
5 |
{% if widget.required %}data-required="true"{% endif %} |
|
4 | 6 |
{% for attr in widget.attrs.items %}{{attr.0}}="{{attr.1}}"{% endfor %}> |
5 | 7 |
{% if not widget.separate_hint and widget.hint %} |
6 | 8 |
<option value="">{{ widget.hint }}</option> |
7 |
- |