1
votes

Using Ionic 3, I have created a prompt alert that is triggered by a function resetPassword(). I want its only input to be focused and open the iOS / Android keyboard when displayed.

This is the function:

  resetPassword() {
    let prompt = this.alertCtrl.create({
      title: 'Reset Password',
      message: "Enter your email address to receive a password reset email",
      inputs: [
        {
          name: 'email',
          placeholder: 'Email',
          type: 'email'
        },
      ],
      buttons: [
        {
          text: 'Cancel',
          handler: data => {
            console.log('Cancel clicked', data);
          }
        },
        {
          text: 'Send',
          handler: data => {
            console.log('Send clicked');    
          }
        }
      ]
    });
    prompt.present().then(() => {
      console.log("presenting")
      const firstInput: any = document.querySelector('ion-alert input');
      console.log("alert input", JSON.stringify(firstInput))
      firstInput.focus();
      return;
    });
  }

Using .focus() seems to not be working. Logging JSON.stringify(firstInput) displays the following on iOS:

{
  "__zone_symbol__ngModelChangefalse": [{
    "type": "eventTask",
    "state": "scheduled",
    "source": "HTMLInputElement.addEventListener:ngModelChange",
    "zone": "angular",
    "runCount": 0
  }],
  "__zone_symbol__inputfalse": [{
    "type": "eventTask",
    "state": "scheduled",
    "source": "HTMLInputElement.addEventListener:input",
    "zone": "angular",
    "runCount": 0
  }],
  "__zone_symbol__blurfalse": [{
    "type": "eventTask",
    "state": "scheduled",
    "source": "HTMLInputElement.addEventListener:blur",
    "zone": "angular",
    "runCount": 0
  }],
  "__zone_symbol__compositionstartfalse": [{
    "type": "eventTask",
    "state": "scheduled",
    "source": "HTMLInputElement.addEventListener:compositionstart",
    "zone": "angular",
    "runCount": 0
  }],
  "__zone_symbol__compositionendfalse": [{
    "type": "eventTask",
    "state": "scheduled",
    "source": "HTMLInputElement.addEventListener:compositionend",
    "zone": "angular",
    "runCount": 0
  }]
}

What can I do to fix this?

2
so unfortunately this trick that you have will only work on Android, since iOS 10+ or so Apple wants only for user to set focus on input elements explicitly and would not support programmatic set of focus on elements going forward. Thinking there is to prevent various malicious intents. But yeah it sux as some of good practices with UX suffer too;/ - Sergey Rudenko

2 Answers

0
votes

You can apply cssClass to input. In your code,

inputs: [
  {
     name: 'email',
     placeholder: 'Email',
     type: 'email'
     cssClass: 'customClass'
  },
]

And apply css properties to this custom class in scss file.

.customClass:focus {
   -css properties here-
}
-1
votes

alert.present(); returns a Promise. So we can simply add the following lines to achieve the expected behaviour.

alert.present().then(() => {
const firstInput: any = document.querySelector('ion-alert input');
firstInput.focus();
return;

});

Due to the fact, that querySelector(); allways takes the first result, it will focus the first input element, which was found inside the presented alert.

If You want to focus the second, third, etc. You should change querySelector('ion-alert input'); to querySelectorAll('ion-alert input')[1], 1 as a placeholder for the second input element.

And in your config.xml file dont forget to add this line

<preference name="KeyboardDisplayRequiresUserAction" value="false" />