Django Form - условное отображение полей с помощью JQuery

Отказ от претензий: Я зашел в тупик. Попробовав 10+ различных вопросов и ответов только на Stack Overflow, я уперся в стену. Я надеюсь, что смогу решить эту проблему с помощью прямого вопроса. Пожалуйста, будьте мягче. Я потратил несколько дней на поиск в Stack Overflow и в Интернете, чтобы попытаться заставить это работать. Есть МНОГО предложений, и ни одно из них не сработало для меня до сих пор. Признаюсь, я не очень хорошо разбираюсь в JS, и, вероятно, поэтому я сильно спотыкаюсь на этом требовании.

Если у вас есть замечания по качеству этого вопроса, пожалуйста, прокомментируйте его с конструктивной критикой. Просто сказать, что вопрос плохо сформулирован, не поможет. Однако, если вы поделитесь конкретными примерами того, что я мог бы сделать, чтобы сформулировать вопрос более полезным образом, это будет здорово. Надеюсь, вы сможете убедиться, что я приложил немало усилий, чтобы изложить суть желаемой цели, а также то, что я пытался сделать.

В данной реализации используется Django 4.0 и Bootstrap5 с CrispyForms.

Цель: Пользователь, выбирая значение в одном поле, определяет, будет ли показано или скрыто другое поле. По умолчанию условное поле имеет значение "Нет". Воздействующее поле будет показано, когда пользователь изменит условное поле на значение "Да". В частности, если пользователь выберет "Да" для поля Повторяющееся событие, будет показано поле Шаблон повторения.

Обратите внимание, что реализация Class Based Views в шаблоне работает отлично. Вот скриншот формы (с неработающим требованием условного поля): Working form screenshot

Существующий код (только соответствующие фрагменты)

Вот что у меня есть в models.py:

YES_NO_CHOICES = [
    ('No', 'No'),
    ('Yes', 'Yes'),
]
RECURRENCE_PATTERN_CHOICES = [
    ('---', '---'),
    ('Daily', 'Daily'),
    ('Weekly', 'Weekly'),
    ('Monthly', 'Monthly'),
    ('Yearly', 'Yearly'),
]


class Event(models.Model):
    event_name = models.CharField(
        max_length=70,
        help_text='''Enter a name for the event. This is a required field and is limited to 70 characters.'''
    )
    recurring_event = models.CharField(
        max_length=5,
        choices=YES_NO_CHOICES,
        default='No',
        help_text='''Is this a one off event or will it recur? Selecting Yes will open up additional fields.'''

    )
    recurrence_pattern = models.CharField(
        max_length=10,
        choices=RECURRENCE_PATTERN_CHOICES,
        default='---',
        help_text='''Select the recurrence pattern for this event.'''
    )

Вот что у меня есть в файле forms.py:

class EventStaffSummaryUpdateView(UpdateView):
    """Event Staff Update view - allows staff to change event details"""
    model = Event
    template_name = 'events/event_staff_summary_form.html'
    fields = [
            'event_name',
            'recurring_event',
            'recurrence_pattern',
    ]
    context_object_name = 'event'

В шаблоне event_staff_summary.html (с использованием наследования) у меня есть:

   <div class="content-section">
        <form method="POST">
            {% csrf_token %}
            <fieldset class="form-group">
                <div id="event_name">
                    {{ form.event_name|as_crispy_field }}
                </div>
                <div id="recurring_event">
                    {{ form.recurring_event|as_crispy_field }}
                </div>
                <div id="recurrence_pattern">
                    {{ form.recurrence_pattern|as_crispy_field }}
                </div>
            </fieldset>
            <div class="form-group pt-4 pb-2">
                {% if page_type == 'Update' %}
                    <button class="btn btn-BlueGray" type="submit">Update Event</button>
                {% else %}
                    <button class="btn btn-BlueGray" type="submit">Create Event</button>
                {% endif %}
            </div>
        </form>
    </div>

В шаблоне base.html я использую ссылку Google JQuery (найденную на моем пути как простой способ внедрения JQuery):

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>

Как вы можете видеть на скриншоте, сама форма отображается отлично. Таким образом, модели, форма и даже html работают до сих пор. Представление на основе класса обновления работает с БД. Осталось только показать или скрыть шаблон Recurrence на основе значения в поле Recurrence event. Что приводит меня к...

Что я уже пробовал?

Из 10+ JS сниппетов, которые я встречал и пробовал, вот ведущий кандидат, который кажется наиболее близким. Я очень хочу, чтобы это работало, так как это имеет смысл для меня.

    <script>
        $("#recurring_event").change(function() {
            if ($(this).val() === "Yes") {
                $('#recurrence_pattern').show();
            } else {
                $('#recurrence_pattern').hide();
            }
         });
    </script>

Request

У кого-нибудь есть предложения о том, как я могу заставить это работать? У меня есть требования к ряду условно отображаемых полей. Я бы предпочел не работать с чекбоксами, так как обычно клиент предпочитает, чтобы пользователь явно нажимал "Да" или "Нет", поскольку это для них более понятно (они считают, что при закрытом вопросе и выборе "да/нет" нет возможности двусмысленности)

Это требование условных полей в формах реализовано во многих случаях, поэтому я знаю, что не ищу невозможного. Я надеюсь, что существует простая доработка (или очистка) сниппета javascript, который я разместил. Я также приветствую другие предложенные JS сниппеты

Заранее спасибо за помощь.

Обновить библиотеку до <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>

Заверните функцию в событие готовности DOM.

Обновите селектор на <select> (из div). Сделайте это, просмотрев DOM.

Конечный результат:

(function($){
    $(document).ready(function(){
        $("#id_recurring_event").change(function() {
            if ($(this).val() === "Yes") {
                $('#id_recurrence_pattern').show();
            } else {
                $('#id_recurrence_pattern').hide();
            }
        });
    })
})(jQuery);

Для этого можно использовать метод trigger(). Таким образом, всякий раз, когда ваша страница загружается, вызывайте этот метод, чтобы выполнить событие изменения, которое прикреплено к select-box .

Рабочий код :

$(document).ready(function() {
  $("#id_recurring_event").change(function() {
    if ($(this).val() === "No") {
      $('#recurrence_pattern').hide();
    } else {
      $('#recurrence_pattern').show();
    }
  });
  $("#id_recurring_event").trigger("change")
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>

<div class="content-section">
  <form method="POST">
    <fieldset class="form-group">
      <div id="event_name">
        ABC ..
      </div>
      <div id="recurring_event">
        <select id="id_recurring_event">
          <option value="Yes">Yes</option>
          <option value="No" selected="true">No</option>
        </select>
      </div>
      <div id="recurrence_pattern">
        somethings ..................
      </div>
    </fieldset>
  </form>
</div>

Вернуться на верх