Form submit in footer

What is the best way to handle having a form in the content, but the submit/save button in the footer? For example, I’d like to have something like this:

<ion-content>
  <form>
    <ion-input [(ngModel)]="something" name="someName"></ion-input>
  </form>
</ion-content>
<ion-footer>
  <button ion-button full type="submit">Save</button>
</ion-footer>

Now obviously, this doesn’t work, is there a best-practive for this kind of case?

2 Likes

Is there a specific need for it to be a submit button? I would just do something like:

<button ion-button type="button" (click)="submitForm()">
2 Likes

By using the submit type, it prevents the form from accidentally being submitted with validation errors.

Can’t the submitForm method in the component check to see if the form is valid or not and do whatever is needed?

I don’t know best practices, but one solution would be to set the ``[disabled] property of the button to be true whenever the form validators are not all true.

I try to only do that on very small forms, because if the form has to scroll, sometimes the invalid field isn’t in view and it can be confusing for the user to figure out what’s wrong. My typical idiom is to have a touchedAndInvalid method in the component that can be used to trigger error classes and messages in the template. Then I put a submitAttempted boolean in the component which makes touchedAndInvalid consider all controls to have been touched. The submit function checks if the form is valid, and if not, sets submitAttempted to true and returns immediately. This will cause all error conditions on missing required fields to pop.

3 Likes

I like your structure @rapropos. I’ll tell you though, my biggest challenge (and there are a lot) in this new Ionic world is designing useful UI pages that require no scrolling on any recent device. Now I’m wondering if your structure could be better even if no scrolling is needed, for example in the case of security information you’d want to erase quickly, like CCV numbers.

How would you do that? You don’t have a reference to the form.

I build the form using FormBuilder in the constructor of the component, so the component has a reference to it.

Ahh I see. I’ve just been doing the markup validation. I’ll have to look into the FormBuilder.

This worked for me, hopefully it will work for your needs:

<ion-content padding>
  <form (ngSubmit)="login()" #loginForm="ngForm">
    <ion-list>
      <ion-item>
        <ion-label floating>Email</ion-label>
        <ion-input type="text" [(ngModel)]="form.email" name="email"></ion-input>
      </ion-item>
      <ion-item>
        <ion-label floating>Password</ion-label>
        <ion-input type="password" [(ngModel)]="form.password" name="password"></ion-input>
      </ion-item>
    </ion-list>
  </form>
</ion-content>

<ion-footer>
  <ion-toolbar>
    <button ion-button block full large clear [disabled]="!loginForm.form.valid" (click)="loginForm.ngSubmit.emit()">Login</button>
  </ion-toolbar>
</ion-footer>
7 Likes

Thank you.It works for me :slight_smile:

why we use emit() function

It is not a good option to have a form in footer section. Although it is feasible to implement form in Footer, however it is not a good user perspective to have form in footer section.

hi rapropos can u please give the example code for this? i need it immediately please help me…

I can’t seem to get this to work. on Ionic 3.

A little different example that I have.

<ion-content>
  <form  #testForum="ngForm" novalidate>
    <ion-input type="text" [ngModel]="inputOne" name="boxOne"></ion-input>
  </form>
</ion-content>
<ion-footer>
  <button type=submit [disabled]="isDisabled || testForum.controls.boxOne?.invalid"
               ion-button 
               (click)="save(testForum)" > {{'SAVEBTN'|translate}} </button>    
</ion-footer>

The TestForum is empty in the footer so anytime the input has a value it fails with "Cannot read property ‘controls’ of undefined. The footer doesn’t see the form.

Any idea?

I made a suggestion in the second post of the thread. The answer to why it couldn’t be adopted was validation. As your example seems to be disavowing validation, is there another reason why you cannot follow that suggestion and just make your button in the footer an ordinary button?

The problem was controlling of the valid state of the button.

This code – testForum.controls.boxOne?.invalid
Fails when its not inside the forum.

I was able to use the footer values in the forum. Not sure if this is ideal.
The new end of my code is something like this.

<ion-footer>
 <button type=submit [disabled]="isDisabled || testForum.controls.boxOne?.invalid"
               ion-button 
                (click)="save(testForum)" > {{'SAVEBTN'|translate}} </button>    
 </ion-footer>
 </form>
 </ion-content>

Seems to work fine.