webentwicklung-frage-antwort-db.com.de

Eckiges Eingabefeld mit Währungsmasken-Direktive für das Geldformat im laufenden Betrieb

Ich versuche, eine Eingabemaske für ein EU-Geldfeld zu erstellen, indem Sie http://jquerypriceformat.com/ verwenden. 

In meiner Direktive wird die Eingabe dem Benutzer mit der angewendeten Maske korrekt angezeigt. Ich glaube jedoch, dass etwas nicht stimmt, da die POST - Werte mit einer komischen Formatierung gesendet werden .

Ich füge die priceformat.js bei

<script src="js/jquery.price_format.1.8.min.js"></script>

<input type="text" currency-input ng-model...>

Und am Winkel:

app.directive('currencyInput', function() {
    return {
      require: '?ngModel',
      link: function($scope, element, attrs, controller) {
        element.priceFormat({
            prefix: '',
            centsSeparator: ',',
            thousandsSeparator: '.'
        });
      }
    };
});

Meine Eingabe zeigt den Wert mit der Maske korrekt an, aber bei POST - Daten (von Winkeln bezeichnet) ist es ein anderer Wert. Was fehlt mir?

eingabe> 2.200,80 | Beitrag> 22.0080

Vielen Dank

24
Antonio Max

Sie können Ihr Passwort ändern, indem Sie auf die Schaltfläche "Abbrechen" klicken.

Weitere Informationen zum Thema:

.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) {

          elem.priceFormat({
            prefix: '',
            centsSeparator: ',',
            thousandsSeparator: '.'
        });                

                return elem[0].value;
            });
        }
    };
}]);

Демо 1 Fiddle

enter image description here

Sie können den Code $formatters wie folgt ändern:

Typ link:

link: function (scope, elem, attrs, ctrl) {
            if (!ctrl) return;

            var format = {
                    prefix: '',
                    centsSeparator: ',',
                    thousandsSeparator: ''
                };

            ctrl.$parsers.unshift(function (value) {
                elem.priceFormat(format);

                return elem[0].value;
            });

            ctrl.$formatters.unshift(function (value) {
                elem[0].value = ctrl.$modelValue * 100 ;
                elem.priceFormat(format);
                return elem[0].value;
            })
        }

Демо 2 Fiddle

31
Maxim Shoustin

Drücken Sie einen $parser an den Controller und aktualisieren Sie den Wert nur, wenn er nicht mit der Eingabe übereinstimmt, und verwenden Sie $setViewValue() und $render().

app.directive('currencyInput', function() {
    return {
      require: '?ngModel',
      link: function($scope, element, attrs, controller) {
        return ctrl.$parsers.Push(function(inputValue) {

            ...

            if (result != inputValue) {
                controller.$setViewValue(res);
                controller.$render();
            }
        });
      }
    };
});

Hier ist eine Geige mit der Logik, die ich für meine Deviseingabe-Direktive verwendet habe: Fiddle

17
dubilla

Spät zur Party, aber ich glaube, das verdient eine andere Antwort! Ich habe das Modul ng-currency verwendet. Es ist absolut fantastisch.

3
David Posey

Ich mag Dubillas Ansatz wegen seiner Schlichtheit und Eleganz. Ich entschied mich dazu (mit gebührenpflichtigen Credits) einige Features hinzuzufügen, um es dem realen Anwendungsfall ziemlich nahe zu bringen. 

Ich habe es in einem Github-Projekt verwendet, um einige nützliche Finanzrichtlinien zu erstellen github .

Bemerkenswerte Zusatzfunktionen:

  1. Es führt eine strenge Überprüfung der Eingaben durch, um eine gültige Antwort zu erhalten.
  2. Es gibt einige Tastenkombinationen, um die Eingabe großer Zahlen zu beschleunigen.
  3. Ich zeige, wie man es mit Bootstrap- und Ngmodel-CSS-Updates integriert.
  4. Als Bonus habe ich den Ngmonel des Formulars als JSON ausgegeben, damit die Benutzer sehen können, wie die Formularvalidierung in Echtzeit funktioniert

