diff options
| author | Misko Hevery | 2010-01-28 22:10:49 -0800 | 
|---|---|---|
| committer | Misko Hevery | 2010-01-28 22:11:01 -0800 | 
| commit | a9c182764b5feeb2466c4bb32f7572762f7fab6d (patch) | |
| tree | 48105ad598ca6779e3308b06b12576a366e9be71 | |
| parent | dd9d8bf030688f589af6d47064a0d0eafea41bfa (diff) | |
| download | angular.js-a9c182764b5feeb2466c4bb32f7572762f7fab6d.tar.bz2 | |
added formatters
| -rw-r--r-- | Rakefile | 1 | ||||
| -rw-r--r-- | src/Angular.js | 3 | ||||
| -rw-r--r-- | src/Formaters.js | 6 | ||||
| -rw-r--r-- | src/Formatters.js | 14 | ||||
| -rw-r--r-- | src/Widgets.js | 37 | ||||
| -rw-r--r-- | test/BinderTest.js | 17 | ||||
| -rw-r--r-- | test/FormatersTest.js | 6 | ||||
| -rw-r--r-- | test/FormattersTest.js | 28 | ||||
| -rw-r--r-- | test/WidgetsTest.js | 6 | 
9 files changed, 84 insertions, 34 deletions
@@ -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";    };  | 
