jQuery. Исправление "is not focusable" для форм с табами

Ответить
Аватара пользователя
Distructor
Администратор
Сообщения: 1607
Зарегистрирован: 28.12.2009
Допустим у нас есть форма поля которой разнесены по нескольким вкладкам (в данном случае табы Twitter Bootstrap) и являются обязательными:

Код: Выделить всё

<form method="post" action="" id="formId">
    
    <ul class="nav nav-tabs" role="tablist">
        <li class="active"><a href="#tab1" data-toggle="tab">Tab 1</a></li>
        <li><a href="#tab2" data-toggle="tab">Tab 2</a></li>
    </ul>
    <div class="tab-content project-part-edit-block">
        <div class="tab-pane active" id="tab1">
            <input type="text" name="field1" required="required" value="">
        </div>
        <div class="tab-pane active" id="tab2">
            <input type="text" name="field2" required="required" value="">
        </div>
    </div>

    <button type="submit" name="save">Сохранить изменения</button>
</form>
При попытке отправки незаполненной формы уведомления валидации браузер покажет только для видимых полей, а по остальным добавит в лог ошибку вида

Код: Выделить всё

An invalid form control with name='field2' is not focusable.
Особо остро проблема стоит, когда на видимой вкладке все поля заполнены и при нажатии "Сохранить изменения" ничего (видимого для пользователя) не происходит.

Для исправления ситуации был написан небольшой скрипт, который проверяет заполненность невидимых в данный момент обязательных полей и переключает вкладку, если находит не заполненные:

Код: Выделить всё

$('#formId [type="submit"]').click(function(){
    // выбираем все невидимые обязательные поля
    $('input, textarea, select').filter('[required]:hidden').each(function(){
        // проверяем их заполненность
        if (!$(this)[0].checkValidity()) {
            var tabId = $(this).closest('.tab-pane').attr('id');
            // переключаем таб
            $('.nav-tabs a[href="#' + tabId + '"]').tab('show');
            // прерываем обработку остальных обязательных полей
            return false;
        }
    });
});

Ответить