JavaScript

Web APIs

Eventos

Ejemplo

El siguiente ejemplo necesita que se añadan eventos a los elementos del formulario para completar su correcto funcionamiento:

  1. Mostrar el número de caracteres restantes que quedan al escribir el cuerpo.
  2. Previsualizar la imagen seleccionada, bien mediante fichero, o bien mediante URL.
  3. Antes de enviar el formulario, validar que se ha proporcionado una imagen válida.
<form id="formulario" action="/form" class="row g-3" method="post" enctype="multipart/form-data">
  <div class="col-12">
    <div class="row g-3">
      <div class="col-12">
        <label for="titulo" class="form-label">Título</label>
        <input type="text" class="form-control" id="titulo" name="titulo" maxlength="40" required>
        <div class="invalid-feedback">
          El título es obligatorio
        </div>
      </div>
      <div class="col-12">
        <label for="cuerpo" class="form-label">Cuerpo</label>
        <textarea class="form-control" placeholder="Máximo 220 caracteres" id="cuerpo" name="cuerpo" rows="3" maxlength="220" required></textarea>
        <div class="invalid-feedback">
          El texto del cuerpo es obligatorio
        </div>
      </div>
    </div>
  </div>
  <div class="col-12">
    <div class="row">
      <div class="col">
        <div class="row g-3">
          <div class="col-12">
            <label for="fichero" class="form-label">Subir imagen de fichero...</label>
            <input class="form-control" type="file" id="fichero" name="fichero" accept="image/png, image/jpeg, image/svg+xml">
            <div class="invalid-feedback">
              Selecciona un fichero de imagen: png, jpg, svg.
            </div>
          </div>
          <div class="col-12">
            <label for="url" class="form-label">Subir imagen de URL...</label>
            <input type="url" class="form-control" id="url" name="url">
            <div class="invalid-feedback">
              Indica una URL de imagen válida
            </div>
          </div>
        </div>
      </div>
      <div class="col-auto align-self-center text-center text-muted">
        <figure style="width: 11rem">
          <img id="imagen" class="p-2 border" style="max-width: 100%" alt="Sin imagen" onload="this.ok=true;" onerror="this.ok=false;">
        </figure>
      </div>
    </div>
  </div>
  <div class="col-12 mt-4">
    <input class="btn btn-primary" type="submit" value="Enviar">
  </div>
</form>
html { font-size: 60%; padding: 2rem; }
// Elementos a los que añadir eventos:
const cuerpo = document.getElementById('cuerpo');
const fichero = document.getElementById('fichero');
const url = document.getElementById('url');
const formulario = document.getElementById('formulario');
// Funciones a utilizar al capturar los eventos:
// 1. Para presentar el número de caracteres restantes
const caracteresRestantes = () =>
  document.querySelector('label[for="cuerpo"]').textContent = 
    `Cuerpo (${220 - cuerpo.value.length} caracteres restantes)`;
// 2. Para presentar la imagen de URL
const verImagenUrl = () => actualizaImagen(url.value);
const actualizaImagen = (src) => {
  document.getElementById('imagen').src = src;
  url.setCustomValidity('');
}
// 3. Para presentar la imagen de fichero
const verImagenFichero = () => {
  const reader = new FileReader();
  reader.onload = (event) => actualizaImagen(event.target.result);
  fichero.files && fichero.files.length && reader.readAsDataURL(fichero.files[0]);
};
// 4. Para saber si la imagen es correcta
const validaImagen = () => {
  const imagen = document.getElementById('imagen');
  const valida = imagen.getAttribute('src') || imagen.ok || false;
  url.setCustomValidity(valida ? '' : 'Imagen incorrecta');
  formulario.classList.add('was-validated');
  return valida;
};
// Tarea 1: actualiza el número de caracteres restantes a medida que se escribe el cuerpo
// Tarea 2: actualiza la imagen cuando cambie el campo de fichero o URL
// Tarea 3: comprueba que la imagen es válida antes de enviar el formulario

❓ Ejercicio 1: Escucha al evento keyup en el elemento cuerpo para que al introducir un caracter en él se actualice el número de caracteres restantes (llamando a la función caracteresRestantes).

❓ Ejercicio 2: Escucha al evento change en los elementos fichero y url para que cuando cambien su valor, se previsualice la imagen a su derecha (llamando a las funciones verImagenFichero y verImagenUrl, respectivamente).

❓ Ejercicio 3: Escucha al evento submit en el elemento formulario para validar que la imagen es correcta antes del envío (llamando a la función validaImagen). En caso de no ser válida, tendrás que parar el envío devolviendo false.

❓ Ejercicio 4: Si el usuario rellenara los dos campos para proporcionar la imagen, ambos se enviarían al servidor. Para evitar eso, cuando se seleccione una imagen por uno de ellos habría que resetear el otro campo. Añade al código del ejercicio 2: url.value = '' o fichero.value = ''.