Búsqueda de sitios web

Javascript/Typescript - Evitar que el formulario se reinicie al enviar


Tengo una clase simple en TypeScript y quiero mostrar los resultados de la entrada al enviar. Aunque esta pregunta ya ha sido hecha, event.preventDefault() no está funcionando. Tal vez puedas darme algunos consejos.

class LoginPanel {

    public appDiv: HTMLElement = document.getElementById('app');

    constructor() {
        this.setForm();
        let btn = document.getElementById('loginButton');
        btn.addEventListener('submit', (event) => {event.preventDefault(); this.submitForm()});
    }

    public setForm(): void {
        this.appDiv.innerHTML = `<form id="loginForm" class="form-signin mt-5">
      <div class="text-center">
      <h1 class="h3 mb-3 font-weight-normal">Please sign in</h1>
      </div>
      <label for="inputEmail" class="sr-only">Email address</label>
      <input type="email" id="inputEmail" class="form-control" placeholder="Email address" required="" autofocus="">
      <label for="inputPassword" class="sr-only">Password</label>
      <input type="password" id="inputPassword" class="form-control mt-1" placeholder="Password" required="">
      <button id="loginButton" class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button>
    </form>
    `;
    }

    public submitForm(): void {
        const elementFirst: HTMLElement = document.createElement('pre');
        const elementSecond: HTMLElement = document.createElement('pre');

        elementFirst.innerHTML = 'email: ' + document.getElementById('loginForm')[0].value;
        document.getElementById('loginForm').appendChild(elementFirst);

        elementSecond.innerHTML = 'password: ' + document.getElementById('loginForm')[1].value;
        document.getElementById('loginForm').appendChild(elementSecond);
    }

}

new LoginPanel();

Respuesta #1

Cuando envías un formulario, envías todos sus valores, no solo un botón.

Por lo tanto, el lugar correcto para prevenir el valor predeterminado es dentro del propio elemento formulario, no en sus botones.

constructor() {
    this.setForm();
    const form = document.getElementById('loginForm');
    form.addEventListener('submit', (event) => {event.preventDefault(); this.submitForm()});
}

Puedes ver que eso funcionaría en este CodePen.

Respuesta #2

Puedes usar onsubmit="return false" en el formulario en su lugar:

<form id="loginForm" class="form-signin mt-5" onsubmit="return false">
  <div class="text-center">
  <h1 class="h3 mb-3 font-weight-normal">Please sign in</h1>
  </div>
  <label for="inputEmail" class="sr-only">Email address</label>
  <input type="email" id="inputEmail" class="form-control" placeholder="Email address" required="" autofocus="">
  <label for="inputPassword" class="sr-only">Password</label>
  <input type="password" id="inputPassword" class="form-control mt-1" placeholder="Password" required="">
  <button id="loginButton" class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button>
</form>

¿Cuál es la diferencia?

La diferencia es que return false; lleva las cosas un poco más lejos en el sentido de que también evita que ese evento se propague (o "burbujee") en el DOM. Lo que quizá no sepas es que cada vez que ocurre un evento en un elemento, ese evento también se activa en cada elemento padre.

Alternativamente, podrías usar event.stopPropagation en el elemento del formulario:

constructor() {
  this.setForm();
  let btn = document.getElementById('loginButton');
  btn.addEventListener('click', (event) => { this.submitForm()});
  let form = document.getElementById('loginForm');
  form.addEventListener('submit', (event) => { event.preventDefault(); event.stopPropagation; });
}

Ver: ¿Cuál es la diferencia entre e.preventDefault(); y return false?