You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在<md-input-container>中实现金额千分位分隔及保留两位小数

Solution for Formatting Currency with Thousand Separators and 2 Decimal Places in AngularJS Material Input

Hey there, let's solve this formatting issue for your unit price input. The key challenge here is balancing a user-friendly formatted display (thousand separators + two fixed decimals) while keeping the underlying ng-model value as a valid number for your business logic. Here's a step-by-step implementation:

1. Create a Custom AngularJS Directive

We'll build a directive that handles the formatting when the input loses focus, and reverts to a raw number when focused for editing. This keeps the model clean while making the display user-friendly.

Add this directive to your AngularJS module:

angular.module('yourAppModule')
.directive('formatCurrency', function($filter) {
  return {
    require: 'ngModel',
    link: function(scope, element, attrs, ngModelCtrl) {
      // Format value for display when input loses focus
      element.on('blur', function() {
        var value = ngModelCtrl.$modelValue;
        if (!value) return;
        
        // Format to 2 decimal places with thousand separators
        var formattedValue = $filter('number')(value, 2);
        ngModelCtrl.$setViewValue(formattedValue);
        ngModelCtrl.$render();
      });

      // Revert to raw number when focusing for editing
      element.on('focus', function() {
        var value = ngModelCtrl.$modelValue;
        if (!value) return;
        
        ngModelCtrl.$setViewValue(value.toString());
        ngModelCtrl.$render();
        // Move cursor to end of input for better UX
        setTimeout(function() {
          element[0].setSelectionRange(element[0].value.length, element[0].value.length);
        }, 0);
      });

      // Parse formatted string back to a number for the model
      ngModelCtrl.$parsers.push(function(viewValue) {
        if (!viewValue) return null;
        
        // Remove non-numeric characters except decimal point
        var rawValue = viewValue.replace(/[^0-9.]/g, '');
        // Ensure exactly two decimal places
        var parts = rawValue.split('.');
        if (parts.length === 1) {
          rawValue += '.00';
        } else if (parts[1].length > 2) {
          parts[1] = parts[1].substring(0, 2);
          rawValue = parts.join('.');
        }
        return parseFloat(rawValue) || null;
      });

      // Format initial value when directive loads
      scope.$watch(function() {
        return ngModelCtrl.$modelValue;
      }, function(newVal) {
        if (newVal !== undefined && !element.is(':focus')) {
          var formattedValue = $filter('number')(newVal, 2);
          ngModelCtrl.$setViewValue(formattedValue);
          ngModelCtrl.$render();
        }
      });
    }
  };
});

2. Update Your HTML Markup

Modify your existing <input> element to use the new directive, and switch the type to text (since type="number" doesn't support thousand separators natively). We'll keep your existing validation and model binding intact:

<td md-cell class="min-width-120px-imp text-right padding-right-10">
  <md-input-container flex class="margin-0" ng-show="!vm.grn.itemdetails[$index].isfree">
    <label translate class="padding-left-0">COMMON.UNITPRICE</label>
    <input 
      id="grnUnitPrice{{$index}}" 
      name="grnUnitPrice{{$index}}" 
      class="text-right" 
      type="text"  <!-- Changed from number to text for separator support -->
      enterastab 
      ng-required="!vm.grn.itemdetails[$index].isfree" 
      ng-model="vm.grn.itemdetails[$index].unitprice" 
      ng-pattern="vm.amountPattern" 
      format-currency  <!-- Added our custom formatting directive -->
      ng-change="vm.updatePriceCalculations($index)" <!-- Completed your ng-change logic -->
    >
  </md-input-container>
</td>

3. Adjust Your Amount Pattern (Optional)

If your existing vm.amountPattern is tailored for type="number", update it to allow thousand separators in the input:

// Pattern allowing numbers with thousand separators and exactly two decimals
vm.amountPattern = /^\d{1,3}(,\d{3})*(\.\d{2})?$/;

Key Notes

  • Model Integrity: The ng-model value remains a numeric type (not a string), so your business logic can use it directly for calculations.
  • User Experience: When the user clicks into the input, it reverts to a raw number (no separators) for easy editing, and re-formats when they click away.
  • Decimal Enforcement: The directive ensures exactly two decimal places are always displayed, even if the input doesn't include them.

内容的提问来源于stack exchange,提问作者Raghul

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 04:09:36