2013-10-24 2 views
24

Я пытаюсь создать маску ввода для денежного поля ЕС с использованием http://jquerypriceformat.com/Угловое, поле ввода с директивой валюты маски для формата денег на лета

До сих пор в моей директиве, вход правильно показывает на пользователь с применяемой маской, но я считаю, что что-то не так, потому что значения POST отправляются со странным форматированием, совершенно отличным от того, что мы видим в поле ввода.

I включают priceformat.js

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

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

А на угловой:

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

Мой вход показывает значение с помощью маски правильно, но на данных POST (называемые по угловым), это другое ценность, что мне не хватает?

ввод> 2.200,80 | разместить> 22,0080

Благодаря

+0

пожалуйста, напишите скрипку/Plunker для использования отладки. Спасибо –

ответ

31

Из вашего примера я не вижу, что ссылка возвращает что-то.

Я хотел бы написать директиву что-то вроде:

.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; 
      }); 
     } 
    }; 
}]); 

Demo 1 Fiddle

enter image description here

Если вы хотите при запуске пожара фильтра используйте $formatters:

Теперь 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

+2

Просто работает! Большое спасибо. Скрипка прекрасна, черт возьми, что вы, ребята, едите? –

+0

@MaximShoustin спасибо. Это имеет некоторые проблемы. Когда значение $ scope.test имеет некоторое значение, например. 1000, а тысячаСепаратор «пуст», поле ввода по-прежнему показывает «1.000,00», когда страница загружена. При вводе в поле ввода оно работает. Любые предложения, как это исправить? – iiro

+0

@iiro, см. Редактирование, которое я разместил. Спасибо –

17

$parser нажать на контроллер, и только обновить значение, когда она не соответствует вход с помощью $setViewValue() и $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(); 
      } 
     }); 
     } 
    }; 
}); 

Вот скрипка с логикой я использовал для моей директивы ввода валюты: Fiddle

+1

. Я добавил некоторые вещи к этому удивительному ответу ниже – Nikos

+0

Я использовал ваш метод, но теперь цена не сообщение на контроллер –

+0

Странное поведение, когда вы пытаетесь перекрыть запятую. Парсер $ снова применяет фильтр. – UserX

1

Мне нравятся подход причина Dubilla по своей простоте и элегантности. Я решил добавить (с соответствующими кредитами) некоторые функции поверх него, чтобы сделать его очень близким к реальному использованию.

Я использую его в проекте github, чтобы создать несколько полезных финансовых директив github.

Заметные дополнительные функции:

  1. Это некоторые строгая проверка входов, чтобы дать правильный ответ.
  2. У него есть несколько сочетаний клавиш, чтобы быстрее вводить большие числа.
  3. Я покажу, как интегрировать его с обновлениями bootstrap и ngmodel css.
  4. В качестве бонуса я outputed ngmonel форме как JSON, чтобы помочь людям увидеть, как форма проверки работает в режиме реального времени

Он также использует POJO как ngmodel:

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

вы можете использовать это с Bootstrap 3 следующим образом:

<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> 
3

Поздно к вечеринке, но я считаю, что это заслуживает другого ответа! Я использовал модуль ng-currency. Это абсолютно фантастично.

0

Вот способ справиться с этим без jQuery, используя только угловую директиву. Этот пример не поддерживает десятичные знаки. Его легко изменить, чтобы поддержать это, но просто измените $filter на функцию toView().

По-моему, это лучший подход для решения одной и той же проблемы, так как вы можете избежать загрузки в jQuery и плагин валюты, упомянутый автором. Поддержка локалей для евро должна поддерживаться за счет использования свойств $locale, но я тестировал это только для использования в долларах США.

(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"> 
 
\t <input input-currency ng-model="amount"> 
 
\t <p><strong>Amount:</strong> {{ amount }}</p> 
 
</div>

Смежные вопросы