На основі абсолютно геніального рішення @claviska, кому належить вся заслуга.
Повнофункціональне введення файлів Bootstrap 4 з валідацією та текстом довідки.
На основі прикладу групи введення у нас є фіктивне текстове поле введення, яке використовується для відображення імені файлу користувачеві, яке заповнюється від onchangeподії у фактичному полі вхідного файлу, прихованому за кнопкою мітки. Крім включення перевірки завантажувальної програми 4 підтримки для ми також дали можливість натиснути будь-де на вході, щоб відкрити діалогове вікно файлу.
Три стану введення файлу
Три можливі стани є неперевіреними, дійсними та недійсними з requiredнабором атрибутів вхідного тегу манекена html .

Розмітка 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!