pax_global_header00006660000000000000000000000064145673013360014522gustar00rootroot0000000000000052 comment=dfaa8133f63aae44310dce6642ec769f9c625809 crispy-bootstrap4-2024.1/000077500000000000000000000000001456730133600152225ustar00rootroot00000000000000crispy-bootstrap4-2024.1/.github/000077500000000000000000000000001456730133600165625ustar00rootroot00000000000000crispy-bootstrap4-2024.1/.github/workflows/000077500000000000000000000000001456730133600206175ustar00rootroot00000000000000crispy-bootstrap4-2024.1/.github/workflows/publish.yml000066400000000000000000000032071456730133600230120ustar00rootroot00000000000000name: Publish Python Package on: release: types: [created] jobs: test: runs-on: ubuntu-latest name: Python ${{ matrix.python-version }} strategy: matrix: python-version: - '3.8' - '3.9' - '3.10' - '3.11' - '3.12' steps: - uses: actions/checkout@v3 - uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} - uses: actions/cache@v3 with: path: ~/.cache/pip key: ${{ runner.os }}-pip-${{ hashFiles('requirements/*.txt') }} restore-keys: | ${{ runner.os }}-pip- - name: Upgrade packaging tools run: python -m pip install --upgrade pip setuptools virtualenv wheel - name: Install dependencies run: python -m pip install --upgrade tox - name: Run tox targets for ${{ matrix.python-version }} run: | ENV_PREFIX=$(tr -C -d "0-9" <<< "${{ matrix.python-version }}") TOXENV=$(tox --listenvs | grep "^py$ENV_PREFIX" | tr '\n' ',') tox - name: Run lint if: ${{ matrix.python-version == '3.9' }} run: | tox -e lint deploy: runs-on: ubuntu-latest needs: [test] steps: - uses: actions/checkout@v3 - name: Set up Python uses: actions/setup-python@v4 with: python-version: "3.10" - name: Install dependencies run: | pip install setuptools wheel twine - name: Publish env: TWINE_USERNAME: __token__ TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }} run: | python setup.py sdist bdist_wheel twine upload dist/* crispy-bootstrap4-2024.1/.github/workflows/test.yml000066400000000000000000000021741456730133600223250ustar00rootroot00000000000000name: CI on: push: branches: - main pull_request: jobs: tests: name: Python ${{ matrix.python-version }} runs-on: ubuntu-latest strategy: matrix: python-version: - '3.8' - '3.9' - '3.10' - '3.11' - '3.12' steps: - uses: actions/checkout@v3 - uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} - uses: actions/cache@v3 with: path: ~/.cache/pip key: ${{ runner.os }}-pip-${{ hashFiles('requirements/*.txt') }} restore-keys: | ${{ runner.os }}-pip- - name: Upgrade packaging tools run: python -m pip install --upgrade pip setuptools virtualenv wheel - name: Install dependencies run: python -m pip install --upgrade tox - name: Run tox targets for ${{ matrix.python-version }} run: | ENV_PREFIX=$(tr -C -d "0-9" <<< "${{ matrix.python-version }}") TOXENV=$(tox --listenvs | grep "^py$ENV_PREFIX" | tr '\n' ',') tox - name: Run lint if: ${{ matrix.python-version == '3.9' }} run: | tox -e lint crispy-bootstrap4-2024.1/.gitignore000066400000000000000000000001631456730133600172120ustar00rootroot00000000000000.venv __pycache__/ *.py[cod] *$py.class venv .eggs .pytest_cache *.egg-info .DS_Store .vscode *python-version .tox crispy-bootstrap4-2024.1/CHANGELOG.md000066400000000000000000000007231456730133600170350ustar00rootroot00000000000000# CHANGELOG FOR CRISPY-BOOTSTRAP4 ## 2024.1 (2024-02-27) * Enabled custom-control checkbox inputs when `show_form_labels` is False. ## 2023.1 (2023-10-16) * Confirmed support for Django 4.2. * Dropped support for Django 3.2, 4.0 and 4.1. * Added support for Django 5.0. * Added support for Python 3.12. * Dropped support for django-crispy-forms 1.x. ## 2022.1 * Initial release to move the template pack from core crispy-forms to a standalone template pack. crispy-bootstrap4-2024.1/LICENSE000066400000000000000000000020601456730133600162250ustar00rootroot00000000000000Copyright (c) 2020 David Smith and contributors. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.crispy-bootstrap4-2024.1/MANIFEST.in000066400000000000000000000003541456730133600167620ustar00rootroot00000000000000include LICENSE include MANIFEST.in include README.md include CHANGELOG.md include tox.ini recursive-include crispy_bootstrap4/templates * recursive-include requirements *.txt recursive-include tests *.html recursive-include tests *.py crispy-bootstrap4-2024.1/README.md000066400000000000000000000015261456730133600165050ustar00rootroot00000000000000# crispy-bootstrap4 [![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/smithdc1/crispy-bootstrap4/blob/main/LICENSE) Bootstrap4 template pack for django-crispy-forms. This template pack was included with the core django-crispy-forms package until version 2.0. ## Installation Install this plugin using `pip`: ```bash $ pip install crispy-bootstrap4 ``` ## Usage You will need to update your project's settings file to add `crispy_forms` and `crispy_bootstrap4` to your projects `INSTALLED_APPS`. Also set `bootstrap4` as and allowed template pack and as the default template pack for your project: ```python INSTALLED_APPS = ( ... "crispy_forms", "crispy_bootstrap4", ... ) CRISPY_ALLOWED_TEMPLATE_PACKS = "bootstrap4" CRISPY_TEMPLATE_PACK = "bootstrap4" ``` crispy-bootstrap4-2024.1/crispy_bootstrap4/000077500000000000000000000000001456730133600207145ustar00rootroot00000000000000crispy-bootstrap4-2024.1/crispy_bootstrap4/__init__.py000066400000000000000000000000001456730133600230130ustar00rootroot00000000000000crispy-bootstrap4-2024.1/crispy_bootstrap4/templates/000077500000000000000000000000001456730133600227125ustar00rootroot00000000000000crispy-bootstrap4-2024.1/crispy_bootstrap4/templates/bootstrap4/000077500000000000000000000000001456730133600250135ustar00rootroot00000000000000crispy-bootstrap4-2024.1/crispy_bootstrap4/templates/bootstrap4/accordion-group.html000066400000000000000000000010711456730133600307730ustar00rootroot00000000000000
{{ fields }}
crispy-bootstrap4-2024.1/crispy_bootstrap4/templates/bootstrap4/accordion.html000066400000000000000000000001121456730133600276340ustar00rootroot00000000000000
{{ content }}
crispy-bootstrap4-2024.1/crispy_bootstrap4/templates/bootstrap4/betterform.html000066400000000000000000000012341456730133600300520ustar00rootroot00000000000000{% for fieldset in form.fieldsets %}
{% if fieldset.legend %} {{ fieldset.legend }} {% endif %} {% if fieldset.description %}

{{ fieldset.description }}

{% endif %} {% for field in fieldset %} {% if field.is_hidden %} {{ field }} {% else %} {% include "bootstrap4/field.html" %} {% endif %} {% endfor %} {% if not forloop.last or not fieldset_open %}
{% endif %} {% endfor %} crispy-bootstrap4-2024.1/crispy_bootstrap4/templates/bootstrap4/display_form.html000066400000000000000000000004101456730133600303640ustar00rootroot00000000000000{% if form.form_html %} {% if include_media %}{{ form.media }}{% endif %} {% if form_show_errors %} {% include "bootstrap4/errors.html" %} {% endif %} {{ form.form_html }} {% else %} {% include "bootstrap4/uni_form.html" %} {% endif %} crispy-bootstrap4-2024.1/crispy_bootstrap4/templates/bootstrap4/errors.html000066400000000000000000000004471456730133600272220ustar00rootroot00000000000000{% if form.non_field_errors %}
{% if form_error_title %}

{{ form_error_title }}

{% endif %}
{% endif %} crispy-bootstrap4-2024.1/crispy_bootstrap4/templates/bootstrap4/errors_formset.html000066400000000000000000000004621456730133600307560ustar00rootroot00000000000000{% if formset.non_form_errors %}
{% if formset_error_title %}

{{ formset_error_title }}

{% endif %}
{% endif %} crispy-bootstrap4-2024.1/crispy_bootstrap4/templates/bootstrap4/field.html000066400000000000000000000113721456730133600267700ustar00rootroot00000000000000{% load crispy_forms_field %} {% if field.is_hidden %} {{ field }} {% else %} {% if field|is_checkbox %}
{% if label_class %}
{% endif %} {% endif %} <{% if tag %}{{ tag }}{% else %}div{% endif %} id="div_{{ field.auto_id }}" class="{% if not field|is_checkbox %}form-group{% if 'form-horizontal' in form_class %} row{% endif %}{% else %}{%if use_custom_control%}{% if tag != 'td' %}custom-control {%endif%} custom-checkbox{% else %}form-check{% endif %}{% endif %}{% if wrapper_class %} {{ wrapper_class }}{% endif %}{% if field.css_classes %} {{ field.css_classes }}{% endif %}"> {% if field.label and not field|is_checkbox and form_show_labels %} {# not field|is_radioselect in row below can be removed once Django 3.2 is no longer supported #} {% endif %} {% if field|is_checkboxselectmultiple %} {% include 'bootstrap4/layout/checkboxselectmultiple.html' %} {% endif %} {% if field|is_radioselect %} {% include 'bootstrap4/layout/radioselect.html' %} {% endif %} {% if not field|is_checkboxselectmultiple and not field|is_radioselect %} {% if field|is_checkbox %} {% if use_custom_control %} {% if tag == 'td' %}
{% endif %} {% if field.errors %} {% crispy_field field 'class' 'custom-control-input is-invalid' %} {% else %} {% crispy_field field 'class' 'custom-control-input' %} {% endif %} {% else %} {% if field.errors %} {% crispy_field field 'class' 'form-check-input is-invalid' %} {% else %} {% crispy_field field 'class' 'form-check-input' %} {% endif %} {% endif %} {% include 'bootstrap4/layout/help_text_and_errors.html' %} {% if use_custom_control and tag == 'td' %}
{% endif %} {% elif field|is_file and use_custom_control %} {% include 'bootstrap4/layout/field_file.html' %} {% else %} {% if field|is_select and use_custom_control %} {% if field.errors %} {% crispy_field field 'class' 'custom-select is-invalid' %} {% else %} {% crispy_field field 'class' 'custom-select' %} {% endif %} {% elif field|is_file %} {% if field.errors %} {% crispy_field field 'class' 'form-control-file is-invalid' %} {% else %} {% crispy_field field 'class' 'form-control-file' %} {% endif %} {% else %} {% if field.errors %} {% crispy_field field 'class' 'form-control is-invalid' %} {% else %} {% crispy_field field 'class' 'form-control' %} {% endif %} {% endif %} {% include 'bootstrap4/layout/help_text_and_errors.html' %}
{% endif %} {% endif %} {% if field|is_checkbox %} {% if label_class %}
{% endif %} {% endif %} {% endif %} crispy-bootstrap4-2024.1/crispy_bootstrap4/templates/bootstrap4/inputs.html000066400000000000000000000006321456730133600272240ustar00rootroot00000000000000{% if inputs %}
{% if label_class %}
{% endif %}
{% for input in inputs %} {% include "bootstrap4/layout/baseinput.html" %} {% endfor %}
{% endif %} crispy-bootstrap4-2024.1/crispy_bootstrap4/templates/bootstrap4/layout/000077500000000000000000000000001456730133600263305ustar00rootroot00000000000000crispy-bootstrap4-2024.1/crispy_bootstrap4/templates/bootstrap4/layout/alert.html000066400000000000000000000004001456730133600303170ustar00rootroot00000000000000 {% if dismiss %}{% endif %} {{ content }} crispy-bootstrap4-2024.1/crispy_bootstrap4/templates/bootstrap4/layout/attrs.html000066400000000000000000000002551456730133600303550ustar00rootroot00000000000000{% for name, value in widget.attrs.items %}{% if value is not False %} {{ name }}{% if value is not True %}="{{ value|stringformat:'s' }}"{% endif %}{% endif %}{% endfor %} crispy-bootstrap4-2024.1/crispy_bootstrap4/templates/bootstrap4/layout/baseinput.html000066400000000000000000000005171456730133600312130ustar00rootroot00000000000000 crispy-bootstrap4-2024.1/crispy_bootstrap4/templates/bootstrap4/layout/button.html000066400000000000000000000000761456730133600305340ustar00rootroot00000000000000 crispy-bootstrap4-2024.1/crispy_bootstrap4/templates/bootstrap4/layout/buttonholder.html000066400000000000000000000003171456730133600317300ustar00rootroot00000000000000
{{ fields_output }}
crispy-bootstrap4-2024.1/crispy_bootstrap4/templates/bootstrap4/layout/checkboxselectmultiple.html000066400000000000000000000035371456730133600337700ustar00rootroot00000000000000{% load crispy_forms_filters %} {% load l10n %}
{% for group, options, index in field|optgroups %} {% if group %}{{ group }}{% endif %} {% for option in options %}
{% if field.errors and forloop.last and not inline_class and forloop.parentloop.last %} {% include 'bootstrap4/layout/field_errors_block.html' %} {% endif %}
{% endfor %} {% endfor %} {% if field.errors and inline_class %}
{# the following input is only meant to allow boostrap to render the error message as it has to be after an invalid input. As the input has no name, no data will be sent. #} {% include 'bootstrap4/layout/field_errors_block.html' %}
{% endif %} {% include 'bootstrap4/layout/help_text.html' %}
checkboxselectmultiple_inline.html000066400000000000000000000014071456730133600352410ustar00rootroot00000000000000crispy-bootstrap4-2024.1/crispy_bootstrap4/templates/bootstrap4/layout{% if field.is_hidden %} {{ field }} {% else %}
{% if field.label %} {% endif %} {% include 'bootstrap4/layout/checkboxselectmultiple.html' %}
{% endif %} crispy-bootstrap4-2024.1/crispy_bootstrap4/templates/bootstrap4/layout/column.html000066400000000000000000000003621456730133600305140ustar00rootroot00000000000000
{{ fields }}
crispy-bootstrap4-2024.1/crispy_bootstrap4/templates/bootstrap4/layout/div.html000066400000000000000000000002551456730133600300020ustar00rootroot00000000000000
{{ fields }}
crispy-bootstrap4-2024.1/crispy_bootstrap4/templates/bootstrap4/layout/field_errors.html000066400000000000000000000003541456730133600316770ustar00rootroot00000000000000{% if form_show_errors and field.errors %} {% for error in field.errors %} {{ error }} {% endfor %} {% endif %} crispy-bootstrap4-2024.1/crispy_bootstrap4/templates/bootstrap4/layout/field_errors_block.html000066400000000000000000000003461456730133600330520ustar00rootroot00000000000000{% if form_show_errors and field.errors %} {% for error in field.errors %}

{{ error }}

{% endfor %} {% endif %} crispy-bootstrap4-2024.1/crispy_bootstrap4/templates/bootstrap4/layout/field_file.html000066400000000000000000000052261456730133600313050ustar00rootroot00000000000000{% load crispy_forms_field %}
{% for widget in field.subwidgets %} {% if widget.data.is_initial %}
{{ widget.data.initial_text }}
{{ field.value }} {% if not widget.data.required %} {% endif %}
{{ widget.data.input_text }}
{% endif %}
{% if not widget.data.is_initial %} {% include 'bootstrap4/layout/help_text_and_errors.html' %} {% endif %} {% if widget.data.is_initial %}
{% include 'bootstrap4/layout/help_text_and_errors.html' %}
{% endif %} {% endfor %}
crispy-bootstrap4-2024.1/crispy_bootstrap4/templates/bootstrap4/layout/field_with_buttons.html000066400000000000000000000021341456730133600331120ustar00rootroot00000000000000{% load crispy_forms_field %} {% if field.label and form_show_labels %} {% endif %}
{% crispy_field field 'class' 'form-control' %} {{ buttons }}
{% include 'bootstrap4/layout/help_text_and_errors.html' %}
crispy-bootstrap4-2024.1/crispy_bootstrap4/templates/bootstrap4/layout/fieldset.html000066400000000000000000000004141456730133600310140ustar00rootroot00000000000000
{% if legend %}{{ legend }}{% endif %} {{ fields }}
crispy-bootstrap4-2024.1/crispy_bootstrap4/templates/bootstrap4/layout/formactions.html000066400000000000000000000006361456730133600315470ustar00rootroot00000000000000 {% if label_class %}
{% endif %}
{{ fields_output }}
crispy-bootstrap4-2024.1/crispy_bootstrap4/templates/bootstrap4/layout/help_text.html000066400000000000000000000004601456730133600312120ustar00rootroot00000000000000{% if field.help_text %} {% if help_text_inline %} {{ field.help_text|safe }} {% else %} {{ field.help_text|safe }} {% endif %} {% endif %} crispy-bootstrap4-2024.1/crispy_bootstrap4/templates/bootstrap4/layout/help_text_and_errors.html000066400000000000000000000005761456730133600334400ustar00rootroot00000000000000{% if help_text_inline and not error_text_inline %} {% include 'bootstrap4/layout/help_text.html' %} {% endif %} {% if error_text_inline %} {% include 'bootstrap4/layout/field_errors.html' %} {% else %} {% include 'bootstrap4/layout/field_errors_block.html' %} {% endif %} {% if not help_text_inline %} {% include 'bootstrap4/layout/help_text.html' %} {% endif %} crispy-bootstrap4-2024.1/crispy_bootstrap4/templates/bootstrap4/layout/inline_field.html000066400000000000000000000024451456730133600316440ustar00rootroot00000000000000{% load crispy_forms_field %} {% if field.is_hidden %} {{ field }} {% else %} {% if field|is_checkbox %}
{% else %}
{% if field.errors %} {% crispy_field field 'placeholder' field.label 'class' 'form-control is-invalid' %} {% else %} {% crispy_field field 'placeholder' field.label 'class' 'form-control' %} {% endif %}
{% endif %} {% endif %} crispy-bootstrap4-2024.1/crispy_bootstrap4/templates/bootstrap4/layout/modal.html000066400000000000000000000012421456730133600303110ustar00rootroot00000000000000 crispy-bootstrap4-2024.1/crispy_bootstrap4/templates/bootstrap4/layout/multifield.html000066400000000000000000000010251456730133600313520ustar00rootroot00000000000000{% load crispy_forms_field %} {% if field.is_hidden %} {{ field }} {% else %} {% if field.label %} {% endif %} {% endif %} crispy-bootstrap4-2024.1/crispy_bootstrap4/templates/bootstrap4/layout/prepended_appended_text.html000066400000000000000000000047231456730133600340760ustar00rootroot00000000000000{% load crispy_forms_field %} {% if field.is_hidden %} {{ field }} {% else %}
{% if field.label and form_show_labels %} {% endif %}
{% if crispy_prepended_text %}
{{ crispy_prepended_text }}
{% endif %} {% if field|is_select and use_custom_control %} {% if field.errors %} {% crispy_field field 'class' 'custom-select is-invalid' %} {% else %} {% crispy_field field 'class' 'custom-select' %} {% endif %} {% else %} {% if field.errors %} {% crispy_field field 'class' 'form-control is-invalid' %} {% else %} {% crispy_field field 'class' 'form-control' %} {% endif %} {% endif %} {% if crispy_appended_text %}
{{ crispy_appended_text }}
{% endif %} {% if error_text_inline %} {% include 'bootstrap4/layout/field_errors.html' %} {% else %} {% include 'bootstrap4/layout/field_errors_block.html' %} {% endif %}
{% if not help_text_inline %} {% include 'bootstrap4/layout/help_text.html' %} {% endif %}
{% endif %} crispy-bootstrap4-2024.1/crispy_bootstrap4/templates/bootstrap4/layout/radioselect.html000066400000000000000000000035271456730133600315230ustar00rootroot00000000000000{% load crispy_forms_filters %} {% load l10n %}
{% for group, options, index in field|optgroups %} {% if group %}{{ group }}{% endif %} {% for option in options %}
{% if field.errors and forloop.last and not inline_class and forloop.parentloop.last %} {% include 'bootstrap4/layout/field_errors_block.html' %} {% endif %}
{% endfor %} {% endfor %} {% if field.errors and inline_class %}
{# the following input is only meant to allow boostrap to render the error message as it has to be after an invalid input. As the input has no name, no data will be sent. #} {% include 'bootstrap4/layout/field_errors_block.html' %}
{% endif %} {% include 'bootstrap4/layout/help_text.html' %}
crispy-bootstrap4-2024.1/crispy_bootstrap4/templates/bootstrap4/layout/radioselect_inline.html000066400000000000000000000013731456730133600330560ustar00rootroot00000000000000{% if field.is_hidden %} {{ field }} {% else %}
{% if field.label %} {% endif %} {% include 'bootstrap4/layout/radioselect.html' %}
{% endif %} crispy-bootstrap4-2024.1/crispy_bootstrap4/templates/bootstrap4/layout/row.html000066400000000000000000000002331456730133600300230ustar00rootroot00000000000000
{{ fields }}
crispy-bootstrap4-2024.1/crispy_bootstrap4/templates/bootstrap4/layout/tab-link.html000066400000000000000000000003131456730133600307140ustar00rootroot00000000000000 crispy-bootstrap4-2024.1/crispy_bootstrap4/templates/bootstrap4/layout/tab.html000066400000000000000000000002431456730133600277630ustar00rootroot00000000000000 {{ links }}
{{ content }}
crispy-bootstrap4-2024.1/crispy_bootstrap4/templates/bootstrap4/layout/uneditable_input.html000066400000000000000000000017611456730133600325560ustar00rootroot00000000000000{% load crispy_forms_field %}
{% if field|is_select and use_custom_control %} {% crispy_field field 'class' 'custom-select' 'disabled' 'disabled' %} {% elif field|is_file %} {% crispy_field field 'class' 'form-control-file' 'disabled' 'disabled' %} {% else %} {% crispy_field field 'class' 'form-control' 'disabled' 'disabled' %} {% endif %} {% include 'bootstrap4/layout/help_text.html' %}
crispy-bootstrap4-2024.1/crispy_bootstrap4/templates/bootstrap4/table_inline_formset.html000066400000000000000000000040411456730133600320640ustar00rootroot00000000000000{% load crispy_forms_tags %} {% load crispy_forms_utils %} {% load crispy_forms_field %} {% specialspaceless %} {% if formset_tag %}
{% endif %} {% if formset_method|lower == 'post' and not disable_csrf %} {% csrf_token %} {% endif %}
{{ formset.management_form|crispy }}
{% if formset.readonly and not formset.queryset.exists %} {% else %} {% for field in formset.forms.0 %} {% if field.label and not field.is_hidden %} {{ field.label }}{% if field.field.required and not field|is_checkbox %}*{% endif %} {% endif %} {% endfor %} {% endif %} {% for field in formset.empty_form %} {% include 'bootstrap4/field.html' with tag="td" form_show_labels=False %} {% endfor %} {% for form in formset %} {% if form_show_errors and not form.is_extra %} {% include "bootstrap4/errors.html" %} {% endif %} {% for field in form %} {% include 'bootstrap4/field.html' with tag="td" form_show_labels=False %} {% endfor %} {% endfor %} {% include "bootstrap4/inputs.html" %} {% if formset_tag %}{% endif %} {% endspecialspaceless %} crispy-bootstrap4-2024.1/crispy_bootstrap4/templates/bootstrap4/uni_form.html000066400000000000000000000004651456730133600275240ustar00rootroot00000000000000{% load crispy_forms_utils %} {% specialspaceless %} {% if include_media %}{{ form.media }}{% endif %} {% if form_show_errors %} {% include "bootstrap4/errors.html" %} {% endif %} {% for field in form %} {% include field_template %} {% endfor %} {% endspecialspaceless %} crispy-bootstrap4-2024.1/crispy_bootstrap4/templates/bootstrap4/uni_formset.html000066400000000000000000000003461456730133600302360ustar00rootroot00000000000000{% with formset.management_form as form %} {% include 'bootstrap4/uni_form.html' %} {% endwith %} {% for form in formset %}
{% include 'bootstrap4/uni_form.html' %}
{% endfor %} crispy-bootstrap4-2024.1/crispy_bootstrap4/templates/bootstrap4/whole_uni_form.html000066400000000000000000000007151456730133600307200ustar00rootroot00000000000000{% load crispy_forms_utils %} {% specialspaceless %} {% if form_tag %}
{% endif %} {% if form_method|lower == 'post' and not disable_csrf %} {% csrf_token %} {% endif %} {% include "bootstrap4/display_form.html" %} {% include "bootstrap4/inputs.html" %} {% if form_tag %}
{% endif %} {% endspecialspaceless %} crispy-bootstrap4-2024.1/crispy_bootstrap4/templates/bootstrap4/whole_uni_formset.html000066400000000000000000000015141456730133600314320ustar00rootroot00000000000000{% load crispy_forms_tags %} {% load crispy_forms_utils %} {% specialspaceless %} {% if formset_tag %}
{% endif %} {% if formset_method|lower == 'post' and not disable_csrf %} {% csrf_token %} {% endif %}
{{ formset.management_form|crispy }}
{% include "bootstrap4/errors_formset.html" %} {% for form in formset %} {% include "bootstrap4/display_form.html" %} {% endfor %} {% if inputs %}
{% for input in inputs %} {% include "bootstrap4/layout/baseinput.html" %} {% endfor %}
{% endif %} {% if formset_tag %}
{% endif %} {% endspecialspaceless %} crispy-bootstrap4-2024.1/requirements/000077500000000000000000000000001456730133600177455ustar00rootroot00000000000000crispy-bootstrap4-2024.1/requirements/lint.txt000066400000000000000000000000231456730133600214470ustar00rootroot00000000000000black flake8 isort crispy-bootstrap4-2024.1/requirements/testing.txt000066400000000000000000000000511456730133600221570ustar00rootroot00000000000000coverage pytest pytest-cov pytest-django crispy-bootstrap4-2024.1/setup.cfg000066400000000000000000000001621456730133600170420ustar00rootroot00000000000000[tool:pytest] DJANGO_SETTINGS_MODULE= tests.test_settings [flake8] max-line-length = 88 [isort] profile = black crispy-bootstrap4-2024.1/setup.py000066400000000000000000000034701456730133600167400ustar00rootroot00000000000000import os from setuptools import setup VERSION = "2024.1" def get_long_description(): with open( os.path.join(os.path.dirname(os.path.abspath(__file__)), "README.md"), encoding="utf8", ) as fp: return fp.read() setup( name="crispy-bootstrap4", description="Bootstrap4 template pack for django-crispy-forms", long_description=get_long_description(), long_description_content_type="text/markdown", author="David Smith", url="https://github.com/django-crispy-forms/crispy-bootstrap4", project_urls={ "Issues": "https://github.com/django-crispy-forms/crispy-bootstrap4/issues", "CI": "https://github.com/django-crispy-forms/crispy-bootstrap4/actions", "Changelog": ( "https://github.com/django-crispy-forms/crispy-bootstrap4/releases" ), }, license="MIT", version=VERSION, packages=["crispy_bootstrap4"], install_requires=["django-crispy-forms>=2.0", "django>=4.2"], python_requires=">=3.8", include_package_data=True, classifiers=[ "Environment :: Web Environment", "Development Status :: 5 - Production/Stable", "Framework :: Django", "Framework :: Django :: 4.2", "Framework :: Django :: 5.0", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Topic :: Internet :: WWW/HTTP", "Topic :: Internet :: WWW/HTTP :: Dynamic Content", "Topic :: Software Development :: Libraries :: Python Modules", ], ) crispy-bootstrap4-2024.1/tests/000077500000000000000000000000001456730133600163645ustar00rootroot00000000000000crispy-bootstrap4-2024.1/tests/__init__.py000066400000000000000000000000001456730133600204630ustar00rootroot00000000000000crispy-bootstrap4-2024.1/tests/conftest.py000066400000000000000000000007221456730133600205640ustar00rootroot00000000000000import pytest from crispy_forms.layout import HTML, Div, Field, Fieldset, Layout, Submit @pytest.fixture def advanced_layout(): return Layout( Div( Div(Div("email")), Div(Field("password1")), Submit("save", "save"), Fieldset( "legend", "first_name", HTML("extra text"), ), Layout("password2"), ), "last_name", ) crispy-bootstrap4-2024.1/tests/forms.py000066400000000000000000000165771456730133600201040ustar00rootroot00000000000000from crispy_forms.helper import FormHelper from django import forms from django.db import models class SampleForm(forms.Form): is_company = forms.CharField( label="company", required=False, widget=forms.CheckboxInput() ) email = forms.EmailField( label="email", max_length=30, required=True, widget=forms.TextInput(), help_text="Insert your email", ) password1 = forms.CharField( label="password", max_length=30, required=True, widget=forms.PasswordInput() ) password2 = forms.CharField( label="re-enter password", max_length=30, required=True, widget=forms.PasswordInput(), ) first_name = forms.CharField( label="first name", max_length=5, required=True, widget=forms.TextInput() ) last_name = forms.CharField( label="last name", max_length=5, required=True, widget=forms.TextInput() ) datetime_field = forms.SplitDateTimeField( label="date time", widget=forms.SplitDateTimeWidget() ) def clean(self): super().clean() password1 = self.cleaned_data.get("password1", None) password2 = self.cleaned_data.get("password2", None) if not password1 and not password2 or password1 != password2: raise forms.ValidationError("Passwords dont match") return self.cleaned_data class SampleForm2(SampleForm): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.helper = FormHelper(self) class CheckboxesSampleForm(forms.Form): checkboxes = forms.MultipleChoiceField( choices=((1, "Option one"), (2, "Option two"), (3, "Option three")), initial=(1,), widget=forms.CheckboxSelectMultiple, ) alphacheckboxes = forms.MultipleChoiceField( choices=( ("option_one", "Option one"), ("option_two", "Option two"), ("option_three", "Option three"), ), initial=("option_two", "option_three"), widget=forms.CheckboxSelectMultiple, ) numeric_multiple_checkboxes = forms.MultipleChoiceField( choices=((1, "Option one"), (2, "Option two"), (3, "Option three")), initial=(1, 2), widget=forms.CheckboxSelectMultiple, ) inline_radios = forms.ChoiceField( choices=( ("option_one", "Option one"), ("option_two", "Option two"), ), widget=forms.RadioSelect, initial="option_two", ) class SelectSampleForm(forms.Form): select = forms.ChoiceField( choices=((1, "Option one"), (2, "Option two"), (3, "Option three")), initial=(1,), widget=forms.Select, ) class CrispyTestModel(models.Model): email = models.CharField(max_length=20) password = models.CharField(max_length=20) class SampleForm3(forms.ModelForm): class Meta: model = CrispyTestModel fields = ["email", "password"] exclude = ["password"] def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.helper = FormHelper(self) class SampleForm4(forms.ModelForm): class Meta: """ before Django1.6, one cannot use __all__ shortcut for fields without getting the following error: django.core.exceptions.FieldError: Unknown field(s) (a, l, _) specified for CrispyTestModel because obviously it casts the string to a set """ model = CrispyTestModel fields = "__all__" # eliminate RemovedInDjango18Warning class SampleForm5(forms.Form): choices = [ (1, 1), (2, 2), (1000, 1000), ] checkbox_select_multiple = forms.MultipleChoiceField( widget=forms.CheckboxSelectMultiple, choices=choices ) radio_select = forms.ChoiceField(widget=forms.RadioSelect, choices=choices) pk = forms.IntegerField() class SampleFormWithMedia(forms.Form): class Media: css = {"all": ("test.css",)} js = ("test.js",) class SampleFormWithMultiValueField(forms.Form): multi = forms.SplitDateTimeField() class CrispyEmptyChoiceTestModel(models.Model): fruit = models.CharField( choices=[("apple", "Apple"), ("pear", "Pear")], null=True, blank=True, max_length=20, ) class SampleForm6(forms.ModelForm): class Meta: """ When allowing null=True in a model field, the corresponding field will have a choice for the empty value. When the form is initialized by an instance with initial value None, this choice should be selected. """ model = CrispyEmptyChoiceTestModel fields = ["fruit"] widgets = {"fruit": forms.RadioSelect()} class SampleForm7(forms.ModelForm): is_company = forms.CharField( label="company", required=False, widget=forms.CheckboxInput() ) password2 = forms.CharField( label="re-enter password", max_length=30, required=True, widget=forms.PasswordInput(), ) class Meta: model = CrispyTestModel fields = ("email", "password", "password2") class SampleForm8(forms.ModelForm): is_company = forms.CharField( label="company", required=False, widget=forms.CheckboxInput() ) password2 = forms.CharField( label="re-enter password", max_length=30, required=True, widget=forms.PasswordInput(), ) class Meta: model = CrispyTestModel fields = ("email", "password2", "password") class FakeFieldFile: """ Quacks like a FieldFile (has a .url and string representation), but doesn't require us to care about storages etc. """ url = "something" def __str__(self): return self.url class FileForm(forms.Form): file_field = forms.FileField(widget=forms.FileInput) clearable_file = forms.FileField( widget=forms.ClearableFileInput, required=False, initial=FakeFieldFile() ) class AdvancedFileForm(forms.Form): file_field = forms.FileField( widget=forms.FileInput(attrs={"class": "my-custom-class"}) ) clearable_file = forms.FileField( widget=forms.ClearableFileInput(attrs={"class": "my-custom-class"}), required=False, initial=FakeFieldFile(), ) class GroupedChoiceForm(forms.Form): choices = [ ( "Audio", [ ("vinyl", "Vinyl"), ("cd", "CD"), ], ), ( "Video", [ ("vhs", "VHS Tape"), ("dvd", "DVD"), ], ), ("unknown", "Unknown"), ] checkbox_select_multiple = forms.MultipleChoiceField( widget=forms.CheckboxSelectMultiple, choices=choices ) radio = forms.MultipleChoiceField(widget=forms.RadioSelect, choices=choices) class CustomRadioSelect(forms.RadioSelect): pass class CustomCheckboxSelectMultiple(forms.CheckboxSelectMultiple): pass class SampleFormCustomWidgets(forms.Form): inline_radios = forms.ChoiceField( choices=( ("option_one", "Option one"), ("option_two", "Option two"), ), widget=CustomRadioSelect, initial="option_two", ) checkboxes = forms.MultipleChoiceField( choices=((1, "Option one"), (2, "Option two"), (3, "Option three")), initial=(1,), widget=CustomCheckboxSelectMultiple, ) crispy-bootstrap4-2024.1/tests/results/000077500000000000000000000000001456730133600200655ustar00rootroot00000000000000crispy-bootstrap4-2024.1/tests/results/bootstrap4/000077500000000000000000000000001456730133600221665ustar00rootroot00000000000000crispy-bootstrap4-2024.1/tests/results/bootstrap4/test_form_helper/000077500000000000000000000000001456730133600255275ustar00rootroot00000000000000bootstrap_form_show_errors_bs4_false.html000066400000000000000000000065071456730133600357640ustar00rootroot00000000000000crispy-bootstrap4-2024.1/tests/results/bootstrap4/test_form_helper
whatever
Insert your email
blabla
foo
bar
whatever
blabla
bootstrap_form_show_errors_bs4_false_lt50.html000066400000000000000000000062441456730133600366260ustar00rootroot00000000000000crispy-bootstrap4-2024.1/tests/results/bootstrap4/test_form_helper
whatever
Insert your email
blabla
foo
bar
whatever
blabla
bootstrap_form_show_errors_bs4_true.html000066400000000000000000000072031456730133600356430ustar00rootroot00000000000000crispy-bootstrap4-2024.1/tests/results/bootstrap4/test_form_helper
whatever
Enter a valid email address.
Insert your email
blabla
Ensure this value has at most 5 characters (it has 19).
foo
bar
Ensure this value has at most 5 characters (it has 18).
whatever
blabla
bootstrap_form_show_errors_bs4_true_lt50.html000066400000000000000000000067401456730133600365140ustar00rootroot00000000000000crispy-bootstrap4-2024.1/tests/results/bootstrap4/test_form_helper
whatever
Enter a valid email address.
Insert your email
blabla
Ensure this value has at most 5 characters (it has 19).
foo
bar
Ensure this value has at most 5 characters (it has 18).
whatever
blabla
test_form_show_errors_non_field_errors_false.html000066400000000000000000000053761456730133600375720ustar00rootroot00000000000000crispy-bootstrap4-2024.1/tests/results/bootstrap4/test_form_helper
Insert your email
test_form_show_errors_non_field_errors_false_lt50.html000066400000000000000000000051551456730133600404310ustar00rootroot00000000000000crispy-bootstrap4-2024.1/tests/results/bootstrap4/test_form_helper
Insert your email
test_form_show_errors_non_field_errors_true.html000066400000000000000000000066021456730133600374500ustar00rootroot00000000000000crispy-bootstrap4-2024.1/tests/results/bootstrap4/test_form_helper
  • Passwords dont match
This field is required. Insert your email
This field is required.
This field is required.
This field is required.
test_form_show_errors_non_field_errors_true_lt50.html000066400000000000000000000063701456730133600403160ustar00rootroot00000000000000crispy-bootstrap4-2024.1/tests/results/bootstrap4/test_form_helper
  • Passwords dont match
This field is required. Insert your email
This field is required.
This field is required.
This field is required.
crispy-bootstrap4-2024.1/tests/results/bootstrap4/test_layout/000077500000000000000000000000001456730133600245425ustar00rootroot00000000000000crispy-bootstrap4-2024.1/tests/results/bootstrap4/test_layout/test_file_field_clearable.html000066400000000000000000000011301456730133600325360ustar00rootroot00000000000000
Currently: something
Change:
test_file_field_clearable_custom_control.html000066400000000000000000000043141456730133600356200ustar00rootroot00000000000000crispy-bootstrap4-2024.1/tests/results/bootstrap4/test_layout
Currently
something
Change
crispy-bootstrap4-2024.1/tests/results/bootstrap4/test_layout/test_file_field_custom_control.html000066400000000000000000000022001456730133600336750ustar00rootroot00000000000000
crispy-bootstrap4-2024.1/tests/results/bootstrap4/test_layout/test_file_field_default.html000066400000000000000000000006651456730133600322640ustar00rootroot00000000000000
crispy-bootstrap4-2024.1/tests/results/bootstrap4/test_layout/test_file_field_with_custom_class.html000066400000000000000000000022031456730133600343600ustar00rootroot00000000000000
test_file_field_with_custom_class_clearable.html000066400000000000000000000043171456730133600363030ustar00rootroot00000000000000crispy-bootstrap4-2024.1/tests/results/bootstrap4/test_layout
Currently
something
Change
crispy-bootstrap4-2024.1/tests/results/bootstrap4/test_layout/test_form_control_size.html000066400000000000000000000006161456730133600322270ustar00rootroot00000000000000
crispy-bootstrap4-2024.1/tests/results/bootstrap4/test_layout/test_fundamentals_example.html000066400000000000000000000044501456730133600326660ustar00rootroot00000000000000
crispy-bootstrap4-2024.1/tests/results/bootstrap4/test_layout/test_inline_formset_checkbox.html000066400000000000000000000060111456730133600333500ustar00rootroot00000000000000
box one box two
crispy-bootstrap4-2024.1/tests/results/bootstrap4/test_layout/test_multiple_fields.html000066400000000000000000000013571456730133600316560ustar00rootroot00000000000000
crispy-bootstrap4-2024.1/tests/results/bootstrap4/test_layout/test_radio_attrs.html000066400000000000000000000015251456730133600310050ustar00rootroot00000000000000
crispy-bootstrap4-2024.1/tests/results/bootstrap4/test_layout/test_uneditable_field.html000066400000000000000000000006361456730133600317530ustar00rootroot00000000000000
test_use_custom_control_in_select_false.html000066400000000000000000000007401456730133600355360ustar00rootroot00000000000000crispy-bootstrap4-2024.1/tests/results/bootstrap4/test_layout
test_use_custom_control_in_select_true.html000066400000000000000000000007411456730133600354240ustar00rootroot00000000000000crispy-bootstrap4-2024.1/tests/results/bootstrap4/test_layout
test_use_custom_control_in_uneditable_select_false.html000066400000000000000000000011501456730133600377260ustar00rootroot00000000000000crispy-bootstrap4-2024.1/tests/results/bootstrap4/test_layout
test_use_custom_control_in_uneditable_select_true.html000066400000000000000000000011511456730133600376140ustar00rootroot00000000000000crispy-bootstrap4-2024.1/tests/results/bootstrap4/test_layout
test_use_custom_control_is_used_in_checkboxes_false.html000066400000000000000000000062231456730133600401120ustar00rootroot00000000000000crispy-bootstrap4-2024.1/tests/results/bootstrap4/test_layout
test_use_custom_control_is_used_in_checkboxes_true.html000066400000000000000000000070151456730133600377770ustar00rootroot00000000000000crispy-bootstrap4-2024.1/tests/results/bootstrap4/test_layout
test_use_custom_control_is_used_in_checkboxes_true_failing.html000066400000000000000000000106471456730133600414750ustar00rootroot00000000000000crispy-bootstrap4-2024.1/tests/results/bootstrap4/test_layout

This field is required.

This field is required.

This field is required.

test_use_custom_control_is_used_in_checkboxes_true_failing_lt50.html000066400000000000000000000103631456730133600423340ustar00rootroot00000000000000crispy-bootstrap4-2024.1/tests/results/bootstrap4/test_layout

This field is required.

This field is required.

This field is required.

test_use_custom_control_is_used_in_radio_false.html000066400000000000000000000016611456730133600370730ustar00rootroot00000000000000crispy-bootstrap4-2024.1/tests/results/bootstrap4/test_layout
test_use_custom_control_is_used_in_radio_true.html000066400000000000000000000020531456730133600367540ustar00rootroot00000000000000crispy-bootstrap4-2024.1/tests/results/bootstrap4/test_layout
test_use_custom_control_is_used_in_radio_true_failing.html000066400000000000000000000024451456730133600404520ustar00rootroot00000000000000crispy-bootstrap4-2024.1/tests/results/bootstrap4/test_layout

This field is required.

test_use_custom_control_is_used_in_radio_true_failing_lt50.html000066400000000000000000000023511456730133600413120ustar00rootroot00000000000000crispy-bootstrap4-2024.1/tests/results/bootstrap4/test_layout

This field is required.

crispy-bootstrap4-2024.1/tests/results/bootstrap4/test_layout_objects/000077500000000000000000000000001456730133600262535ustar00rootroot00000000000000crispy-bootstrap4-2024.1/tests/results/bootstrap4/test_layout_objects/bootstrap_modal_no_kwargs.html000066400000000000000000000022601456730133600344040ustar00rootroot00000000000000