diff --git a/README.md b/README.md
index 582c7ca3..23ccc921 100644
--- a/README.md
+++ b/README.md
@@ -377,8 +377,11 @@ Define the default value of the field in the creation form.
### `number` Field Settings
-* `fractionSize(integer)`
-Number of decimal places to round the number to. If this is not provided, then the fraction size is computed from the current locale's number formatting pattern.
+* `format(string)`
+Format for number to string conversion. Based on [Numeral.js](http://numeraljs.com/), which uses a syntax similar to Excel. You can configure the locale and create named formats by following [angular-numeraljs](https://github.com/baumandm/angular-numeraljs) instructions.
+
+ nga.field('cost', 'number').format('$0,0.00');
+ // now 1234.5 will render as '$1,234.50'
### `choice` and `choices` Field Settings
diff --git a/bower.json b/bower.json
index 49340be8..018cb768 100644
--- a/bower.json
+++ b/bower.json
@@ -8,26 +8,27 @@
"dependencies": {
"angular": "~1.3.1",
"angular-bootstrap": "~0.12.0",
- "angular-resource": "~1.3.1",
"angular-cookies": "~1.3.1",
+ "angular-numeraljs": "~1.1.6",
+ "angular-resource": "~1.3.1",
"angular-sanitize": "~1.3.1",
- "json3": "~3.2.6",
- "es5-shim": "~3.4.0",
- "jquery": "~1.11.0",
- "requirejs": "~2.1.14",
- "requirejs-text": "~2.0.12",
- "bootstrap-sass-official": "~3.3.0",
- "restangular": "~1.4.0",
+ "angular-ui-codemirror": "~0.2.2",
"angular-ui-router": "~0.2.13",
"bootstrap": "~3.3.1",
+ "bootstrap-sass-official": "~3.3.0",
+ "es5-shim": "~3.4.0",
"fontawesome": "~4.1.0",
"humane": "~3.2.0",
- "nprogress": "~0.1.6",
- "textAngular": "~1.2.2",
- "ngInflection": "~1.0.0",
- "angular-ui-codemirror": "~0.2.2",
+ "jquery": "~1.11.0",
+ "json3": "~3.2.6",
"jsonlint": "~1.6.0",
- "ng-file-upload": "~2.2.2"
+ "ng-file-upload": "~2.2.2",
+ "ngInflection": "~1.0.0",
+ "nprogress": "~0.1.6",
+ "requirejs": "~2.1.14",
+ "requirejs-text": "~2.0.12",
+ "restangular": "~1.4.0",
+ "textAngular": "~1.2.2"
},
"devDependencies": {
"angular-mocks": "~1.3.1",
diff --git a/src/javascripts/ng-admin.js b/src/javascripts/ng-admin.js
index 30fb69c5..edf6419d 100644
--- a/src/javascripts/ng-admin.js
+++ b/src/javascripts/ng-admin.js
@@ -8,23 +8,25 @@ define('angular', [], function () {
require.config({
paths: {
+ 'angular-bootstrap': 'bower_components/angular-bootstrap/ui-bootstrap.min',
+ 'angular-bootstrap-tpls': 'bower_components/angular-bootstrap/ui-bootstrap-tpls.min',
+ 'angular-numeraljs': 'bower_components/angular-numeraljs/dist/angular-numeraljs',
'angular-resource': 'bower_components/angular-resource/angular-resource',
'angular-sanitize': 'bower_components/angular-sanitize/angular-sanitize',
+ 'angular-ui-codemirror': 'bower_components/angular-ui-codemirror/ui-codemirror.min',
'angular-ui-router': 'bower_components/angular-ui-router/release/angular-ui-router',
- 'ng-file-upload': 'bower_components/ng-file-upload/angular-file-upload',
+ 'humane': 'bower_components/humane/humane',
+ 'inflection': 'bower_components/inflection/inflection.min',
'lodash': 'bower_components/lodash/dist/lodash.min',
- 'text' : 'bower_components/requirejs-text/text',
- 'angular-bootstrap': 'bower_components/angular-bootstrap/ui-bootstrap.min',
- 'angular-bootstrap-tpls': 'bower_components/angular-bootstrap/ui-bootstrap-tpls.min',
- 'restangular': 'bower_components/restangular/dist/restangular',
+ 'ng-file-upload': 'bower_components/ng-file-upload/angular-file-upload',
'ngInflection': 'bower_components/ngInflection/ngInflection',
- 'inflection': 'bower_components/inflection/inflection.min',
- 'humane': 'bower_components/humane/humane',
'nprogress': 'bower_components/nprogress/nprogress',
+ 'numeral': 'bower_components/numeral/numeral',
+ 'restangular': 'bower_components/restangular/dist/restangular',
+ 'text' : 'bower_components/requirejs-text/text',
'textangular': 'bower_components/textAngular/dist/textAngular.min',
- 'angular-ui-codemirror': 'bower_components/angular-ui-codemirror/ui-codemirror.min',
- 'MainModule': 'ng-admin/Main/MainModule',
'CrudModule': 'ng-admin/Crud/CrudModule',
+ 'MainModule': 'ng-admin/Main/MainModule',
'AdminDescription': '../../build/ng-admin-configuration'
},
shim: {
diff --git a/src/javascripts/ng-admin/Crud/CrudModule.js b/src/javascripts/ng-admin/Crud/CrudModule.js
index aab793dc..3a90f9ce 100644
--- a/src/javascripts/ng-admin/Crud/CrudModule.js
+++ b/src/javascripts/ng-admin/Crud/CrudModule.js
@@ -5,6 +5,7 @@ define(function (require) {
var angular = require('angular');
inflection = require('inflection');
+ var numeral = require('numeral');
require('angular-ui-router');
require('angular-sanitize');
@@ -13,9 +14,10 @@ define(function (require) {
require('textangular');
require('ngInflection');
require('angular-ui-codemirror');
+ require('angular-numeraljs');
var CrudModule = angular.module('crud', [
- 'ui.router', 'ui.bootstrap', 'ngSanitize', 'textAngular', 'ngInflection', 'ui.codemirror', 'angularFileUpload'
+ 'ui.router', 'ui.bootstrap', 'ngSanitize', 'textAngular', 'ngInflection', 'ui.codemirror', 'angularFileUpload', 'ngNumeraljs'
]);
CrudModule.controller('ListController', require('ng-admin/Crud/list/ListController'));
diff --git a/src/javascripts/ng-admin/Crud/column/maNumberColumn.js b/src/javascripts/ng-admin/Crud/column/maNumberColumn.js
index 2fea3b76..a73693cb 100644
--- a/src/javascripts/ng-admin/Crud/column/maNumberColumn.js
+++ b/src/javascripts/ng-admin/Crud/column/maNumberColumn.js
@@ -10,7 +10,7 @@ define(function (require) {
value: '&',
field: '&'
},
- template: '{{ value() | number:field().format() }}'
+ template: '{{ value() | numeraljs:field().format() }}'
};
}
diff --git a/src/javascripts/ng-admin/es6/lib/Field/NumberField.js b/src/javascripts/ng-admin/es6/lib/Field/NumberField.js
index b214d0bb..84285ac2 100644
--- a/src/javascripts/ng-admin/es6/lib/Field/NumberField.js
+++ b/src/javascripts/ng-admin/es6/lib/Field/NumberField.js
@@ -4,23 +4,32 @@ class NumberField extends Field {
constructor(name) {
super(name);
this._type = "number";
- this._fractionSize = undefined;
+ this._format = undefined;
}
/**
- * Number of decimal places to round the number to. If this is not provided,
- * then the fraction size is computed from the current locale's number formatting pattern.
- * In the case of the default locale, it will be 3.
+ * Specify format pattern for number to string conversion.
*
+ * Based on NumeralJs, which uses a syntax similar to Excel.
+ *
+ * {@link} http://numeraljs.com/
+ * {@link} https://github.com/baumandm/angular-numeraljs
* {@example}
*
- * nga.field('height', 'number').fractionSize(2);
+ * nga.field('height', 'number').format('$0,0.00');
*/
- fractionSize(value) {
- if (!arguments.length) return this._fractionSize;
- this._fractionSize = value;
+ format(value) {
+ if (!arguments.length) return this._format;
+ this._format = value;
+ return this;
+ }
+
+ fractionSize(decimals) {
+ console.warn('NumberField.fractionSize() is deprecated, use NumberField.format() instead');
+ this.format('0.' + '0'.repeat(decimals));
return this;
- };
+ }
+
}
export default NumberField;
diff --git a/src/javascripts/test/app-test.js b/src/javascripts/test/app-test.js
index 74e3da6b..865f1062 100644
--- a/src/javascripts/test/app-test.js
+++ b/src/javascripts/test/app-test.js
@@ -22,17 +22,19 @@ requirejs.config({
'mock/Restangular': '/base/test/mock/Restangular',
'angular': 'bower_components/angular/angular',
+ 'angular-bootstrap': 'bower_components/angular-bootstrap/ui-bootstrap.min',
+ 'angular-bootstrap-tpls': 'bower_components/angular-bootstrap/ui-bootstrap-tpls.min',
+ 'angular-numeraljs': 'bower_components/angular-numeraljs/dist/angular-numeraljs',
'angular-resource': 'bower_components/angular-resource/angular-resource',
- 'angular-sanitize': 'bower_components/angular-sanitize/angular-sanitize',
'angular-route': 'bower_components/angular-route/angular-route',
+ 'angular-sanitize': 'bower_components/angular-sanitize/angular-sanitize',
'angular-ui-router': 'bower_components/angular-ui-router/release/angular-ui-router',
- 'lodash': 'bower_components/lodash/dist/lodash.min',
- 'text' : 'bower_components/requirejs-text/text',
- 'angular-bootstrap': 'bower_components/angular-bootstrap/ui-bootstrap.min',
- 'angular-bootstrap-tpls': 'bower_components/angular-bootstrap/ui-bootstrap-tpls.min',
- 'restangular': 'bower_components/restangular/dist/restangular',
'humane': 'bower_components/humane/humane',
+ 'lodash': 'bower_components/lodash/dist/lodash.min',
'nprogress': 'bower_components/nprogress/nprogress',
+ 'numeral': 'bower_components/numeral/numeral',
+ 'restangular': 'bower_components/restangular/dist/restangular',
+ 'text' : 'bower_components/requirejs-text/text',
'MainModule': 'ng-admin/Main/MainModule',
'CrudModule': 'ng-admin/Crud/CrudModule'
@@ -41,6 +43,9 @@ requirejs.config({
'angular': {
exports: 'angular'
},
+ 'angular-numeraljs': {
+ deps: ['angular']
+ },
'angular-mocks': {
deps: ['angular']
},
@@ -70,6 +75,9 @@ requirejs.config({
},
'nprogress': {
exports: 'NProgress'
+ },
+ 'numeral': {
+ exports: 'numeral'
}
},
diff --git a/src/javascripts/test/karma.conf.js b/src/javascripts/test/karma.conf.js
index 629be34f..eb7929c9 100644
--- a/src/javascripts/test/karma.conf.js
+++ b/src/javascripts/test/karma.conf.js
@@ -7,30 +7,31 @@ module.exports = function (config) {
plugins: ['karma-requirejs', 'karma-jasmine', 'karma-chrome-launcher', 'karma-phantomjs-launcher', 'karma-babel-preprocessor'],
files: [
- {pattern: 'bower_components/requirejs-text/text.js', included: false},
- {pattern: 'bower_components/requirejs-text/text.js', included: false},
- {pattern: 'bower_components/codemirror/lib/codemirror.js', included: false},
+ {pattern: 'bower_components/angular-mocks/angular-mocks.js', included: false},
+ {pattern: 'bower_components/angular-numeraljs/dist/angular-numeraljs.js', included: false},
+ {pattern: 'bower_components/angular/angular.js', included: false},
{pattern: 'bower_components/codemirror/addon/edit/closebrackets.js', included: false},
{pattern: 'bower_components/codemirror/addon/edit/matchbrackets.js', included: false},
- {pattern: 'bower_components/codemirror/addon/lint/lint.js', included: false},
- {pattern: 'bower_components/jsonlint/lib/jsonlint.js', included: false},
{pattern: 'bower_components/codemirror/addon/lint/json-lint.js', included: false},
+ {pattern: 'bower_components/codemirror/addon/lint/lint.js', included: false},
{pattern: 'bower_components/codemirror/addon/selection/active-line.js', included: false},
+ {pattern: 'bower_components/codemirror/lib/codemirror.js', included: false},
{pattern: 'bower_components/codemirror/mode/javascript/javascript.js', included: false},
- {pattern: 'bower_components/angular/angular.js', included: false},
- {pattern: 'bower_components/angular-mocks/angular-mocks.js', included: false},
- {pattern: 'ng-admin/lib/polyfill/bind.js', included: true},
+ {pattern: 'bower_components/jsonlint/lib/jsonlint.js', included: false},
+ {pattern: 'bower_components/numeral/numeral.js', included: false},
+ {pattern: 'bower_components/requirejs-text/text.js', included: false},
// ng-admin application files
- {pattern: 'ng-admin/es6/lib/**/*.js', included: false},
{pattern: 'ng-admin/**/**/**/*.js', included: false},
- {pattern: 'ng-admin/lib/**/*.js', included: false},
- {pattern: 'ng-admin/**/view/**/*.html', included: false},
{pattern: 'ng-admin/**/*/*.html', included: false},
+ {pattern: 'ng-admin/**/view/**/*.html', included: false},
+ {pattern: 'ng-admin/es6/lib/**/*.js', included: false},
+ {pattern: 'ng-admin/lib/**/*.js', included: false},
+ {pattern: 'ng-admin/lib/polyfill/bind.js', included: true},
// Test files
- {pattern: 'test/unit/**/**/*.js', included: false},
{pattern: 'test/mock/*.js', included: false},
+ {pattern: 'test/unit/**/**/*.js', included: false},
// Test bootstrap
'test/app-test.js'
diff --git a/src/javascripts/test/unit/Crud/column/maNumberColumnSpec.js b/src/javascripts/test/unit/Crud/column/maNumberColumnSpec.js
new file mode 100644
index 00000000..f7ecf59e
--- /dev/null
+++ b/src/javascripts/test/unit/Crud/column/maNumberColumnSpec.js
@@ -0,0 +1,51 @@
+/*global define,angular,inject,describe,it,expect,beforeEach*/
+
+define(function (require) {
+ 'use strict';
+
+ describe('directive: ma-number-column', function () {
+ var directive = require('ng-admin/Crud/column/maNumberColumn');
+ var NumberField = require('ng-admin/es6/lib/Field/NumberField');
+ angular.module('testapp_NumberColumn', ['ngNumeraljs']).directive('maNumberColumn', directive);
+ require('angular-mocks');
+ require('numeral');
+ require('angular-numeraljs');
+
+ var $compile,
+ scope,
+ directiveUsage = '';
+
+ beforeEach(module('testapp_NumberColumn'));
+
+ beforeEach(inject(function (_$compile_, _$rootScope_) {
+ $compile = _$compile_;
+ scope = _$rootScope_;
+ }));
+
+ it("should contain a span tag", function () {
+ scope.field = new NumberField();
+ var element = $compile(directiveUsage)(scope);
+ scope.$digest();
+ expect(element.children()[0].nodeName).toBe('SPAN');
+ });
+
+ it("should contain the bounded value with", function () {
+ scope.field = new NumberField();
+ scope.value = 123;
+ var element = $compile(directiveUsage)(scope);
+ scope.$digest();
+ expect(element.find('span').html()).toBe('123');
+ scope.value = 456;
+ scope.$digest();
+ expect(element.find('span').html()).toBe('456');
+ });
+
+ it("should use the provided number format", function () {
+ scope.field = new NumberField().format('$0,000.00');
+ scope.value = 1234.5;
+ var element = $compile(directiveUsage)(scope);
+ scope.$digest();
+ expect(element.find('span').html()).toBe('$1,234.50');
+ });
+ });
+});