Skip to content

Invalid-feedback does not appear with SelectDateWidget #749

@Pfu

Description

@Pfu

Hi,

The html <div class="Invalid-feedback" > is present into generated page, but it is not displayed with SelectDateWidget.

I found some explanations on this page.

Image

<div class="mb-3 is-invalid">
 <label class="form-label" for="id_price">Price</label>
 <input type="number" name="price" value="888" autofocus="autofocus" class="form-control is-invalid" placeholder="Price" title="" required="" id="id_price">
 <div class="invalid-feedback">Test</div>
</div>

<div class="mb-3 is-invalid">
 <label class="form-label" for="id_date_year">Date</label>
 <div class="row bootstrap5-multi-input">
  <div class="col-4">
   <select name="date_year" class="form-control is-invalid" title="" required="" id="id_date_year">
    <option value="2023" selected="">2023</option>
    <option value="2024">2024</option>
    <option value="2025">2025</option>
   </select>
  </div>
  <div class="col-4">
   <select name="date_month" class="form-control is-invalid" title="" required="" id="id_date_month">
    <option value="1">janvier</option>
    <option value="2">février</option>
    <option value="3">mars</option>
    <option value="4" selected="">avril</option>
    <option value="5">mai</option>
    <option value="6">juin</option>
    <option value="7">juillet</option>
    <option value="8">août</option>
    <option value="9">septembre</option>
    <option value="10">octobre</option>
    <option value="11">novembre</option>
    <option value="12">décembre</option>
   </select>
  </div>
  <div class="col-4">
   <select name="date_day" class="form-control is-invalid" title="" required="" id="id_date_day">
    <option value="1">1</option>
    <option value="2">2</option>
    <option value="3">3</option>
    <option value="4">4</option>
    <option value="5">5</option>
    <option value="6">6</option>
    <option value="7">7</option>
    <option value="8">8</option>
    <option value="9">9</option>
    <option value="10">10</option>
    <option value="11">11</option>
    <option value="12">12</option>
    <option value="13">13</option>
    <option value="14">14</option>
    <option value="15">15</option>
    <option value="16">16</option>
    <option value="17">17</option>
    <option value="18">18</option>
    <option value="19">19</option>
    <option value="20">20</option>
    <option value="21">21</option>
    <option value="22">22</option>
    <option value="23">23</option>
    <option value="24">24</option>
    <option value="25">25</option>
    <option value="26">26</option>
    <option value="27">27</option>
    <option value="28">28</option>
    <option value="29">29</option>
    <option value="30" selected="">30</option>
    <option value="31">31</option>
   </select>
  </div>
 </div>
   <div class="invalid-feedback">date over 1 year</div>
</div>

After some testing, the html <div class="Invalid-feedback" > should be located just after the select which contains the CSS class="form-control is-invalid" in order to be displayed.

Maybe the ideal location would be just after the first select (the one that corresponds to the years).

<div class="mb-3 is-invalid">
 <label class="form-label" for="id_price">Price</label>
 <input type="number" name="price" value="888" autofocus="autofocus" class="form-control is-invalid" placeholder="Price" title="" required="" id="id_price">
 <div class="invalid-feedback">date over 1 year</div>
</div>

<div class="mb-3 is-invalid">
 <label class="form-label" for="id_date_year">Date</label>
 <div class="row bootstrap5-multi-input">
  <div class="col-4">
   <select name="date_year" class="form-control is-invalid" title="" required="" id="id_date_year">
    <option value="2023" selected="">2023</option>
    <option value="2024">2024</option>
    <option value="2025">2025</option>
   </select>
  <div class="invalid-feedback">date over 1 year</div>
  </div>
  <div class="col-4">
   <select name="date_month" class="form-control is-invalid" title="" required="" id="id_date_month">
    <option value="1">janvier</option>
    <option value="2">février</option>
    <option value="3">mars</option>
    <option value="4" selected="">avril</option>
    <option value="5">mai</option>
    <option value="6">juin</option>
    <option value="7">juillet</option>
    <option value="8">août</option>
    <option value="9">septembre</option>
    <option value="10">octobre</option>
    <option value="11">novembre</option>
    <option value="12">décembre</option>
   </select>
  </div>
  <div class="col-4">
   <select name="date_day" class="form-control is-invalid" title="" required="" id="id_date_day">
    <option value="1">1</option>
    <option value="2">2</option>
    <option value="3">3</option>
    <option value="4">4</option>
    <option value="5">5</option>
    <option value="6">6</option>
    <option value="7">7</option>
    <option value="8">8</option>
    <option value="9">9</option>
    <option value="10">10</option>
    <option value="11">11</option>
    <option value="12">12</option>
    <option value="13">13</option>
    <option value="14">14</option>
    <option value="15">15</option>
    <option value="16">16</option>
    <option value="17">17</option>
    <option value="18">18</option>
    <option value="19">19</option>
    <option value="20">20</option>
    <option value="21">21</option>
    <option value="22">22</option>
    <option value="23">23</option>
    <option value="24">24</option>
    <option value="25">25</option>
    <option value="26">26</option>
    <option value="27">27</option>
    <option value="28">28</option>
    <option value="29">29</option>
    <option value="30" selected="">30</option>
    <option value="31">31</option>
   </select>
  </div>
 </div>
</div>

Image

I work on Django 4.2.8 and on Fedore (6.14.4-200.fc41.x86_64).
Below is the Python code for the Django form:

from django import forms
from datetime import timedelta
from datetime import datetime
from datetime import date as dt
from django.utils import timezone

def validate_date(value):
    if isinstance(value, dt):
        if value < (timezone.now() - timedelta(days=365)).date():
            raise ValidationError("date over 1 year")
        if value > timezone.now().date():
            raise ValidationError("not in future")

def validate_test(value):
    if value == 888:
        raise ValidationError("Test")

class RecordWithShopForm(forms.ModelForm):
    date = forms.DateField(
        initial=datetime.now,
        validators=[validate_date],
        widget=forms.SelectDateWidget(
            years=[2023, 2024, 2025],
        ),
    )
    note = forms.CharField(required=False)
    price = forms.IntegerField(required=True, validators=[validate_test])

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions