ionic-team / ionic-framework

A powerful cross-platform UI toolkit for building native-quality iOS, Android, and Progressive Web Apps with HTML, CSS, and JavaScript.
https://ionicframework.com
MIT License
50.93k stars 13.51k forks source link

bug: IonButton type="submit" does not submit form when enter pressed in inputs #19368

Closed calendee closed 1 year ago

calendee commented 5 years ago

Bug Report

Ionic version: [x] @ionic/react 4.9.0-rc.2

Current behavior: IonButtons created with type="submit" do not submit the forms when a user presses the "enter" key in an input field.

You can see that the generated Shadow DOM input does NOT contain the type="submit" attribute.

IonButton Submit

Expected behavior: Standard HTML buttons created with type="submit" will automatically attempt to submit the form when the user presses "enter" in an input field. For accessibility, IonButtons inside a form should do the same.

Steps to reproduce: In the form below, press the "enter" key and observe that the form does not attempt to submit. Related code:

<form onSubmit={handleSubmit1}>
  <IonItem>
    <IonLabel>Ionic Input</IonLabel>
    <IonInput
      name="ionicInput1"
      id="ionicInput1"
      placeholder="Press enter in this field"
    />
  </IonItem>
  <IonItem>
    <label for="genericInput1">Generic Input</label>
    <input
      type="text"
      name="genericInput1"
      id="genericInput1"
      placeholder="Press enter in this field"
    />
  </IonItem>
  <IonButton type="submit">Submit</IonButton>
</form>

Working sample that demonstrate a regular <button type="submit">Submit</button> does properly submit the form and that an IonButton type="submit"/> does not:

Other information: None

Ionic info:

Ionic:

   Ionic CLI       : 5.2.5 (/Users/jn/.nvm/versions/node/v10.16.3/lib/node_modules/ionic)
   Ionic Framework : @ionic/react 4.9.0-rc.2

Utility:

   cordova-res : not installed
   native-run  : not installed

System:

   NodeJS : v10.16.3 (/Users/jn/.nvm/versions/node/v10.16.3/bin/node)
   npm    : 6.9.0
   OS     : macOS Mojave
5im0n commented 5 years ago

Issue already closed one year ago #15136

W3THS commented 5 years ago

I'm also experiencing this issue. Reading through #15136 is seems to suggest that this functionality only works when 1 input is on a form (which it does) and that is due to browsers implementation and not ionic. However, this does not explain why it works when you add a button with an input type of submit? If it was due to the browser it still shouldn't work?

riffbyte commented 4 years ago

This is not a bug with react or ionic, it is the way forms work on most of the browsers.

You can add a hidden submit input with absolute positioning like so: JSX: <input type="submit" className="submit-enter" /> CSS:

.submit-enter {
  position: absolute;
  visibility: hidden;
  left: -1000px;
}

This works on all desktop and mobile browsers

W3THS commented 4 years ago

Should setting the type of the ionic button to submit not cause the same functionality as having a hidden submit input though?

riffbyte commented 4 years ago

It probably should, if your button is inside the <form> tag. I assumed that you had a similar issue that I had, when submit button couldn't be place inside the form.

W3THS commented 4 years ago

Yes the button is inside the form. It looks like the setting doesn’t do anything when it comes to the shadow DOM

StanLindsey commented 4 years ago

Adding type="submit" does affect the shadon-dom correctly for me - but it doesn't allow the enter key to submit the form. A hidden input does work on the other hand. This feels wrong though.

xQuai commented 4 years ago

I would like to confirm that I also have this "error" in my project. I am also used to the fact that the form can be submitted by pressing the Enter key. Is there any news on this topic?

Versions:

Ionic:

   Ionic CLI       : 5.4.13 (C:\Users\<Username>\AppData\Roaming\npm\node_modules\ionic)
   Ionic Framework : @ionic/react 4.11.4

Capacitor:

   Capacitor CLI   : 1.3.0
   @capacitor/core : 1.3.0

Utility:

   cordova-res : not installed
   native-run  : not installed

System:

   NodeJS : v10.14.1 (C:\Program Files\nodejs\node.exe)
   npm    : 6.13.4
   OS     : Windows 10
Yohandah commented 4 years ago

I have the same issue with the following code, I am using the angular material lib, with a ion-button. Pressing enter in any of the fields doesn't submit the form.

<form (ngSubmit)="performLogin()" [formGroup]="loginForm">
    <mat-form-field appearance="outline" color="primary">
      <mat-label>Login</mat-label>
      <input matInput type="text" formControlName="login" placeholder="Login" required />
      <mat-error *ngIf="loginForm.get('login').invalid">
        {{ loginForm.get("login").hasError("required") ? "Required" : "" }}
      </mat-error>
    </mat-form-field>

    <mat-form-field appearance="outline">
      <mat-label>Password</mat-label>
      <input matInput type="password" formControlName="password" placeholder="Password" required />
      <mat-error *ngIf="loginForm.get('password').invalid">
        {{ loginForm.get("password").hasError("required") ? "Champ requis" : "" }}
      </mat-error>
    </mat-form-field>

    <ng-container *ngIf="!isProcessingLogin; then loginButton; else loading"></ng-container>

    <ng-template #loginButton>
      <ion-button [disabled]="!loginForm.valid" shape="round" type="submit">
        Login
      </ion-button>
    </ng-template>

    <ng-template #loading>
      <ion-spinner color="primary"></ion-spinner>
    </ng-template>
  </form>

I fixed it adding on my inputs : (keyup.enter)="loginForm.valid ? performLogin() : undefined" but it would be nice if it was working by default

Hesesses commented 4 years ago

Having the same problem with Ionic 5

<form [formGroup]="loginForm" class="login-form ion-no-padding" (submit)="login()">
          <ion-item>
            <ion-label position="stacked" translate>common.email</ion-label>
            <ion-input type="email" formControlName="email" [placeholder]="'login.placeholder_email' | translate"></ion-input>
          </ion-item>

          <ion-item>
            <ion-label position="stacked" translate>common.password</ion-label>
            <ion-input type="password" formControlName="password" [placeholder]="'login.placeholder_password' | translate" ></ion-input>
          </ion-item>

          <div class="ion-text-right">
            <ion-button type="submit" shape="round" size="large"><ion-icon name="arrow-forward-outline"></ion-icon></ion-button>
          </div>
        </form>

Pressing enter doesnt fire the submit, clicking the button works

SvenBudak commented 4 years ago

Yeah i am also confused. When i change <ion-button type="submit"> to <button type="submit"> then it works well. I saw that this issue was already present in Ionic 4... Isnt it time to fix this? ;)

AntonSimanikhin commented 4 years ago

Same problem with Ionic 5 React. I thought having this type available for the IonButton component is the ability to submit on press Enter key. When is this going to be resolved?

mobileias commented 4 years ago

@liamdebeasi sir can you help us, we have same problem into ionic angular latest 5.2.2 also, <ion-button color="danger" size="large" expand="block" type="submit" id="login_button" [disabled]="is_disable">SIGNIN&nbsp;<i class="fas fa-sign-in-alt"></i></ion-button>

When click on button it submit form but if press enter button then form not submitted.

Thanks in advance

liamdebeasi commented 4 years ago

I am able to reproduce this, and the bug does not seem to be limited to just Ionic React apps.

The reason why this is happening is buttons in the Shadow DOM are not picked up by the parent form. In this case, clicking the button and pressing "Enter" would normally not submit the form.

We added some code to submit the form when you click the button: https://github.com/ionic-team/ionic/blob/master/core/src/components/button/button.tsx#L155

The issue still persists for pressing "Enter". I will look into adding a fix for this in Ionic Framework, but for now you can add a keyup listener on the form to work around this limitation.

Lindsor commented 4 years ago

This seems to be an issue with the way WebComponents/shadow-dom work in general (they are working on a solution). Adding the hidden input field seems to work, albeit its pretty hacky. From a consistency perspective i would want Ionic button to work exactly the same as native button, so what if ionic adds the hidden input submit button outside the shadow DOM until the spec comes up with a permanent fix. This inconsistency should be abstracted away from the library consumer.

hoi4 commented 3 years ago

Using an ion-button with type="submit" inside a form with only one input works. As soon as there is more than one input inside the form, it doesn't work anymore. 🤔

brendensoares commented 3 years ago

Why not make the web component nest the shadowed component and add the work around submit button?

<submit-button>
  <button class="hacky-hack" />
  <ion-button />
<submit-button>
.hacky-hack {
  visibility: hidden;
  position: absolute;
  position: -999px;
}

This would allow the quickfix of adding the hidden <button> while not requiring any action on the consuming app's part.

CONFIRMED this does work. Create a component that has shadow DOM disabled with child components as shown above. This is much cleaner than have a global style with a hidden button element in all forms.

The ionic framework could tweak the code for ion-button to do this out of the box until the W3C defines a solution and the browsers implement it.

See also https://stackoverflow.com/questions/54370436/can-i-get-a-button-in-shadowdom-to-submit-a-form-not-in-shadowdom

eddiechok commented 3 years ago

any updates?

adrm commented 3 years ago

This keeps happening for us, but strangely only for tactile events from touch screens or simulated touch screens through browser dev tools. It works fine for mouse clicks. Quite worrysome that the submit button in a mobile UI framework does not do its only job in a mobile device.

Maybe the easiest and least problematic fix is to not use shadow DOM for this component, the same as other form-related components like input?

stewones commented 3 years ago

this still an issue as of sep 2021

I'm having to fake a submit button inside the form as workaround

godenji commented 2 years ago
<form
  (submit)="save()"
  (keyup.enter)="save()"
  ....
>

Ughhh, any chance this can be solved at the framework level?

Peppering forms with (keyup.enter)="save()" is kind of annoying.

Muskos commented 2 years ago

Also as a hack: You can add <input type="submit"/> and the form will submit by 'enter'

snblackout commented 2 years ago

I can't believe a fake submit button is the official solution to this. What a hack.

liamdebeasi commented 2 years ago

Thanks for the feedback everyone. We are bumping this up in priority internally. Not ETA on a release date yet, but we will update this thread when we have more to share.

thetaPC commented 1 year ago

Thanks for the issue! This has been resolved via PR https://github.com/ionic-team/ionic-framework/pull/27790 and will be available in an upcoming release of Ionic.

thetaPC commented 1 year ago

The fix has been released on v7.1.4!