• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

goinnn / django-multiselectfield / 15537274011

09 Jun 2025 02:43PM UTC coverage: 87.129% (-1.1%) from 88.235%
15537274011

Pull #172

github

web-flow
Merge d3aa062d0 into cf6a60d42
Pull Request #172: Add SortableMultiChoiceField for Ordered Multi-Select Support

45 of 51 new or added lines in 4 files covered. (88.24%)

2 existing lines in 1 file now uncovered.

176 of 202 relevant lines covered (87.13%)

0.87 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

86.84
/multiselectfield/forms/widgets.py
1
# -*- coding: utf-8 -*-
2
# Copyright (c) 2012 by Pablo Martín <goinnn@gmail.com>
3
#
4
# This program is free software: you can redistribute it and/or modify
5
# it under the terms of the GNU Lesser General Public License as published by
6
# the Free Software Foundation, either version 3 of the License, or
7
# (at your option) any later version.
8
#
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU Lesser General Public License for more details.
13
#
14
# You should have received a copy of the GNU Lesser General Public License
15
# along with this programe.  If not, see <https://www.gnu.org/licenses/>.
16
import sys
1✔
17

18
from django import forms
1✔
19

20

21
class SortedCheckboxSelectMultiple(forms.CheckboxSelectMultiple):
1✔
22

23
    def __init__(self, *args, **kwargs):
1✔
24
        super().__init__(*args, **kwargs)
1✔
25
        self.attrs['class'] = 'ui-pre-sortable'
1✔
26

27
    class Media:
1✔
28
        js = (
1✔
29
            'sortmultiselectfield/sortmultiselectfield.js'
30
        )
31
        css = {
1✔
32
            'all': ('sortmultiselectfield/sortmultiselectfield.css',)
33
        }
34

35
    def optgroups(self, name, value, attrs=None):
1✔
36
        """Return a list of optgroups for this widget."""
37
        groups = []
1✔
38
        has_selected = False
1✔
39
        choices = self.choices
1✔
40

41
        def index_of(val, in_list):
1✔
42
            try:
1✔
43
                return in_list.index(val)
1✔
44
            except ValueError:
1✔
45
                return sys.maxsize
1✔
46

47
        choices = sorted(choices, key=lambda choice: index_of(choice[0], value))
1✔
48

49
        for index, (option_value, option_label) in enumerate(choices):
1✔
50
            if option_value is None:
1✔
NEW
51
                option_value = ''
×
52
            subgroup = []
1✔
53
            if isinstance(option_label, (list, tuple)):
1✔
NEW
54
                group_name = option_value
×
NEW
55
                subindex = 0
×
NEW
56
                choices = option_label
×
57
            else:
58
                group_name = None
1✔
59
                subindex = None
1✔
60
                choices = [(option_value, option_label)]
1✔
61
            groups.append((group_name, subgroup, index))
1✔
62

63
            for subvalue, sublabel in choices:
1✔
64
                selected = (not has_selected or self.allow_multiple_selected) and str(
1✔
65
                    subvalue
66
                ) in value
67
                has_selected |= selected
1✔
68
                subgroup.append(
1✔
69
                    self.create_option(
70
                        name,
71
                        subvalue,
72
                        sublabel,
73
                        selected,
74
                        index,
75
                        subindex=subindex,
76
                        attrs=attrs,
77
                    )
78
                )
79
                if subindex is not None:
1✔
NEW
80
                    subindex += 1
×
81
        return groups
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc