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

zostera / django-bootstrap4 / 14969570320

12 May 2025 10:11AM CUT coverage: 90.734%. Remained the same
14969570320

Pull #818

github

web-flow
Merge 4584b0cfb into f9a52afbd
Pull Request #818: Bump dependabot/fetch-metadata from 2.2.0 to 2.4.0

233 of 302 branches covered (77.15%)

Branch coverage included in aggregate %.

1275 of 1360 relevant lines covered (93.75%)

10.31 hits per line

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

80.45
/src/bootstrap4/forms.py
1
from django.forms import EmailInput, NumberInput, PasswordInput, Textarea, TextInput, URLInput
11✔
2
from django.utils.safestring import mark_safe
11✔
3

4
from .bootstrap import get_bootstrap_setting, get_field_renderer, get_form_renderer, get_formset_renderer
11✔
5
from .exceptions import BootstrapError
11✔
6
from .text import text_value
11✔
7
from .utils import add_css_class, render_tag
11✔
8

9
FORM_GROUP_CLASS = "form-group"
11✔
10

11

12
def render_formset(formset, **kwargs):
11✔
13
    """Render a formset to a Bootstrap layout."""
14
    renderer_cls = get_formset_renderer(**kwargs)
11✔
15
    return renderer_cls(formset, **kwargs).render()
11✔
16

17

18
def render_formset_errors(formset, **kwargs):
11✔
19
    """Render formset errors to a Bootstrap layout."""
20
    renderer_cls = get_formset_renderer(**kwargs)
×
21
    return renderer_cls(formset, **kwargs).render_errors()
×
22

23

24
def render_form(form, **kwargs):
11✔
25
    """Render a form to a Bootstrap layout."""
26
    renderer_cls = get_form_renderer(**kwargs)
11✔
27
    return renderer_cls(form, **kwargs).render()
11✔
28

29

30
def render_form_errors(form, type="all", **kwargs):
11✔
31
    """Render form errors to a Bootstrap layout."""
32
    renderer_cls = get_form_renderer(**kwargs)
×
33
    return renderer_cls(form, **kwargs).render_errors(type)
×
34

35

36
def render_field(field, **kwargs):
11✔
37
    """Render a field to a Bootstrap layout."""
38
    renderer_cls = get_field_renderer(**kwargs)
11✔
39
    return renderer_cls(field, **kwargs).render()
11✔
40

41

42
def render_label(content, label_for=None, label_class=None, label_title=""):
11✔
43
    """Render a label with content."""
44
    attrs = {}
11✔
45
    if label_for:
11✔
46
        attrs["for"] = label_for
11✔
47
    if label_class:
11✔
48
        attrs["class"] = label_class
11✔
49
    if label_title:
11✔
50
        attrs["title"] = label_title
11✔
51
    return render_tag("label", attrs=attrs, content=content)
11✔
52

53

54
def render_button(
11✔
55
    content,
56
    button_type=None,
57
    button_class="btn-primary",
58
    size="",
59
    href="",
60
    name=None,
61
    value=None,
62
    title=None,
63
    extra_classes="",
64
    id="",
65
):
66
    """Render a button with content."""
67
    attrs = {}
11✔
68
    classes = add_css_class("btn", button_class)
11✔
69
    size = text_value(size).lower().strip()
11✔
70
    if size == "xs":
11!
71
        classes = add_css_class(classes, "btn-xs")
×
72
    elif size == "sm" or size == "small":
11!
73
        classes = add_css_class(classes, "btn-sm")
×
74
    elif size == "lg" or size == "large":
11✔
75
        classes = add_css_class(classes, "btn-lg")
11✔
76
    elif size == "md" or size == "medium":
11!
77
        pass
×
78
    elif size:
11!
79
        raise BootstrapError(f'Parameter "size" should be "xs", "sm", "lg" or empty ("{size}" given).')
×
80

81
    if button_type:
11✔
82
        if button_type not in ("submit", "reset", "button", "link"):
11✔
83
            raise BootstrapError(
11✔
84
                'Parameter "button_type" should be "submit", "reset", "button", "link" or empty '
85
                f'("{button_type}" given).'
86
            )
87
        if button_type != "link":
11✔
88
            attrs["type"] = button_type
11✔
89

90
    classes = add_css_class(classes, extra_classes)
11✔
91
    attrs["class"] = classes
11✔
92

93
    if href:
11✔
94
        tag = "a"
11✔
95
        if button_type and button_type != "link":
11✔
96
            raise BootstrapError(f'Button of type "{button_type}" is not allowed a "href" parameter.')
11✔
97
        attrs["href"] = href
11✔
98
        # Specify role for link with button appearance
99
        attrs.setdefault("role", "button")
11✔
100
    else:
101
        tag = "button"
11✔
102

103
    if id:
11!
104
        attrs["id"] = id
×
105
    if name:
11!
106
        attrs["name"] = name
×
107
    if value:
11!
108
        attrs["value"] = value
×
109
    if title:
11!
110
        attrs["title"] = title
×
111
    return render_tag(tag, attrs=attrs, content=mark_safe(content))
11✔
112

113

114
def render_field_and_label(field, label, field_class="", label_for=None, label_class="", layout="", **kwargs):
11✔
115
    """Render a field with its label."""
116
    if layout == "horizontal":
11!
117
        if not label_class:
11!
118
            label_class = get_bootstrap_setting("horizontal_label_class")
11✔
119
        if not field_class:
11!
120
            field_class = get_bootstrap_setting("horizontal_field_class")
11✔
121
        if not label:
11!
122
            label = mark_safe(" ")
11✔
123
        label_class = add_css_class(label_class, "control-label")
11✔
124
    html = field
11✔
125
    if field_class:
11!
126
        html = f'<div class="{field_class}">{html}</div>'
11✔
127
    if label:
11!
128
        html = render_label(label, label_for=label_for, label_class=label_class) + html
11✔
129
    return html
11✔
130

131

132
def render_form_group(content, css_class=FORM_GROUP_CLASS):
11✔
133
    """Render a Bootstrap form group."""
134
    return f'<div class="{css_class}">{content}</div>'
11✔
135

136

137
def is_widget_with_placeholder(widget):
11✔
138
    """
139
    Return whether this widget should have a placeholder.
140

141
    Only text, text area, number, e-mail, url, password, number and derived inputs have placeholders.
142
    """
143
    return isinstance(widget, (TextInput, Textarea, NumberInput, EmailInput, URLInput, PasswordInput))
11✔
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

© 2025 Coveralls, Inc