Основан на абсолютно блестящем решении @claviska, которому все заслуги.
Полнофункциональный ввод файла Bootstrap 4 с проверкой и текстом справки.
Основываясь на примере группы ввода, мы имеем фиктивное поле ввода текста, используемое для отображения имени файла пользователю, которое заполняется onchange
событием в поле фактического файла ввода, скрытом за кнопкой метки. Помимо включения поддержки проверки bootstrap 4, мы также дали возможность щелкнуть в любом месте ввода, чтобы открыть диалоговое окно файла.
Три состояния ввода файла
Три возможных состояния не подтверждены, действительны и недействительны с установленным атрибутом фиктивного тега ввода HTML required
.
HTML-разметка для ввода
Введу только 2 пользовательских классы input-file-dummy
и input-file-btn
к надлежащему стилю и проволоке желаемого поведения. Все остальное - стандартная разметка Bootstrap 4.
<div class="input-group">
<input type="text" class="form-control input-file-dummy" placeholder="Choose file" aria-describedby="fileHelp" required>
<div class="valid-feedback order-last">File is valid</div>
<div class="invalid-feedback order-last">File is required</div>
<label class="input-group-append mb-0">
<span class="btn btn-primary input-file-btn">
Browse… <input type="file" hidden>
</span>
</label>
</div>
<small id="fileHelp" class="form-text text-muted">Choose any file you like</small>
JavaScript поведенческие положения
Фиктивный ввод должен быть только для чтения, в соответствии с исходным примером, чтобы пользователь не мог изменить ввод, который может быть изменен только через диалог открытия файла. К сожалению, проверка не выполняется в readonly
полях, поэтому мы переключаем редактируемость ввода для фокуса и размытия ( события jquery onfocusin
и onfocusout
) и гарантируем, что он снова станет доступным для проверки после выбора файла.
Кроме того, чтобы сделать текстовое поле кликабельным, запуская событие нажатия кнопки, остальная функциональность заполнения фиктивного поля была предусмотрена @claviska.
$(function () {
$('.input-file-dummy').each(function () {
$($(this).parent().find('.input-file-btn input')).on('change', {dummy: this}, function(ev) {
$(ev.data.dummy)
.val($(this).val().replace(/\\/g, '/').replace(/.*\//, ''))
.trigger('focusout');
});
$(this).on('focusin', function () {
$(this).attr('readonly', '');
}).on('focusout', function () {
$(this).removeAttr('readonly');
}).on('click', function () {
$(this).parent().find('.input-file-btn').click();
});
});
});
Индивидуальные настройки
Самое главное, мы не хотим, чтобы readonly
поле переходило между серым фоном и белым, поэтому мы гарантируем, что оно остается белым. У кнопки span нет курсора-указателя, но мы все равно должны добавить его для ввода.
.input-file-dummy, .input-file-btn {
cursor: pointer;
}
.input-file-dummy[readonly] {
background-color: white;
}
NJoy!