Se requiere entrada HTML5, desplácese hasta la entrada con la barra de navegación fija al enviar

8 minutos de lectura

Se requiere entrada HTML5 desplacese hasta la entrada con la
Agustín Riedinger

Cuando intento enviar un formulario al que le faltan campos obligatorios, mi navegador (Chrome) muestra un mensaje que menciona que falta un campo y, si está fuera de mi pantalla, se desplaza hacia arriba.

Mi problema es que tengo un encabezado fijo de 50 px en mi página web y, como resultado, el campo de entrada está oculto y el mensaje parece salir de la nada:

Campo de entrada oculto

En vez de

Campo de entrada mostrado

¿Hay alguna forma de evitar esto?

Intenté aplicar el margen de 50px a <html> y para <body>

Salud


EDITAR

Aquí hay un violín del problema: http://jsfiddle.net/LL5S6/1/

  • Tuve exactamente el mismo problema, lástima que a nadie se le ocurrió una solución para esto.

    – tirdadc

    28 julio 2014 en 18:23

  • Creo que debemos considerar la required="required" html como algo inestable en este momento… Es complicado de usar, no es muy compatible y todavía tiene efectos secundarios como este…

    – Agustín Riedinger

    13 ago. 14 en 13:19

  • usando la versión 37.0.2062.120 de Chrome, funciona como usted quiere. ya lo has probado?

    – dippas

    17 sep.

  • prueba esto: jsfiddle.net/LL5S6/46

    – Abudayah

    17 sep.

Tuve exactamente el mismo problema y lo resolví usando jquery con este código:

var delay = 0;
var offset = 150;

document.addEventListener('invalid', function(e){
   $(e.target).addClass("invalid");
   $('html, body').animate({scrollTop: $($(".invalid")[0]).offset().top - offset }, delay);
}, true);
document.addEventListener('change', function(e){
   $(e.target).removeClass("invalid")
}, true);

El desplazamiento debe ser la altura de su encabezado y el retraso es el tiempo que desea que tarde en desplazarse hasta el elemento.

  • ¡Exactamente lo que necesitaba! Pero tenga cuidado: si usa un retraso > 0, el mensaje del navegador “Complete este campo” desaparecerá tan pronto como comience el desplazamiento (por lo que solo es visible durante unos pocos milisegundos)

    – mosca tecnológica

    12 jun.

  • En mi opinión, esta solución es incorrecta, ya que el evento ‘no válido’ no burbujea de acuerdo con developer.mozilla.org/en-US/docs/Web/Events/invalid

    – M Klein

    05 abr.

1641756886 448 Se requiere entrada HTML5 desplacese hasta la entrada con la
A1rPun

La única forma que encontré es agregar una ‘anulación’ al controlador no válido. Para implementar esto para cada entrada en su formulario, puede hacer algo como esto.

var elements = document.querySelectorAll('input,select,textarea');
var invalidListener = function(){ this.scrollIntoView(false); };

for(var i = elements.length; i--;)
    elements[i].addEventListener('invalid', invalidListener);

Esto requiere HTML5 y está probado en IE11, Chrome y Firefox.
Créditos a @HenryW por encontrar eso scrollIntoView funciona como se esperaba.

Tenga en cuenta que el parámetro falso para scrollIntoView alinea la entrada con la parte inferior, por lo que si tiene un formulario grande, puede alinearse con la parte inferior de la página.

jsfiddle

  • Gracias @HenryW, lo agregaré a la respuesta.

    – A1rPun

    17 sep.

  • ¡Bastante agradable! ¡Aunque una depuración del navegador sería aún mejor!

    – Agustín Riedinger

    17 sep.

  • scrollIntoView no funciona con encabezados posicionados fijos en la parte superior de la página.

    – feeela

    08 feb.

  • @feeela Resolvió el problema para OP que tenía un encabezado posicionado fijo. ¿Puedes especificar qué No funciona?

    – A1rPun

    08 feb.

  • Esto no funciona si hay varias entradas no válidas porque se desplazará hasta la última entrada no válida y luego el navegador se desplazará hacia atrás hasta la primera en la parte superior y oculta por la barra de navegación fija. Debería haber una forma de ejecutar scrollIntoView solo para la primera entrada no válida, pero no sé cómo.

    – Christian Toffolo

    29 nov.

1641756886 707 Se requiere entrada HTML5 desplacese hasta la entrada con la
Ausi

En navegadores modernos hay una nueva propiedad CSS para ese caso de uso:

html {
    scroll-padding-top: 50px;
}

Tu JSFiddle actualizado: http://jsfiddle.net/5o10ydbk/

Compatibilidad con navegadores para scroll-padding: https://caniuse.com/#search=scroll-padding

1641756886 696 Se requiere entrada HTML5 desplacese hasta la entrada con la
alf eaton

Cuando hay varias entradas no válidas en el formulario, solo desea desplazarse hasta la primera de ellas:

var form = $('#your-form')
var navbar = $('#your-fixed-navbar')

// listen for `invalid` events on all form inputs
form.find(':input').on('invalid', function (event) {
    var input = $(this)

    // the first invalid element in the form
    var first = form.find(':invalid').first()

    // only handle if this is the first invalid input
    if (input[0] === first[0]) {
        // height of the nav bar plus some padding
        var navbarHeight = navbar.height() + 50

        // the position to scroll to (accounting for the navbar)
        var elementOffset = input.offset().top - navbarHeight

        // the current scroll position (accounting for the navbar)
        var pageOffset = window.pageYOffset - navbarHeight

        // don't scroll if the element is already in view
        if (elementOffset > pageOffset && elementOffset < pageOffset + window.innerHeight) {
            return true
        }

        // note: avoid using animate, as it prevents the validation message displaying correctly
        $('html,body').scrollTop(elementOffset)
    }
})

