1

I need to use ng2-currency-mask input mask with Ionic 3 app. They have given a fix for input focus issue which is in the Ionic app. I cannot understand what I have to do here. Can you tell me how to use it?

child component

.html

<div>
    <input currencyMask type="tel" [(ngModel)]="value" [id]="'yourInputId' + index" 
    (focus)="scrollTo(index)" />
</div>

.ts

import { Content } from 'ionic-angular';

export class...

    @ViewChild(Content) content: Content;

    scrollTo(index) {
        let yOffset = document.getElementById('yourInputId' + index).offsetTop;
        this.content.scrollTo(0, yOffset + 20);
    }

Can you tell me what was this [id]="'yourInputId' + index"? How can I set that on my Ionic app?

You can read more about it here.

Update:

I have tried like this.But compile time error on template due to index. I don't have any for loops here.

 <input currencyMask type="tel" [ngModel]="data?.budget" 
 [options]="{ prefix: '', thousands: ',', decimal: '' }" 
 formControlName="budget" 
 ngModelChange)="data.budget=$event;calculateContingency()" 
 [id]="'yourInputId' + index" (focus)="scrollTo(index)"/>

My component structure:

parent.html

<ion-content class="project">
  <ion-grid>
    <ion-row class="details">
      <project [data]="data"></project>// above code is in this child componet
    </ion-row>

  </ion-grid>
</ion-content>
Sampath
  • 63,341
  • 64
  • 307
  • 441
  • I am guessing that yourInputId is a unique code you give to the input tag and index is from ngFor, in case you have one. The whole thing to identify the DOM element by an unique id – Vega Sep 13 '17 at 07:06
  • yes the index i think is for a loop array of phones as (home, work, mobile) with the same id but looking like this : ['phone_0', 'phone_1', 'phone_2'] as @Vega said if you have one just put the id name in your input phone. Regards –  Sep 13 '17 at 07:13
  • Actually, I don't have any `ngFor` here. Just an `input` contol. Then how can I set that? @headmax Please see my update too: – Sampath Sep 13 '17 at 07:18
  • Please see my **Update** @Vega – Sampath Sep 13 '17 at 07:19

3 Answers3

1

Can you try this : (if your input id="mobile")

<ion-input currencyMask type="tel" [ngModel]="data?.budget" 
[options]="{ prefix: '', thousands: ',', decimal: '' }" 
formControlName="budget" 
ngModelChange)="data.budget=$event;calculateContingency()" 
[id]="'mobile0'" (focus)="scrollTo(0)"></ion-input>

I think the index is an array from phones (home, mobile, work) is about you id name + index (phone). Setting the id in your context just add 'mobile' and for the index put only 0 for a try i didn't tested that modules. Regards

  • I did that. But it shows this error. Any clue? I have scrollTo() method on ts file. https://i.imgur.com/HjBam37.png – Sampath Sep 13 '17 at 07:28
  • here the list to setting ion-input https://ionicframework.com/docs/api/components/input/Input/ and this is the reason why you need an index –  Sep 13 '17 at 07:31
  • But they didn't use `ion-input` no? Just an `input` no? – Sampath Sep 13 '17 at 07:37
  • Try if you can add if you didn't the input list or change (the scroll method is to focus to the input mobile) –  Sep 13 '17 at 07:39
  • Now the problem is here `this.content.scrollTo(0, yOffset + 20);`. `this.content` shows `undefine` that is why this error? why? https://i.imgur.com/HjBam37.png – Sampath Sep 13 '17 at 07:52
  • add this at the end (focus)="ionFocus(0)"> –  Sep 13 '17 at 07:55
  • Please see my component structure above. I think that is why I cannot access parent `content` no? How to do that? – Sampath Sep 13 '17 at 07:56
  • this .. need to be placed in the –  Sep 13 '17 at 08:09
  • Thanks for the support. But it is not working. May be a component issue. Disappoint :( – Sampath Sep 13 '17 at 09:00
  • Sorry for that bad support i will try it myself to be aware ;) thanks. –  Sep 13 '17 at 09:02
  • Nope, You gave very good support. problem with the 3rd party directive. I have logged as an issue : https://github.com/cesarrew/ng2-currency-mask/issues/18#issuecomment-329053852 – Sampath Sep 13 '17 at 09:04
  • 1
    ;) hope you got a commit fix soon on git, regards. –  Sep 13 '17 at 09:06
1

Try this syntax:

HTML:

     <ion-input currencyMask type="tel" [ngModel]="data?.budget" 
     [options]="{ prefix: '', thousands: ',', decimal: '' }" 
     formControlName="budget" 
     ngModelChange)="data.budget=$event;calculateContingency()" 
     id="yourInputId" (focus)="scrollTo()"></ion-input>

TypeScript:

 scrollTo() {
        let yOffset = document.getElementById('yourInputId').offsetTop;
        this.content.scrollTo(0, yOffset + 20);
    }
