Enable/Disable form buttons


#1

Hi.

I’m very new to Angular and Ionic and in all honestly coming from jQuery mindset I find it very difficult for now on how to work with things, but I’m sure I will get there.
Following this documentation I have created my first form, with FormBuilder.
My problem is that the submit button never gets enabled.
Here is my html code:

<form [formGroup]="authForm" (ngSubmit)="logForm()">
   
   <ion-item >
        <ion-label floating>First Name</ion-label>
        <ion-input type="text" value=""  formControlName="firstname"></ion-input>         
    </ion-item>

    <ion-item >
        <ion-label floating>Surname</ion-label>
        <ion-input type="text" value="" formControlName="surname"></ion-input>         
    </ion-item>

      
                  
    <ion-item >
        <ion-label floating>Mobile number</ion-label>
        <ion-input type="tel" value="" formControlName="tel"></ion-input>
    </ion-item>


    <button  ion-button block large type="submit" [disabled]="!authForm.valid">Save</button>

</form>

And here is the TS file:

import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';
import {Validators, FormBuilder, FormGroup } from '@angular/forms';



@Component({
  selector: 'firts_run',
  templateUrl: 'first_run.html'
})
export class FirstRun {
	 private authForm : FormGroup;
 
    constructor(private navController: NavController, private fb: FormBuilder) {
        this.authForm = this.fb.group({  
            'firstname': ['', Validators.compose([Validators.required, Validators.minLength(3)])],
            'surname': ['', Validators.compose([Validators.required, Validators.minLength(3)])],
            'tel': ['', Validators.compose([Validators.required, Validators.minLength(11), Validators.pattern('[0-9]{11}')])]
        });
  
    
    }
     
	  logForm(){
				console.log(this.authForm.valid); 
				console.log(this.authForm.value)
			 }
}

My problem is that the form never gets in a submittable state. I have tried to remove the [disabled]="!authForm.valid" attribute from the submit button which allowed me to submit the form, by doing that I could check that authForm.valid returns true when the fields are field in correctly so the validators are working as expected, yet the submit button stays disabled.

I’m very tempted to add javascript to it and manually update the state of the button, but I’m trying to do it the “Angular” way and I’m failing to understand what I’m missing.

Here is my ionic info output:

Cordova CLI: 6.5.0
Ionic Framework Version: 2.2.0
Ionic CLI Version: 2.2.1
Ionic App Lib Version: 2.2.0
Ionic App Scripts Version: 1.1.4
ios-deploy version: Not installed
ios-sim version: Not installed
OS: Windows 10
Node Version: v6.10.0
Xcode version: Not installed

Thank you for your help and support.


#2

Your tel pattern is pretty severe in that it only allows numbers, but aside from that I don’t see anything wrong in your code. I dropped it into a sample project, entered “abcdef” for both names and “01234567891” for mobile number, and the submit button enabled.


#3

Hi Robert.

Thanks for the feedback, than i really don’t understand what’s happening. I
will test on mobile as well, currently I was only testing in browser, but i
haven’t seen anything in documentation which indicated the fact that it
will only work on mobile.

Kind regards.
Emil Borconi-Szedressy


#4

It worked for me in Chromium, but if you enter anything but a number in the tel field (like spaces or parentheses or +/-, all of which people tend to enter in phone number fields), validation will fail.


#5

Hi.
I know about the Tel validation, i set it intentionally not to allow
anything but numbers. As said if i remove the disable and check the value
in console.log i can see true/false as expected so validation is working
correctly just the button status doesn’t get updated…

Kind regards.
Emil Borconi-Szedressy


#6

Try doing what I did. Create a new project and copy exactly the code you posted here into it (I put the guts of FirstRun into the HomePage of a stock tabs project). If it works as you expect, then you have a baseline to figure out any subtle differences from your real app. There’s what appears to be a typo in the selector (firts instead of first), but I doubt that’s relevant.


#7

Thank I might try just that because I’m out of any ideas… Thanks for taking the time to look into it!


#8

Ok i think i got it, my bad.

It looks that the button status only updates on focus/blur change I was
expecting it to update as you type, in this case I might use a different
approach, knowing my userbase I’m sure that will generate confusion between
them.

Once again thank you for the help and support.

Kind regards.
Emil Borconi-Szedressy


#9

I really don’t think so. I don’t have to switch field focus or anything. I hit backspace, the button becomes disabled. I type the 11th number, the button immediately becomes enabled.


#10

That is really odd than Robert.

I will start from scratch tomorrow with a clear head, it’s possible that
I’m missing the obvious.

Thank you again for the help.

Kind regards.
Emil Borconi-Szedressy


#11

