Basado en la solución absolutamente brillante de @claviska, a quien se le debe todo el crédito.
Entrada de archivo Bootstrap 4 con todas las funciones con validación y texto de ayuda.
Según el ejemplo del grupo de entrada , tenemos un campo de texto de entrada ficticio utilizado para mostrar el nombre de archivo al usuario, que se completa desde el onchange
evento en el campo del archivo de entrada real oculto detrás del botón de etiqueta. Además de incluir la validación bootstrap 4 soporte de , también hemos hecho posible hacer clic en cualquier lugar de la entrada para abrir el cuadro de diálogo del archivo.
Tres estados de la entrada del archivo
Los tres estados posibles no están validados, son válidos e inválidos con el required
conjunto de atributos de etiqueta de entrada html ficticia .
Marcado HTML para la entrada
Introducimos solo 2 clases personalizadas input-file-dummy
y input-file-btn
para diseñar y conectar correctamente el comportamiento deseado. Todo lo demás es el marcado estándar de 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>
Disposiciones de comportamiento de JavaScript
La entrada ficticia debe ser de solo lectura, según el ejemplo original, para evitar que el usuario cambie la entrada que solo se puede cambiar a través del diálogo de abrir archivo. Desafortunadamente, la validación no ocurre en los readonly
campos, por lo que alternamos la editabilidad de la entrada en foco y desenfoque ( eventos jquery onfocusin
y onfocusout
) y nos aseguramos de que se vuelva a validar una vez que se selecciona un archivo.
Además de hacer que se pueda hacer clic en el campo de texto, al activar el evento de clic del botón, @claviska imaginó el resto de la funcionalidad de llenar el campo ficticio.
$(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();
});
});
});
Ajustes de estilo personalizados
Lo más importante es que no queremos que el readonly
campo salte entre el fondo gris y el blanco, por lo que nos aseguramos de que permanezca en blanco. El botón span no tiene un cursor de puntero, pero debemos agregar uno para la entrada de todos modos.
.input-file-dummy, .input-file-btn {
cursor: pointer;
}
.input-file-dummy[readonly] {
background-color: white;
}
nJoy!