Vega
  • 27,856
  • 27
  • 95
  • 103
  • Now no errors. But it doesn't allow me to click it since not an `ion-input`. Any clue? But they gave above solution is for that I think. But not working. – Sampath Sep 13 '17 at 07:35
  • Replace by ? – Vega Sep 13 '17 at 07:48
  • It shows this error: https://i.imgur.com/HjBam37.png .Please see my component structure above. Due to that, I cannot access parent's `content`. How can I do that? it shows `undefine` here `this.content.scrollTo(0, yOffset + 20);`. – Sampath Sep 13 '17 at 07:57
  • Either 1. set a wrapper on the input and give it a local template variable name #Content 2. Move ...scrollTo to the parent and in the child call it with an output and set #Content on the child tag. I hope being understandable :) – Vega Sep 13 '17 at 08:03
  • @viewchild Content is not defined until you set #Content somewhere – Vega Sep 13 '17 at 08:07
  • Actually, I do not have `content` class on the child component.Just a `div` element. You can see updated post above. But parent component has. So how can I use `this.content.scrollTo(0, yOffset + 20);` method? Hope I don't need `content` here. Any clue? – Sampath Sep 13 '17 at 08:13
  • Content is a reference to a DOM element with #Content template variable on it which will receive the scroll. It needs to be a wrapper element of the input (thus + 20 on the offset) – Vega Sep 13 '17 at 08:15
  • 1
    I will make a stackbliz to try to reproduce it – Vega Sep 13 '17 at 08:17
  • Yes, You're right. Then can you modify your code to reflect it? Now you know about my component structure. – Sampath Sep 13 '17 at 08:17
  • My problem here is `this.content` shows `undefine`. – Sampath Sep 13 '17 at 08:20
  • I am still trying to make the mask work in the demo, but I updated my post – Vega Sep 13 '17 at 08:31
  • Thanks. Actually, if you can give me a clue to avoid `this.content` `undefine` issue then I can continue. – Sampath Sep 13 '17 at 08:34
  • If don't have the issue of the input hidden by the keyboard, you can forgo the (focus)=.... . Otherwise, just putting #Content on the wrapper div, as in my updated post, you should be good. Doesn't it work? – Vega Sep 13 '17 at 08:38
  • Did you create an `Ionic 3` project or ? – Sampath Sep 13 '17 at 08:41
  • I did but the mask dosn't work. Have import { Content } from 'ionic-angular'; ? I haven't seen that before in the doc. And they forgot to add {import ViewChild} from "@angulare/core" – Vega Sep 13 '17 at 08:48
  • Do you have ? Content in fact is reference to that element, my bad: https://ionicframework.com/docs/api/components/content/Content/ – Vega Sep 13 '17 at 08:54
  • Yes, When I do not use ion-input I cannot click the element. But when I used it then it shows this error. Horrible :( https://i.imgur.com/cROsswH.png – Sampath Sep 13 '17 at 08:57
  • The same as in my demo :( – Vega Sep 13 '17 at 08:58
  • Please see this post too: https://stackoverflow.com/questions/46192659/access-parent-content-within-child-component-or-better-way – Sampath Sep 13 '17 at 08:59
  • Welcome :) Should you report to the mask writting team? If you need a quick startup: https://stackblitz.com/edit/ionic-pifdy2?file=app%2Fapp.component.ts – Vega Sep 13 '17 at 09:03
  • I did. But I'll put a new issue with more details later. Thanks. https://github.com/cesarrew/ng2-currency-mask/issues/18#issuecomment-329053852 – Sampath Sep 13 '17 at 09:06
  • I have tried another directive. That too not working with Ionic 3. This is the 2nd day more than 15+ Hours for this simple thing. Sorry for me :( See that too : https://stackoverflow.com/questions/46189208/input-mask-with-thousand-separator-ionic-3 – Sampath Sep 13 '17 at 09:09
0

Actually, I was able to make a directive and it seems to work pretty well on desktop, iOS, and android.

No hacks required.

create IonMask directive by

ionic g directive

then replace it with this:

// Angular
import { Directive, Input } from '@angular/core';

// Ionic
import { IonInput } from '@ionic/angular';

// Rxjs
import { takeUntil } from 'rxjs/operators';
import { Subject } from 'rxjs';

// Text-mask
import { createTextMaskInputElement } from 'text-mask-core';

/**
 * ion-mask directive, based on text-mask module
 */
@Directive({
  selector: '[ionMask]',
  providers: [IonInput],
})
export class IonMaskDirective {

  @Input('ionMask') 
  private mask            : Array<any>    = [];
  private onDestroy       : Subject<void> = new Subject<void>();

  constructor(public ionInput: IonInput) {}

  public ngOnInit() {
    this.configureInput();
  }

  public ngOnDestroy() {
    this.onDestroy.next();
  }

  public async configureInput() {
    const input       = await this.ionInput.getInputElement();
    const maskedInput = createTextMaskInputElement({
      inputElement  : input,
      mask          : this.mask,
      guide         : false
    });
    this.ionInput
      .ionChange
      .pipe( takeUntil( this.onDestroy ) )
      .subscribe( ( event: CustomEvent ) => {
        const { value } = event.detail;
        maskedInput.update(value);
        this.ionInput.value = input.value;
      });
  }

}

import the directive on your component:

@NgModule({
  imports: [....],
  declarations: [..., IonMaskDirective , ...],
})
export class yourComponentModule { }

Use it like that in your component's template :

<ion-input formControlName="controlName" [ionMask]="mask"></ion-input>

And in your component's controller (phone mask) :

public mask : Array<any>  =  ['(', /[1-9]/, /\d/, /\d/, ')', ' ', /\d/, /\d/, /\d/, '-', /\d/, /\d/, /\d/, /\d/,];

source: https://github.com/ionic-team/ionic-framework/issues/15424#issuecomment-552057007

Mansour Alnasser
  • 4,446
  • 5
  • 40
  • 51