简体   繁体   中英

Format input value in Angularjs

I'm trying to write a directive that automatically formats a number in the <input> but the the model isn't formatted. Getting it to work is fine, on load the value in the input is displayed as 1,000,000 and 1000000 in the controller, however when typing only the ngModel.$parsers function fires. The only time when the ngModel.$formatters fire is when the directive gets loaded and when the value is 0.

How can I make it work on keypress(I've tried binding to keypress/keyup but it doesn't work).

Here's my code:

angular.module('myApp.directives', []).directive('filterInput', ['$filter', function($filter) {
    return {
        restrict: 'A',
        require: 'ngModel',
        link: function(scope, element, attr, ngModel) {

            ngModel.$parsers.push(function fromUser(text) {
                return parseInt(text.replace(",", ""));
            });

            ngModel.$formatters.push(function toUser(text) {
                console.log($filter('number')(text));
                return ($filter('number')(text || ''));
            });

        }
    };
}]);

Here is working example where we use unshift :

angular.module('myApp.directives', []).directive('format', ['$filter', function ($filter) {
    return {
        require: '?ngModel',
        link: function (scope, elem, attrs, ctrl) {
            if (!ctrl) return;


            ctrl.$formatters.unshift(function (a) {
                return $filter(attrs.format)(ctrl.$modelValue)
            });


            ctrl.$parsers.unshift(function (viewValue) {
                var plainNumber = viewValue.replace(/[^\d|\-+|\.+]/g, '');
                elem.val($filter(attrs.format)(plainNumber));
                return plainNumber;
            });
        }
    };
}]);

The HTML seems:

<input type="text" ng-model="test" format="number" />

See Demo Fiddle

Hope its help

This module works fine for me.

https://github.com/assisrafael/angular-input-masks

Example:

<input type="text" name="field" ng-model="number" ui-number-mask>

Small edit to Maxim Shoustin's answer below as per the answer to this question: AngularJS formatter - how to display blank instead of zero

Only change is to ensure that the input is blank rather than zero on the deletion of the last number:

   ctrl.$parsers.unshift(function (viewValue) {
        console.log(viewValue);
        if(viewValue){
            var plainNumber = viewValue.replace(/[^\d|\-+|\.+]/g, '');
            elem.val($filter('number')(plainNumber));
            return plainNumber;
        }else{
            return '';
        }
    });

http://jsfiddle.net/2n73j6rb/

I created this directive solution for myself which does:

  1. Initializes input to 0.00 on focus.
  2. Compatible with Template-Driven and ReactiveForm.
  3. Removes/undo any non-digit entry.
  4. Prevents empty input.
  5. Paste 123ab4d5, outputs: 12345.
  6. Divides every thousand by a ,
  7. Backspace/Delete compatible.
  8. Lets enter/remove in the middle.
  9. Positive int only.

在此处输入图片说明

在此处输入图片说明

在此处输入图片说明

Recommended : Use [maxLength] to limit user to a certain length.

 <input [maxLength]="9" appPriceUsd>

Here is the directive:

// Format USD by Reza Taba
import { DecimalPipe } from '@angular/common';
import { Directive, ElementRef, HostListener } from '@angular/core';


@Directive({
  selector: '[appPriceUsd]'
})
export class PriceUsdDirective {
  constructor(private elRef: ElementRef, private decimalPipe: DecimalPipe) { }

  @HostListener('focus') initializeValue(): void {
    if (this.elRef.nativeElement.value === '') {
      this.elRef.nativeElement.value = '0.00';
    }
  }

  @HostListener('keyup') formatUsd(): void {
    let value: string;
    value = this.elRef.nativeElement.value as string;
    value = this.removeNonDigtis(value); // remove all non-digit values
    value = this.addDecimalPoint(value); // Add . to the -2 index
    value = this.applyDecimalPipe(value); // to divide every thousand
    this.elRef.nativeElement.value = value;
  }

  removeNonDigtis(value: string): string {
    let inputArray: string[] = [];
    const digitArray: string[] = [];

    // 12a34b to ["1", "2", "a", "3", "4", "b"]
    inputArray = value.split('');

    // remove any non-digit value
    for (const iterator of inputArray) {
      if (/[0-9]/.test(iterator)) {
        digitArray.push(iterator);
      }
    }

    return digitArray.join('');
  }

  addDecimalPoint(value: string): string {
    const inputArray = value.split(''); // ['0', '.', '0', '0']
    inputArray.splice(-2, 0, '.'); // place decimal in -2
    return inputArray.join('');
  }

  applyDecimalPipe(value: string): string {
    console.log(value);
    return value === '' || value === '.'
      ? '0.00'
      : this.decimalPipe.transform(value, '1.2-2');
  }
}

Hope it helps. Enjoy coding.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM