Exposición de campos de formulario adicionales a través de botones de opción marcados | Programar Plus

Hay un :checked pseudoclase en CSS. A menudo pienso en él en relación con el “truco de casilla de verificación”, en el que lo usa en una casilla de verificación oculta con el ~ combinador general de hermanos para simular el comportamiento de alternancia sin ningún JavaScript. Es un truco porque ahora tiene estos elementos de formulario perdidos en la página que realmente no son para un formulario. No es un gran problema, ya que estoy seguro de que puede solucionarlo en términos de accesibilidad, pero hay una manera de usar este mismo concepto de una manera totalmente no pirateada, ¡en una forma real!

Utilicé esta técnica en el formulario de publicación de trabajos de CodePen para revelar solo campos de formulario adicionales según sea necesario.

Vayamos al grano con una demostración:

Vea el Pen LEGXOK de Chris Coyier (@chriscoyier) en CodePen.

El HTML

Digamos que estamos usando botones de radio aquí. Se puede “marcar” (:marcar) una casilla de verificación o un botón de opción. El div que vamos a revelar tiene que ser posterior y un elemento hermano (dentro del mismo padre).

<input type="radio" name="choice-animals" id="choice-animals-dogs">
<label for="choice-animals-dogs">I like dogs more</label>
    
<div class="reveal-if-active">
  Anything you want in here.
</div>

El CSS

De forma predeterminada, ese div “revelar si está activo” estará oculto. Vamos a hacer eso de varias maneras diferentes. No todos son necesarios solo para ocultarlo, pero jugarán un factor en cómo se revela.

.reveal-if-active {
  opacity: 0;
  max-height: 0;
  overflow: hidden;
}

Ahora, cuando se marca un botón de radio o una casilla de verificación en el mismo nivel en que se marca, revela:

input[type="radio"]:checked ~ .reveal-if-active,
input[type="checkbox"]:checked ~ .reveal-if-active {
  opacity: 1;
  max-height: 100px; /* little bit of a magic number :( */
  overflow: visible;
}

Eso funciona, pero hagamos la transición de todo estilo elegante y Sass it up:

.reveal-if-active {
  opacity: 0;
  max-height: 0;
  overflow: hidden;
  transform: scale(0.8);
  transition: 0.5s;
  input[type="radio"]:checked ~ &,
  input[type="checkbox"]:checked ~ & {
    opacity: 1;
    max-height: 100px;
    overflow: visible;
    padding: 10px 20px;
    transform: scale(1);
  }
}

Eso hará el truco.

¿Qué pasa con los campos obligatorios?

Esto se vuelve un poco engañoso. Digamos que en los divs “revelar si está activo” está poniendo más campos de formulario (ese es el punto realmente). Es posible que desee solicitar un campo si se revela, pero no si no lo es. Un campo obligatorio que está oculto aún es obligatorio, por lo que no puede simplemente poner el required atribuya en esos campos ocultos y olvídese, para no meterse en una situación desagradable de UX.

Manejo esto poniendo una clase “requerir si está activo” en la entrada, y una data-* atributo que hace referencia al ID con el que está emparejado.

... 

<div class="reveal-if-active">
  <label for="which-dog">Good call. What's the name of your favorite dog?</label>
  <input class="require-if-active" type="text" id="which-dog" name="which-dog" data-require-pair="#choice-animals-dogs">
</div>

Luego, cuando se carga la página, y cada vez que una casilla de verificación o un botón de radio cambia de valor, ejecuta JavaScript para determinar si esa entrada debe ser necesaria o no.

var FormStuff = {
  
  init: function() {
    // kick it off once, in case the radio is already checked when the page loads
    this.applyConditionalRequired();
    this.bindUIActions();
  },
  
  bindUIActions: function() {
    // when a radio or checkbox changes value, click or otherwise
    $("input[type="radio"], input[type="checkbox"]").on("change", this.applyConditionalRequired);
  },
  
  applyConditionalRequired: function() {
    // find each input that may be hidden or not
    $(".require-if-active").each(function() {
      var el = $(this);
      // find the pairing radio or checkbox
      if ($(el.data("require-pair")).is(":checked")) {
        // if its checked, the field should be required
        el.prop("required", true);
      } else {
        // otherwise it should not
        el.prop("required", false);
      }
    });
  }

};

FormStuff.init();

Sí, se requiere poco JavaScript. También podríamos ocultar/mostrar a través de JavaScript, pero CSS es bastante adecuado para ello. Incluso podría decir que es una preocupación de diseño, por lo que pertenece a CSS. #debate

Aquí está esa demostración de nuevo.

peculiaridad extraña

Becca Rice me escribió para decirme que hay un error con el material CSS que revela los campos adicionales específicamente en UI WebView en iOS 9 y versiones anteriores. No directamente en Safari, sino en aplicaciones que usan el WebView incorporado para mostrar la web dentro de sus propias aplicaciones. Incluso, en el momento de escribir este artículo, toda la aplicación de Chrome en iOS usa UI WebView.

El error es: puede hacer clic en un botón de opción para expandir los campos adicionales. Tal vez incluso haga clic en uno diferente para cerrar los originales y abrir un nuevo conjunto de campos adicionales, pero luego deja de funcionar. Puede continuar alternando las radios, pero ya nada cambia. No está claro si el botón de radio solo cambia de estado visualmente pero no cambia de valor, o si el CSS simplemente no reacciona al nuevo :checked valor.

Ambos lo confirmamos. Hay una aplicación solo para probar UI WebView frente a WK WebView.

(Visited 4 times, 1 visits today)