Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Limit the length of a string using angular 2/ionic 2

How do i restrict the phone number field to 10 characters using angular2. i tried using ng-maxlenth but it is working only in browser but not in the android devices.

I found one code snippet using angular 1. But how do i rewrite the the same code using angular2?

app.directive("limitTo", [function() {
    return {
        restrict: "A",
        link: function(scope, elem, attrs) {
            var limit = parseInt(attrs.limitTo);
            angular.element(elem).on("keypress", function(e) {
                if (this.value.length == limit) e.preventDefault();
            });
        }
    }
}]);

<input limit-to="4" type="number" class="form-control input-lg" ng-model="search.main" placeholder="enter first 4 digits: 09XX">
like image 517
vishnu Avatar asked Sep 07 '16 05:09

vishnu


5 Answers

Instead of using a custom directive, you could just use the maxlength HTML attribute and the attr binding from Angular 2 like this: [attr.maxlength]="4"

<ion-input type="text" [(ngModel)]="a.myInput" [attr.maxlength]="4"></ion-input>

You can also bind that attribute to a property from your Component to set the max length dynamically.

like image 107
sebaferreras Avatar answered Nov 03 '22 11:11

sebaferreras


In angular2 it will look like:

@Directive({
  selector: '[limit-to]',
  host: {
    '(keypress)': '_onKeypress($event)',
  }
})
export class LimitToDirective {
  @Input('limit-to') limitTo; 
  _onKeypress(e) {
     const limit = +this.limitTo;
     if (e.target.value.length === limit) e.preventDefault();
  }
}

Don't forget to register directive in NgModule sth like:

@NgModule({
  imports: [ BrowserModule ],
  declarations: [ App, LimitToDirective ],
  bootstrap: [ App ]
})
export class AppModule {}

And then use it like:

<input limit-to="4" type="number" placeholder="enter first 4 digits: 09XX">

Here is the Plunker!

like image 32
yurzui Avatar answered Nov 03 '22 12:11

yurzui


Just use slice:

{{expression | slice:begin:end}}

Angular DOCS: https://angular.io/docs/ts/latest/cookbook/ajs-quick-reference.html

like image 25
Felipe Sabino Avatar answered Nov 03 '22 13:11

Felipe Sabino


I have faced the similar issue in ionic2/angular2 on samsung android devices. I have written the custom directive to handle this. Same mentioned in my blog and usage instructions mentioned in that. http://jagadeeshmanne.blogspot.com/2017/08/ionic-2-angular-maxlength-issue-in.html

import { Directive, EventEmitter, HostListener, Input, Output } from '@angular/core';
import { Platform } from "ionic-angular";
 
@Directive({
    selector: '[cMaxLength]'
})
export class MaxLengthDirective {
 
  @Input('cMaxLength') cMaxLength:any;
  @Output() ngModelChange:EventEmitter<any> = new EventEmitter();
 
  constructor(public platform: Platform) {
  }
 
  //keypress event doesn't work in ionic android. the keydown event will work but the value doesn't effect until this event has finished. hence using keyup event. 
  @HostListener('keyup',['$event']) onKeyup(event) {
    const element = event.target as HTMLInputElement;
    const limit = this.cMaxLength;
    if (this.platform.is('android')) {
      const value = element.value.substr(0, limit);
      if (value.length <= limit) {
        element.value = value;
      } else {
        element.value = value.substr(0, limit-1);
      }
      this.ngModelChange.emit(element.value);
    }
  }
 
  @HostListener('focus',['$event']) onFocus(event) {
    const element = event.target as HTMLInputElement;
    if (!this.platform.is('android')) {
      element.setAttribute('maxlength', this.cMaxLength)
    }
  }
}
like image 2
Jagadeesh Avatar answered Nov 03 '22 12:11

Jagadeesh


@yurzui solution didn't work on android device. the keypress event does not fire for some reasons, as mentioned by @Jagadeesh. Also there are issues updating binded data by ngModel.

I suggest this solution instead:

import {Directive, Input, Output, EventEmitter} from '@angular/core'

@Directive({
  selector: '[limit-to]',
  host: {
    '(input)': 'onInputChange($event)',
  }
})
export class LimitToDirective {
  @Input('limit-to') limitTo;
  @Output() ngModelChange:EventEmitter<any> = new EventEmitter();
  oldValue: any;

  onInputChange(e){
    const limit = +this.limitTo;
    if(e.target.value.length > limit) {
      e.target.value = this.oldValue;
    }
    this.oldValue = e.target.value;
    this.ngModelChange.emit(e.target.value);
  }
}

on input event, check the length of the current input value, if it exceeded the limit, replace it by the last stored oldValue, then update the displayed text value of the input. and fire a new ngModelChange event to update the binded property.

like image 1
iouhammi Avatar answered Nov 03 '22 12:11

iouhammi