JSFiddle

Se requiere entrada HTML5 desplacese hasta la entrada con la
henryw

ok, hice una prueba sucia con un fragmento de código que encontré aquí en SO

Como es un código de otra persona, simplemente lo modifico para desplazarme hasta el elemento al que le faltaba un requisito de entrada. No quiero ningún crédito por ello, y tal vez ni siquiera sea lo que tienes en mente, tú o alguien más podría usarlo como referencia.

El objetivo era obtener la identificación del elemento de entrada olvidado/incorrecto:

            var myelement = input.id;
            var el = document.getElementById(myelement);
            el.scrollIntoView(false);

Tenga en cuenta que este violín solo funciona para su violín publicado anteriormente, no maneja múltiples campos de entrada olvidados o incorrectos. Solo quería mostrar una alternativa.

—–>jSFiddle

  • Acabas de resolver un rompecabezas juntando las piezas correctas 😉 Se me ocurrió una solución aún más corta que publicaré en un segundo.

    – A1rPun

    17 sep.

  • Ver este violín. Porque especifica falso para scrollIntoView el elemento está en la parte inferior de la página. Entonces la solución no es perfecta (la mía tampoco lo es)

    – A1rPun

    17 sep.

  • creo que necesita tener falso, si es verdadero, no funciona. solía ESTA como mi referencia para dar la respuesta

    – HenryW

    17 sep.

  • si se puede modificar alignWithTop agregando el margin-top: 50px; o obteniendo la posición de los campos, ambos códigos están listos :), creo que depende del OP ajustarlo.

    – HenryW

    17 sep.

  • Mi primera solución fue obtener el getBoundingClientRect y verifique si la parte superior era menor que la parte inferior del encabezado … y luego desplace la ventana en consecuencia. Creo que scrollIntoView es aceptable;)

    – A1rPun

    17 sep.

Traté de usar el método de TJ Moats, pero no funcionó como era necesario, porque a menudo volvía al campo, lo cual era incorrecto al principio.

Entonces, lo hice:

var navhei = $('header').height();
var navheix = navhei + 30;
document.addEventListener('invalid', function(e){
$(e.target).addClass("invalid");
   $('html, body').animate({scrollTop: $($(".invalid")[0]).offset().top - navheix }, 0);
 
setTimeout(function() {
$('.invalid').removeClass('invalid');
},0300);
}, true);
body {
    margin: 0;
    margin-top: 50px;
    text-align: center;
}

header {
    position: fixed;
    width: 100%;
    height: 50px;
    background-color: #CCCCCC;
    text-align:center;
    top: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.min.js"></script>
<header>This is the header</header>
<div>
<form action="">
<br>
    <input id="text" type="text" required="required" /><br><br>
    <input id="text" type="text" required="required" /><br><br><br><br>
    <input id="text" type="text" required="required" /><br><br>
    <input id="text" type="text" required="required" /><br><br><br><br>
    <input id="text" type="text" required="required" /><br><br><br><br><br><br>
    <input id="text" type="text" required="required" /><br><br>
        <p>Click send (at the bottom of the page), without filling the input field.</p><br><br><br><br><br><br>
        <input id="text" type="text" required="required" /><br><br>
    <input type="submit" id="btnSubmit" />
    </form>
</div>

Espero que sea útil para la gente 🙂

  • Acabas de resolver un rompecabezas juntando las piezas correctas 😉 Se me ocurrió una solución aún más corta que publicaré en un segundo.

    – A1rPun

    17 sep.

  • Ver este violín. Porque especifica falso para scrollIntoView el elemento está en la parte inferior de la página. Entonces la solución no es perfecta (la mía tampoco lo es)

    – A1rPun

    17 sep.

  • creo que necesita tener falso, si es verdadero, no funciona. solía ESTA como mi referencia para dar la respuesta

    – HenryW

    17 sep.

  • si se puede modificar alignWithTop agregando el margin-top: 50px; o obteniendo la posición de los campos, ambos códigos están listos :), creo que depende del OP ajustarlo.

    – HenryW

    17 sep.

  • Mi primera solución fue obtener el getBoundingClientRect y verifique si la parte superior era menor que la parte inferior del encabezado … y luego desplace la ventana en consecuencia. Creo que scrollIntoView es aceptable;)

    – A1rPun

    17 sep.

1641756886 614 Se requiere entrada HTML5 desplacese hasta la entrada con la
Schlebe

Puedes usar oninvalid atributo de evento de HTML5 y en la etiqueta de su script escriba una función para redirigirlo.

Aquí está el ejemplo:

<input type="text" required oninvalid="scroll_to_validator(this)">

<script>
    function scroll_to_validator(input)
        {
        input.focus(); 
        }
</script>

Y al hacer clic en el botón Enviar, se desplazará al campo no válido.

Para el botón de radio, agregue solo en una radio con el mismo nombre
Aquí está el ejemplo (jsfiddle)

  • Hola Abhilash. Veo que eres un usuario nuevo. Para su información, he formateado su código usando {} como código fuente. Esto es mejor que usar caracteres ` para resaltar texto y usar mucho
    para simular una nueva línea.

    – Schlebe

    31 oct.

  • @schlebe Muchas gracias

    – Abhilash Sharma

    13 jul.

.

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad