Projet

Général

Profil

0001-forms-use-a-template-to-render-checkboxes-widget-483.patch

Frédéric Péters, 30 novembre 2020 13:04

Télécharger (7,67 ko)

Voir les différences:

Subject: [PATCH] forms: use a template to render checkboxes widget (#48387)

 wcs/admin/workflows.py                        |  6 +-
 wcs/qommon/form.py                            | 91 +++++--------------
 .../qommon/forms/widgets/checkboxes.html      | 18 ++++
 3 files changed, 46 insertions(+), 69 deletions(-)
 create mode 100644 wcs/qommon/templates/qommon/forms/widgets/checkboxes.html
wcs/admin/workflows.py
873 873
                workflow=self.objectdef.workflow)
874 874
        display_locations = form.get_widget('display_locations')
875 875
        if display_locations:
876
            del display_locations.widgets[0]  # validation page
876
            # remove validation page from choices
877
            display_locations.options = display_locations.options[1:]
877 878
        return form
878 879

  
879 880

  
......
886 887
        form.remove('prefill')
887 888
        display_locations = form.get_widget('display_locations')
888 889
        if display_locations:
889
            del display_locations.widgets[0]  # validation page
890
            # remove validation page from choices
891
            display_locations.options = display_locations.options[1:]
890 892
        return form
891 893

  
892 894

  
wcs/qommon/form.py
1334 1334
                self.value = None
1335 1335

  
1336 1336

  
1337
class CheckboxesWidget(CompositeWidget):
1337
class CheckboxesWidget(Widget):
1338 1338
    readonly = False
1339 1339
    template_name = 'qommon/forms/widgets/checkboxes.html'
1340 1340
    has_inside_labels = True
1341 1341

  
1342 1342
    def __init__(self, name, value=None, options=None, **kwargs):
1343
        CompositeWidget.__init__(self, name, value, **kwargs)
1344
        self.element_names = collections.OrderedDict()
1345

  
1343
        self.options = options
1344
        self.options_with_attributes = kwargs.pop('options_with_attributes', None)
1345
        self.inline = kwargs.pop('inline', True)
1346
        self.max_choices = int(kwargs.pop('max_choices', 0) or 0)
1346 1347
        if 'title' in kwargs:
1347 1348
            del kwargs['title']
1348 1349
        if 'readonly' in kwargs:
1349 1350
            del kwargs['readonly']
1350 1351
            self.readonly = True
1351
        self.inline = kwargs.get('inline', True)
1352
        self.max_choices = int(kwargs.get('max_choices', 0) or 0)
1352
        super().__init__(name, value, **kwargs)
1353 1353

  
1354
        self.options_with_attributes = kwargs.pop('options_with_attributes', None)
1355
        self.disabled_options = []
1356
        if self.options_with_attributes:
1357
            options = self.options_with_attributes
1354
    def is_selected(self, value):
1355
        return bool(self.value and value in self.value)
1358 1356

  
1357
    def get_options(self):
1358
        options = self.options_with_attributes or self.options
1359 1359
        for i, option in enumerate(options):
1360 1360
            if len(option) == 2:
1361
                key, title = option[:2]
1362
                name = 'element%d' % i
1361
                obj, description, key = (option[0], option[1], str(i))
1363 1362
            else:
1364
                _, title, key  = option[:3]
1365
                name = 'element%s' % str(key)
1366

  
1367
            key = str(key)
1368

  
1369
            element_kwargs = kwargs.copy()
1370
            if self.options_with_attributes and option[-1].get('disabled'):
1371
                element_kwargs['disabled'] = 'disabled'
1372
                self.disabled_options.append(name)
1373
            # don't mark individual checkboxes as required
1374
            element_kwargs.pop('required', None)
1375

  
1376
            if value and key in value:
1377
                checked = True
1378
            else:
1379
                checked = False
1380
            self.add(CheckboxWidget, name, title=title, value=checked, **element_kwargs)
1381
            self.element_names[name] = key
1363
                obj, description, key = option[:3]
1364
            yield {
1365
                'name': self.name + '$element%s' % key,
1366
                'value': obj,
1367
                'label': description,
1368
                'disabled': bool(self.options_with_attributes and option[-1].get('disabled')),
1369
                'selected': self.is_selected(obj)
1370
            }
1382 1371

  
1383 1372
    def _parse(self, request):
1384 1373
        if self.readonly:
1385 1374
            return
1386 1375
        values = []
1387
        for name in self.element_names:
1388
            if name in self.disabled_options:
1376
        for option in self.get_options():
1377
            if option.get('disabled'):
1389 1378
                continue
1390
            value = self.get(name)
1391
            if value is True:
1392
                values.append(self.element_names[name])
1379
            name = option['name']
1380
            if name in request.form and not request.form[name] in (False, '', 'False'):
1381
                values.append(option['value'])
1393 1382
        self.value = values
1394 1383
        if self.required and not self.value:
1395 1384
            self.set_error(self.REQUIRED_ERROR)
......
1398 1387

  
1399 1388
    def set_value(self, value):
1400 1389
        self.value = value
1401
        for name in self.element_names:
1402
            widget = self.get_widget(name)
1403
            if self.element_names[name] in self.value:
1404
                widget.set_value(True)
1405
            else:
1406
                widget.set_value(False)
1407 1390
        self._parsed = True
1408 1391

  
1409
    def has_error(self, request=None):
1410
        return Widget.has_error(self, request=request)
1411

  
1412
    def render_content(self):
1413
        r = TemplateIO(html=True)
1414
        if self.inline:
1415
            r += htmltext('<ul class="inline">')
1416
        else:
1417
            r += htmltext('<ul>')
1418
        for widget in self.get_widgets():
1419
            if widget.attrs and 'disabled' in widget.attrs:
1420
                r += htmltext('<li class="disabled"><label>')
1421
            else:
1422
                r += htmltext('<li><label>')
1423
            if self.readonly:
1424
                widget.attrs['disabled'] = 'disabled'
1425
                if widget.value:
1426
                    r += htmltext('<input type="hidden" name="%s" value="yes" >') % widget.name
1427
                widget.name = widget.name + 'xx'
1428
            r += widget.render_content(standalone=False)
1429
            r += htmltext('<span>%s</span>') % widget.title
1430
            r += htmltext('</label>')
1431
            r += htmltext('</li>')
1432
        r += htmltext('</ul>')
1433
        return r.getvalue()
1434

  
1435 1392

  
1436 1393
class ValidatedStringWidget(StringWidget):
1437 1394
    '''StringWidget which checks the value entered is correct according to a regex'''
wcs/qommon/templates/qommon/forms/widgets/checkboxes.html
1
{% extends "qommon/forms/widget.html" %}
2

  
3
{% block widget-control %}
4
<ul {% if widget.inline %}class="inline"{% endif %}>
5
  {% for option in widget.get_options %}
6
  <li {% if option.disabled %}class="disabled"{% endif %}><label><input
7
   {% if option.selected %}checked="checked"
8
   {% elif widget.readonly or option.disabled %}disabled{% endif %}
9
   {% for attr in widget.attrs.items %}{{attr.0}}="{{attr.1}}"{% endfor %}
10
   type="checkbox"
11
   {% if widget.readonly %}value="yes" disabled
12
   {% else %}name="{{ option.name }}" value="yes">
13
   {% endif %}<span>{{ option.label }}</span></label>
14
   {% if widget.readonly and option.selected %}<input type="hidden" name="{{ option.name }}" value="yes">{% endif %}
15
   </li>
16
{% endfor %}
17
</ul>
18
{% endblock %}
0
-