aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMisko Hevery2010-01-28 22:10:49 -0800
committerMisko Hevery2010-01-28 22:11:01 -0800
commita9c182764b5feeb2466c4bb32f7572762f7fab6d (patch)
tree48105ad598ca6779e3308b06b12576a366e9be71
parentdd9d8bf030688f589af6d47064a0d0eafea41bfa (diff)
downloadangular.js-a9c182764b5feeb2466c4bb32f7572762f7fab6d.tar.bz2
added formatters
-rw-r--r--Rakefile1
-rw-r--r--src/Angular.js3
-rw-r--r--src/Formaters.js6
-rw-r--r--src/Formatters.js14
-rw-r--r--src/Widgets.js37
-rw-r--r--test/BinderTest.js17
-rw-r--r--test/FormatersTest.js6
-rw-r--r--test/FormattersTest.js28
-rw-r--r--test/WidgetsTest.js6
9 files changed, 84 insertions, 34 deletions
diff --git a/Rakefile b/Rakefile
index 8bb7e1f2..883198dc 100644
--- a/Rakefile
+++ b/Rakefile
@@ -42,6 +42,7 @@ task :compile do
src/ControlBar.js \
src/DataStore.js \
src/Filters.js \
+ src/Formatters.js \
src/JSON.js \
src/Model.js \
src/Parser.js \
diff --git a/src/Angular.js b/src/Angular.js
index ce25423c..3c88c6b7 100644
--- a/src/Angular.js
+++ b/src/Angular.js
@@ -24,10 +24,11 @@ var consoleNode, msie,
jQuery = window['jQuery'] || window['$'], // weirdness to make IE happy
foreach = _.each,
extend = _.extend,
+ identity = _.identity,
angular = window['angular'] || (window['angular'] = {}),
angularValidator = angular['validator'] || (angular['validator'] = {}),
angularFilter = angular['filter'] || (angular['filter'] = {}),
- angularFormater = angular['formater'] || (angular['formater'] = {}),
+ angularFormatter = angular['formatter'] || (angular['formatter'] = {}),
angularCallbacks = angular['callbacks'] || (angular['callbacks'] = {}),
angularAlert = angular['alert'] || (angular['alert'] = function(){
log(arguments); window.alert.apply(window, arguments);
diff --git a/src/Formaters.js b/src/Formaters.js
deleted file mode 100644
index e623d6b8..00000000
--- a/src/Formaters.js
+++ /dev/null
@@ -1,6 +0,0 @@
-
-extend(angularFormater, {
- 'noop':function(){
-
- }
-});
diff --git a/src/Formatters.js b/src/Formatters.js
new file mode 100644
index 00000000..74126feb
--- /dev/null
+++ b/src/Formatters.js
@@ -0,0 +1,14 @@
+function formater(format, parse) {return {'format':format, 'parse':parse};}
+function toString(obj) {return ""+obj;};
+extend(angularFormatter, {
+ 'noop':formater(identity, identity),
+ 'boolean':formater(toString, toBoolean),
+ 'number':formater(toString, function(obj){return 1*obj;}),
+
+ 'list':formater(
+ function(obj) { return obj ? obj.join(", ") : obj; },
+ function(value) {
+ return value ? _(_(value.split(',')).map(jQuery.trim)).select(_.identity) : value;
+ }
+ )
+});
diff --git a/src/Widgets.js b/src/Widgets.js
index d85c0ddc..d392d285 100644
--- a/src/Widgets.js
+++ b/src/Widgets.js
@@ -19,25 +19,26 @@ WidgetFactory.prototype = {
if (exp) exp = exp.split(':').pop();
var event = "change";
var bubbleEvent = true;
+ var formatter = angularFormatter[input.attr('ng-format')] || angularFormatter['noop'];
if (type == 'button' || type == 'submit' || type == 'reset' || type == 'image') {
- controller = new ButtonController(input[0], exp);
+ controller = new ButtonController(input[0], exp, formatter);
event = "click";
bubbleEvent = false;
} else if (type == 'text' || type == 'textarea' || type == 'hidden' || type == 'password') {
- controller = new TextController(input[0], exp);
+ controller = new TextController(input[0], exp, formatter);
event = "keyup change";
} else if (type == 'checkbox') {
- controller = new CheckboxController(input[0], exp);
+ controller = new CheckboxController(input[0], exp, formatter);
event = "click";
} else if (type == 'radio') {
- controller = new RadioController(input[0], exp);
+ controller = new RadioController(input[0], exp, formatter);
event="click";
} else if (type == 'select-one') {
- controller = new SelectController(input[0], exp);
+ controller = new SelectController(input[0], exp, formatter);
} else if (type == 'select-multiple') {
- controller = new MultiSelectController(input[0], exp);
+ controller = new MultiSelectController(input[0], exp, formatter);
} else if (type == 'file') {
- controller = this.createFileController(input, exp);
+ controller = this.createFileController(input, exp, formatter);
} else {
throw 'Unknown type: ' + type;
}
@@ -186,8 +187,9 @@ var ButtonController = NullController;
///////////////////////
// TextController
///////////////////////
-function TextController(view, exp) {
+function TextController(view, exp, formatter) {
this.view = view;
+ this.formatter = formatter;
this.exp = exp;
this.validator = view.getAttribute('ng-validate');
this.required = typeof view.attributes['ng-required'] != "undefined";
@@ -206,7 +208,7 @@ TextController.prototype = {
if (this.lastValue === value) {
return false;
} else {
- scope.setEval(this.exp, value);
+ scope.setEval(this.exp, this.formatter['parse'](value));
this.lastValue = value;
return true;
}
@@ -214,10 +216,10 @@ TextController.prototype = {
updateView: function(scope) {
var view = this.view;
- var value = scope.get(this.exp);
+ var value = this.formatter['format'](scope.get(this.exp));
if (typeof value === "undefined") {
value = this.initialValue;
- scope.setEval(this.exp, value);
+ scope.setEval(this.exp, this.formatter['parse'](value));
}
value = value ? value : '';
if (this.lastValue != value) {
@@ -248,21 +250,23 @@ TextController.prototype = {
///////////////////////
// CheckboxController
///////////////////////
-function CheckboxController(view, exp) {
+function CheckboxController(view, exp, formatter) {
this.view = view;
this.exp = exp;
this.lastValue = undefined;
+ this.formatter = formatter;
this.initialValue = view.checked ? view.value : "";
};
CheckboxController.prototype = {
- updateModel: function(scope) {
+ updateModel: function(scope) {
+ jstd.console.log("model");
var input = this.view;
var value = input.checked ? input.value : '';
if (this.lastValue === value) {
return false;
} else {
- scope.setEval(this.exp, value);
+ scope.setEval(this.exp, this.formatter['parse'](value));
this.lastValue = value;
return true;
}
@@ -273,9 +277,10 @@ CheckboxController.prototype = {
var value = scope.eval(this.exp);
if (typeof value === "undefined") {
value = this.initialValue;
- scope.setEval(this.exp, value);
+ scope.setEval(this.exp, this.formatter['parse'](value));
}
- input.checked = input.value == (''+value);
+ value = this.formatter['format'](value);
+ input.checked = input.value == value;
}
};
diff --git a/test/BinderTest.js b/test/BinderTest.js
index cf2fa31a..450100e4 100644
--- a/test/BinderTest.js
+++ b/test/BinderTest.js
@@ -129,10 +129,10 @@ BinderTest.prototype.testChangingRadioUpdatesModel = function(){
};
BinderTest.prototype.testChangingCheckboxUpdatesModel = function(){
- var form = compile('<input type="checkbox" name="model.price" value="A" checked>');
+ var form = compile('<input type="checkbox" name="model.price" value="true" checked ng-format="boolean">');
form.scope.set('model', {});
form.binder.updateView();
- assertEquals('A', form.scope.get('model').price);
+ assertEquals(true, form.scope.get('model').price);
};
BinderTest.prototype.testBindUpdate = function() {
@@ -951,3 +951,16 @@ BinderTest.prototype.testItShouldRenderMultiRootHtmlInBinding = function() {
'<div>before <span ng-bind="a|html">a<b>c</b>d</span>after</div>',
x.node.sortedHtml());
};
+
+BinderTest.prototype.testItShouldUseFormaterForText = function() {
+ var x = compile('<input name="a" ng-format="list" value="a,b">');
+ x.binder.updateView();
+ assertEquals(['a','b'], x.scope.get('a'));
+ var input = x.node.find('input');
+ input[0].value = ' x,,yz';
+ input.change();
+ assertEquals(['x','yz'], x.scope.get('a'));
+ x.scope.set('a', [1 ,2, 3]);
+ x.binder.updateView();
+ assertEquals('1, 2, 3', input[0].value);
+};
diff --git a/test/FormatersTest.js b/test/FormatersTest.js
deleted file mode 100644
index 0122b6ad..00000000
--- a/test/FormatersTest.js
+++ /dev/null
@@ -1,6 +0,0 @@
-TestCase("formaterTest", {
- testNoop: function(){
- assertEquals("abc", angular.formater.noop("abc"));
- assertEquals("xyz", angular.formater.noop("abc", "xyz"));
- }
-});
diff --git a/test/FormattersTest.js b/test/FormattersTest.js
new file mode 100644
index 00000000..b71e68dc
--- /dev/null
+++ b/test/FormattersTest.js
@@ -0,0 +1,28 @@
+TestCase("formatterTest", {
+ testNoop: function(){
+ assertEquals("abc", angular.formatter.noop.format("abc"));
+ assertEquals("xyz", angular.formatter.noop.parse("xyz"));
+ assertEquals(null, angular.formatter.noop.parse(null));
+ },
+
+ testList: function() {
+ assertEquals('a, b', angular.formatter.list.format(['a', 'b']));
+ assertEquals(['abc', 'c'], angular.formatter.list.parse(" , abc , c ,,"));
+ assertEquals(null, angular.formatter.list.parse(null));
+ },
+
+ testBoolean: function() {
+ assertEquals('true', angular.formatter.boolean.format(true));
+ assertEquals('false', angular.formatter.boolean.format(false));
+ assertEquals(true, angular.formatter.boolean.parse("true"));
+ assertEquals(false, angular.formatter.boolean.parse(""));
+ assertEquals(false, angular.formatter.boolean.parse("false"));
+ assertEquals(null, angular.formatter.boolean.parse(null));
+ },
+
+ testNumber: function() {
+ assertEquals('1', angular.formatter.number.format(1));
+ assertEquals(1, angular.formatter.number.format('1'));
+ }
+
+});
diff --git a/test/WidgetsTest.js b/test/WidgetsTest.js
index c0a2d082..4e3852a5 100644
--- a/test/WidgetsTest.js
+++ b/test/WidgetsTest.js
@@ -3,7 +3,7 @@ WidgetTest = TestCase('WidgetTest');
WidgetTest.prototype.testRequired = function () {
var view = $('<input name="a" ng-required>');
var scope = new Scope({$invalidWidgets:[]});
- var cntl = new TextController(view[0], 'a');
+ var cntl = new TextController(view[0], 'a', angularFormatter.noop);
cntl.updateView(scope);
assertTrue(view.hasClass('ng-validation-error'));
assertEquals("Required Value", view.attr('ng-error'));
@@ -16,7 +16,7 @@ WidgetTest.prototype.testRequired = function () {
WidgetTest.prototype.testValidator = function () {
var view = $('<input name="a" ng-validate="testValidator:\'ABC\'">');
var scope = new Scope({$invalidWidgets:[]});
- var cntl = new TextController(view[0], 'a');
+ var cntl = new TextController(view[0], 'a', angularFormatter.noop);
angular.validator.testValidator = function(value, expect){
return value == expect ? null : "Error text";
};
@@ -44,7 +44,7 @@ WidgetTest.prototype.testValidator = function () {
WidgetTest.prototype.testRequiredValidator = function () {
var view = $('<input name="a" ng-required ng-validate="testValidator:\'ABC\'">');
var scope = new Scope({$invalidWidgets:[]});
- var cntl = new TextController(view[0], 'a');
+ var cntl = new TextController(view[0], 'a', angularFormatter.noop);
angular.validator.testValidator = function(value, expect){
return value == expect ? null : "Error text";
};