Instead try this, It is already declared in the constructor


#12

You can also try to declare it as private authForm : any rather than a FormGroup type because you already called it a form group in html; Since you are in angular 2 you can also replace the (ngSubmit) by (submit)


#13

I see no compelling reason for weakening type declarations here.

Are you positive about that? The official docs use (ngSubmit).


#14

I am having a similar issue. My button is not toggling enabled when the form is valid.

Started a new project and copied over code from a working example.

Any luck figuring out your issue?


#15

Thank you everybody.
Once again thank you for your support. Without changing anything, it’s now working, however I did noticed that it’s not working in Desktop Chrome but it does on an Android phone. Even on Android phone the behaviour is strange. First time it only fires on blur/focus second time I load the page it’s working as expected.

I have started a new project and I only have 2 files in it, this one, and a “Landing” page with 4 buttons.

I think I will just fall back to validation on button press and display error message accordingly, the feature is nice but after spending 2 days trying to figure out what’s wrong I think it’s time to look at a workaround and move on with the project because I have plenty of other stuff to do.

Once again thank you for the advice/help & support.


#16
> Blockquote 
import { Component, OnInit } from '@angular/core';
import { IonicPage, NavController, NavParams, LoadingController, ToastController } from 'ionic-angular';
import { FormBuilder, Validators, FormGroup, AbstractControl } from '@angular/forms';
import { Firebase } from '@ionic-native/firebase';

/** /////// Page /////// */
import { TabsPage } from '../tabs/tabs';
import { SignupPage } from '../signup/signup';
import { UserCredentials } from '../../shared/interfaces';
import { DataService } from '../../shared/services/data.service';
import { AuthService } from '../../shared/services/auth.service';

/** /////// Start Code /////// */
@IonicPage()
@Component({
  selector: 'page-login',
  templateUrl: 'login.html',
})
export class LoginPage implements OnInit {
  backgrounds = [
    "assets/img/background/Bak4.jpg",    
  ]
  
  public loginForm: any;
  loginFirebaseAccountForm: FormGroup;
  email: AbstractControl;
  password: AbstractControl;
  
  constructor(
    public nav: NavController, 
    public navParams: NavParams,
    public fb: FormBuilder,
    public loadingCtrl: LoadingController,
    public toastCtrl: ToastController,
    public dataService: DataService,
    public authService: AuthService){ }

    ngOnInit() {
      this.loginFirebaseAccountForm = this.fb.group({
        'email': ['', Validators.compose([Validators.required])],
        'password': ['', Validators.compose([Validators.required, Validators.minLength(5)])]
      });
      this.email = this.loginFirebaseAccountForm.controls['email'];
      this.password = this.loginFirebaseAccountForm.controls['password'];      
    }      
  
  onSubmit(signInForm: any): void {
    var self = this;
    if (this.loginFirebaseAccountForm.valid) {
      let loader = this.loadingCtrl.create({
        content: 'Signing in firebase..',
        dismissOnPageChange: true
      });
      loader.present();
      let user: UserCredentials = {
        email: signInForm.email,
        password: signInForm.password
      };
      console.log(user);
      this.authService.signInUser(user.email, user.password)
      .then(function (result) {
        self.nav.setRoot(TabsPage);
      }).catch(function (error) {
      // Handle Errors here.
      var errorMessage = error.message;
      loader.dismiss().then(() => {
        let toast = self.toastCtrl.create({
          message: errorMessage,
          duration: 4000,
          position: 'top'
        });
        toast.present();
      });
    });
  }
}

register() {
  this.nav.push(SignupPage);  
}
}

#17
Had the same issue and got it to work like this Preformatted text
<form [formGroup]="loginFirebaseAccountForm" (ngSubmit)="onSubmit(loginFirebaseAccountForm.value)">
     <ion-item [class.error]="!email.valid && email.touched">`Preformatted text`
     <ion-label>
      <ion-icon name="ios-mail-outline" color="light"></ion-icon> 
      </ion-label>
      <ion-input type="text" value="" [formControl]="email" placeholder="البريد الالكتروني"></ion-input>
      </ion-item>
 <ion-item [class.error]="!password.valid && password.touched">
      <ion-label>
      <ion-icon dir="rtl" name="ios-eye-off-outline" color="light"></ion-icon> 
      </ion-label>            
      <ion-input type="password" [formControl]="password" placeholder="كلمة المرور"> </ion-input>
      </ion-item>
<!--Start Login In button -->    
<button ion-button type="submit" class="custom-button" [disabled]="!loginFirebaseAccountForm.valid">Sign in</button>
<!--End Login In button -->

#18

what about select tag .please tell me validation for select element