Formit+AjaxForm - поле checkbox/radio и реакция на событие

Всем привет!

Для ФОС использую Formit+AjaxForm.
Поля, которые использую: input(text), textarea, select, checkbox и radio — они все обязательные (&validate=`field:required,...`).

Суть ситуации. Если не заполнить любое из обязательных полей и нажать Отправить, то рядом с каждым полем появляется уведомление об обязательности заполнения.
Кликаем по input(text) или textarea, вставляем любой символ — уведомление исчезает;
Кликаем по select, выбираем любое значение — уведомление исчезает;
С этими типами полей проблем нет — уведомление работает корректно.

Кликаем по checkbox или radio, ставим галку — уведомление не исчезает.
Эта ситуация конечно же не критична. Но всё же, хочется привести уведомления для checkbox и radio к общей логике поведения — чтобы после взведения галки уведомление об обязательности заполнения исчезало.

Насколько понимаю, нужно править assets/components/ajaxform/js/default.js

К сожалению, я плохо разбираюсь в этом, но вначале попробовал доработать самостоятельно(beforeSubmit: function (fields, form){ ...) — добавить типы checkbox и radio в form.find('input,checkbox, radio,textarea,select,button').attr('disabled', true);. Не помогло.
Ивaныч
31 августа 2022, 18:27
modx.pro
1 164
0

Комментарии: 15

Артур Шевченко
31 августа 2022, 20:46
0
Лезть в исходники необязательно, повесь на checkbox и radio обработчик события change и скрывай ошибки.
    Ивaныч
    31 августа 2022, 21:52
    0
    На счёт необязательности, согласен. Но, корректное решение нужно искать в исходниках, а не колхозить изощрения. Так считаю. Тем более это не частный случай, а всего лишь банальная недоработка популярного плагина. Если у кого есть решение вопроса по существу, прошу помочь.
      Артур Шевченко
      31 августа 2022, 22:12
      +1
      Вот кусок кода который скрывает ошибки. Проверьте вёрстку.
        Ивaныч
        31 августа 2022, 22:40
        0
        Попробую разобраться, хотя заранее сомневаюсь в собственном успехе — второй день пытаюсь, иначе не обратился бы на форум за помощью.

        Артур, в любом случае, спасибо за отклик и помощь!
    Alexey
    01 сентября 2022, 09:46
    0
    Не скажу за радиокнопки, но чекбокс у меня корректно отрабатывает — сообщение об ошибке скрывается, если его прочекать. Без всяких доработок js

    skrinshoter.ru/s/010922/JHg0TdiX?a
    skrinshoter.ru/s/010922/AwHFH32a?a

    Покажите чанк формы.
      Ивaныч
      01 сентября 2022, 16:08
      0
      <form action="[[*id]]" method="post" class="ajax_form af_example" enctype="multipart/form-data">
      <div class="form-group">
      <label for="chetest">Поле checkbox <span class="required">*</span>:</label>
      <div class="controls">
      <span class="error_chetest">[[!+fi.error.chetest]]</span>
      <span><input type="checkbox" name="chetest[]" id="chetest" value="Вариант1" [[!+fi.chetest:FormItIsChecked=`Вариант1`]]>Вариант1</span>
      <span><input type="checkbox" name="chetest[]" id="chetest" value="Вариант2" [[!+fi.chetest:FormItIsChecked=`Вариант2`]]>Вариант2</span>
      <input type="hidden" name="chetest[]" value="">
      </div>
      </div>
        Alexey
        01 сентября 2022, 16:21
        0
        Я не совсем понимаю логику — почему у разных чекбоксов один атрибут name? Да ещё массив… не говоря уже про одинаковые id. Если нужно выбрать в форме какой-то один вариант из двух, то здесь радиобаттоны нужны, не?

        Конструкции типа [[!+fi.error.chetest]] используются для formit без ajaxForm.

        Вот рабочий вариант для одного чекбокса:

        <input type="hidden" name="q_agree" value="">
        <div class="form-b__field form-b__field_full">
            <input type="checkbox" name="q_agree" class="checkbox" id="politic" value="1" checked="">
            <label for="politic"><a href="politika-konfidenczialnosti">Политика конфиденциальности</a></label> 
            <span class="error_q_agree"></span>   
        </div>

        скрытый инпут нужен для проверки на пустоту, иначе required-валидация пропустит. А спан с классом error_q_agree как раз и отвечает за вывод ошибок (класс строится из строки 'erorr_' + имя поля)
          Ивaныч
          01 сентября 2022, 16:31
          0
          Нее, тут идея следущая: можно выбрать 1 вариант, а можно и оба(вариант1+вариант2) = поэтому чекбокс, а не радио.
            Ивaныч
            01 сентября 2022, 16:43
            0
            Конструкции типа [[!+fi.error.chetest]] используются для formit без ajaxForm.
            Не знал об этом, исключил эту конструкцию.
            Спасибо за информацию!
        Ивaныч
        01 сентября 2022, 16:27
        0
        Насколько понимаю, причина в специфике указания имени для чекбоксов и радио, а точнее name=«chetest[]» != name=«chetest». В AjaxForm идет проверка и из-за [] чекбоксы и радио проверку не проходят, и поэтому уведомление не исчезает.

        Пробовал доработать строку в default.js:
        $(document).on('keypress change', '.error', function () {
                    var key = $(this).attr('name'); 
                    $(this).removeClass('error');
                    $('.error_' + key).html('').removeClass('error');
                });
        заменив var key = $(this).attr('name'); на var key = $(this).attr('id');
        или var key = $(this).attr('name'); на input[type=«hidden»][name="' + chetest[] + '"]
        Понимаю, что мои попытки ничтожны.
          Alexey
          01 сентября 2022, 16:47
          0
          Мне кажется, в этом случае, проще было бы дать чекбоксам разные имена и добавить кастомный валидатор, который при сабмите проверял бы, заполнен ли хоть один чекбокс. И если нет, то выводил бы предупреждение
            Артур Шевченко
            02 сентября 2022, 00:54
            0
            Скорее всего вот так должно работать:
            $(document).on('keypress change', '.error', function () {
                        var key = $(this).attr('name'); 
                        key = key.replace(/[\[\]]/g, '');
                        $(this).removeClass('error');
                        $('.error_' + key).html('').removeClass('error');
                    });
              Ивaныч
              02 сентября 2022, 02:48
              0
              К сожалению,
              key = key.replace(/[\[\]]/g, '');
              не дало результата. Фиксирую прежнее поведение: селект, инпут(текст) и текстареа — уведомление исчезает, у чекбоксов и радио — не исчезает.
                Ивaныч
                02 сентября 2022, 04:53
                0
                Так понимаю, что реплейс
                key = key.replace(/[\[\]]/g, '');
                должен был заменить вхождения ключа chetest[] (с квадратными скобками) на ключ без квадратных скобок. Даже если бы эта регулярка сработала, то возникла бы следущая проблема — с проставленной галкой в checkbox при повторном нажатии Отправить — появляется уведомление об обязательности поля, мол галка не стоит.

                Корректным вариантом, имхо, будет что-то подобное:
                key = key or key[]
                То есть проверка на оба ключа, со скобками и без. А вот как это реализовать, не знаю. По идее это должно решить вопрос, если мыслю в верном направлении.
                  Артур Шевченко
                  02 сентября 2022, 13:12
                  0
                  <form action="[[*id]]" method="post" class="ajax_form af_example" enctype="multipart/form-data">
                  <div class="form-group">
                  <label for="chetest">Поле checkbox <span class="required">*</span>:</label>
                  <div class="controls">
                  <span class="error_chetest">[[!+fi.error.chetest]]</span>
                  <span><input type="checkbox" name="chetest[]" id="chetest" value="Вариант1" [[!+fi.chetest:FormItIsChecked=`Вариант1`]]>Вариант1</span>
                  <span><input type="checkbox" name="chetest[]" id="chetest" value="Вариант2" [[!+fi.chetest:FormItIsChecked=`Вариант2`]]>Вариант2</span>
                  <input type="hidden" name="chetest_control" value="">
                  </div>
                  </div>
                  Вешаешь на chetest обработчик события change, если хотя бы один из чекбоксов выбран в chetest_control записываешь 1, если ни один не выбран 0, после этого делаешь так
                  $('[name="chetest_control"]').trigger('change');
                  И валидируешь chetest_control. По-другому чекбоксы валидировать нельзя, т.к. если чекбокс не выбран на сервер ничего не передаётся, я попробовал обойти, но нет до AjaxForm всё равно не доходит сообщение об ошибке и вообще информация о том, что есть какой-то там чекбокс.
              Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
              15