django-bootstrap5 icon indicating copy to clipboard operation
django-bootstrap5 copied to clipboard

Invalid-feedback does not appear with SelectDateWidget

Open Pfu opened this issue 7 months ago • 4 comments

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])

Pfu avatar Apr 30 '25 14:04 Pfu

已收到,谢谢! 

scuyangguang avatar Apr 30 '25 14:04 scuyangguang

Is this fixed by #767?

dyve avatar Oct 19 '25 09:10 dyve

I think I tried to check a while ago, but there were other issues with SelectDateWidget, so I couldn't verify.

Sorry for not reporting those other issues.

xi avatar Oct 19 '25 10:10 xi

Should we revert #767?

dyve avatar Oct 19 '25 10:10 dyve