Search code examples
javascriptangularjsinputionic-frameworksoft-keyboard

Show/retain keyboard when password toggler is clicked


I have the following code, which results in a single password input being rendered with the toggler overlaying the visible input. The ion-toggle directive toggles visibility of the two inputs.

<label class="item item-input">
    <input placeholder="Password" ng-hide="showPassword" type="password">
    <input placeholder="Password" ng-if="showPassword" type="text">

    <ion-toggle ng-model="showPassword" toggle-class="toggle-energized">&nbsp;</ion-toggle>
</label>

When the toggler has focus, the software keyboard retracts. The user has to then tap back into the input to show the keyboard again.

How can I programmatically show/retain the keyboard when the toggler has focus? I've tried writing a directive to force focus back onto the inputs, but that feels clunky, and there's the issue of there being two inputs.

Here's a basic demo. You won't get a keyboard in a desktop browser, of course.

Thank you.


Solution

  • I created a directive which will give focus on password field when toogle button is clicked. Also refactored html of password field instead of two field it will only show one field.

    Markup

    <ion-content>
      <label class="item item-input" ng-init="pwd">
        <input placeholder="Password" ng-attr-type="{{showPassword? 'text': 'password'}}" 
          ng-model="pwd" do-focus="showPassword"/>
    
        <ion-toggle ng-model="showPassword" toggle-class="toggle-energized">&nbsp;</ion-toggle>
       </label>
    </ion-content>
    

    Directive

    .directive('doFocus', function(){
      return{
        link: function(scope, element, attrs){
          scope.$watch(attrs.doFocus,function(newValue, oldValue){
              element.focus();
          });
        }
      }
    });
    

    Forked Codepen

    Edit

    Directive has implemented in such a way that we are passing to toggling flag name to the showPassword inside directive attribute like do-focus="showPassword" so that directive will put $watch on the scope variable by using attrs.doFocus, watcher function gets fired and when you toggle the showPassword button. Basically this inner watcher is scope.$watch('showPassword'. Then the function first parameter would be newValue which is changed value & oldValue means the previous value of showPassword model. Here in your case newValue & oldValue are just redundant they are just not use anywhere, but if you wanted to do something on there change then they could help you.