ionic-framework: Implicit form submit doesn't work in Ionic 4

Bug Report

@ionic/core@4.0.0-beta.11 @stencil/core@0.12.4

Describe the Bug

I created a login form (started with the Ionic Stencil PWA Starter) using form, ion-input and ion-button. When I try to implicitly submit the form by pressing enter in one of the inputs, the form does not get submitted, despite my button having the type="submit" attribute set.

Steps to Reproduce

  1. Create a form
  2. Focus on one of the inputs
  3. Press enter
  4. Nothing happens

Related Code

Fiddle: http://jsfiddle.net/ok8zn5e6/2/

<ion-list>
  <form onSubmit={e => this.submitLogin(e)}>
    <ion-item>
      <ion-label position="stacked">
        Email
      </ion-label>
      <ion-input name="username" type="email" placeholder="you@domain.com" required autofocus />
    </ion-item>
    <ion-item>
      <ion-label position="stacked">
        Password
      </ion-label>
      <ion-input name="password" type="password" placeholder="********" required />
    </ion-item>

    <ion-button type="submit" color="primary">
      <ion-icon slot="end" name="log-in" />
      Log In
    </ion-button>
  </form>
</ion-list>

Expected Behavior

The implicit form submit should work because the form contains a button with type="submit".

Additional Context

http://stonefishy.github.io/blog/2015/06/30/implicit-submission-of-form-when-pressing-enter-key/

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 3
  • Comments: 16 (12 by maintainers)

Commits related to this issue

Most upvoted comments

@simonhaenisch Thanks for your response. I will not open this issue because we already have two which seperate this issues very well:

#15136: Button does not trigger ngSubmit #16498: Prev / Next button on mobile keyboard

So it’s not useful to have different issues opened for the same topic. Is that okay for you 😃

I think that a more permanent solution may be in order – this is standard / expected behavior. This would require implementing a (keyup.enter) on every form input that performed the form submission and dismissed the keyboard as necessary. You would also have to duplicate the form submission handling for (ngSubmit) because users could still tap the submit button itself.

+1, As pointed out by @simonhaenisch , the native keyboard behavior is totally different, so a framework-based workaround is needed in order to save the UX with forms.

@mhartington would it be possible to expose the shadow option of the ion-input component decorator like:

<ion-input shadow={false}></ion-input>

I know it’s not super trivial, but I really don’t see a point in enabling Shadow DOM for this if there is so many built-in benefits being lost. Or as an alternative, add a shadow option to setupConfig(config: IonicConfig) to globally opt out of Shadow DOM.

Or maybe a better way to go is to add a ion-form component that encapsulates all inputs within the form’s Shadow DOM but doesn’t have seperate Shadow DOMs for each input?

So there’s a few things going on here.

  1. Native inputs, submit inputs, and browser built-ins

So vanilla use-case where things work

<form onsubmit="checkData(event)">
  <input type="text" required>
  <input type="password" required>
  <input type="submit">
</form>

In this case, the form and inputs will submit on enter because of the built in HTML FormValidation/handling. This is something built into the browser, just as long as the form is valid and there is a valid handler for onsubmit

  1. Ionic inputs and ionic button

Use case where things do not work

<form onsubmit="checkData(event)" novalidate>
  <ion-input type="email" required></ion-input>
  <ion-input type="password" required></ion-input>
  <ion-button type="submit" color="primary">
    Log In
  </ion-button>
</form>

Why this does not work is a mixture of Custom Elements and Shadow DOM encapsulation. Since the native inputs in ion-input are encapsulated with shadow DOM, the built in browser form validation will not be able to work here. Also, because the ion-input essentially extend a base div element, there’s no built in behavior for it to follow.

Why did this work in early V4 release and V3?

This worked in earlier release and in V3 because we did not use shadow DOM, so the native inputs were reachable by the browser own built-in functionality.

Ways to deal with this: In a framework landscape, like Angular, you’d have a keyup handler to list for enter. In vanilla JS, you’d have to wire that logic up yourself.