Es verwendet auch ein POJO als ngmodel:

function Money() {
    this.notional = 0;
    this.maxValue = 99999999999.9;
    this.maxValueString = "99,999,999,999.9";
    this.maxPrecision = 10;
}

sie können es mit Bootstrap 3 wie folgt verwenden:

<h1>Currency Formatting directive</h1>

<div class="row">

    <div class="col-md-6">
        <form name="myForm">

            <div class="form-group" ng-class="{'has-error': myForm.notional.$invalid && myForm.notional.$touched}">
                <input type="text" ng-model="myForm.money.notional  " money="money" money-input size="30" required
                       name="notional"
                       class="form-control"
                       placeholder="Enter notional amount"/>

                      <p class="help-block error" ng-show="myForm.notional.$error.required && myForm.notional.$touched">Required</p>



            </div>

            <button ng-disabled="myForm.$invalid" type="submit">SAVE</button>
        </form>
        <h2>Tips</h2>
        <ol>

            <li> Entering 'k' will multiply the amount by one thousand</li>
            <li> Entering 'm' will multiply the amount by one million</li>
            <li> Entering 'b' will multiply the amount by one billion</li>
        </ol>
    </div>
</div>
<p>Form debugger</p>
<pre>
               form = {{ myForm | json }}
    </pre>
1
Nikos

Hier ist eine Möglichkeit, dies ohne jQuery zu tun, indem nur eine Angular-Direktive verwendet wird. Dieses Beispiel unterstützt keine Dezimalzahlen. Es ist leicht, es zu ändern, um dies zu unterstützen, ändern Sie einfach den $filter in der toView()-Funktion.

Meiner Meinung nach ist dies ein besserer Ansatz, um das gleiche Problem zu lösen, da Sie das Laden in jQuery und das vom Autor erwähnte Währungs-Plugin vermeiden können. Die Ländereinstellung für Euro sollte durch die Verwendung der $locale-Eigenschaften unterstützt werden, aber ich habe dies nur für die Verwendung in USD getestet.

(function() {
  var app = angular.module('currencyMask', []);

  // Controller
  app.controller('ctrl', ['$scope', function($scope) {
    $scope.amount = 100000;
  }]);

  // Directive
  app.directive('inputCurrency', ['$locale', '$filter', function($locale, $filter) {

    // For input validation
    var isValid = function(val) {
      return angular.isNumber(val) && !isNaN(val);
    };

    // Helper for creating RegExp's
    var toRegExp = function(val) {
      var escaped = val.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
      return new RegExp(escaped, 'g');
    };

    // Saved to your $scope/model
    var toModel = function(val) {

      // Locale currency support
      var decimal = toRegExp($locale.NUMBER_FORMATS.DECIMAL_SEP);
      var group = toRegExp($locale.NUMBER_FORMATS.GROUP_SEP);
      var currency = toRegExp($locale.NUMBER_FORMATS.CURRENCY_SYM);

      // Strip currency related characters from string
      val = val.replace(decimal, '').replace(group, '').replace(currency, '').trim();

      return parseInt(val, 10);
    };

    // Displayed in the input to users
    var toView = function(val) {
      return $filter('currency')(val, '$', 0);
    };

    // Link to DOM
    var link = function($scope, $element, $attrs, $ngModel) {
      $ngModel.$formatters.Push(toView);
      $ngModel.$parsers.Push(toModel);
      $ngModel.$validators.currency = isValid;

      $element.on('keyup', function() {
        $ngModel.$viewValue = toView($ngModel.$modelValue);
        $ngModel.$render();
      });
    };

    return {
      restrict: 'A',
      require: 'ngModel',
      link: link
    };
  }]);
})();
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.5/angular.min.js"></script>

<div ng-app="currencyMask" ng-controller="ctrl">
	<input input-currency ng-model="amount">
	<p><strong>Amount:</strong> {{ amount }}</p>
</div>

0
Kevin Leary