mirror of
https://github.com/Hopiu/angular.js.git
synced 2026-05-17 19:11:08 +00:00
Added formatter documentation.
This commit is contained in:
parent
96e37a0866
commit
c048f0d8e8
4 changed files with 276 additions and 2 deletions
24
docs/formatter.template
Normal file
24
docs/formatter.template
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
<h1><tt>{{name}}</tt></h1>
|
||||||
|
<h2>Description</h2>
|
||||||
|
{{{description}}}
|
||||||
|
|
||||||
|
<h2>Usage</h2>
|
||||||
|
<h3>In HTML Template Binding</h3>
|
||||||
|
<tt>
|
||||||
|
<input type="text" ng:format="{{shortName}}">
|
||||||
|
</tt>
|
||||||
|
<h3>In JavaScript</h3>
|
||||||
|
<tt ng:non-bindable>
|
||||||
|
var userInputString = angular.formatter.{{shortName}}.format(modelValue);<br/>
|
||||||
|
var modelValue = angular.formatter.{{shortName}}.parse(userInputString);
|
||||||
|
</tt>
|
||||||
|
|
||||||
|
<h3>Returns</h3>
|
||||||
|
{{{returns}}}
|
||||||
|
|
||||||
|
<h3>CSS</h3>
|
||||||
|
{{{css}}}
|
||||||
|
|
||||||
|
<WIKI:SOURCE style="display:block;">
|
||||||
|
{{{example}}}
|
||||||
|
</WIKI:SOURCE>
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
<h1><tt>{{name}}</tt></h1>
|
<h1><tt>{{name}}</tt></h1>
|
||||||
{{{description}}}
|
{{{description}}}
|
||||||
|
|
||||||
<WIKI:SOURCE style="display:block;">
|
{{#example}}<WIKI:SOURCE style="display:block;">{{/example}}
|
||||||
{{{example}}}
|
{{{example}}}
|
||||||
</WIKI:SOURCE>
|
{{#example}}</WIKI:SOURCE>{{/example}}
|
||||||
|
|
|
||||||
132
src/Angular.js
132
src/Angular.js
|
|
@ -92,6 +92,65 @@ var _undefined = undefined,
|
||||||
angularTextMarkup = extensionMap(angular, 'markup'),
|
angularTextMarkup = extensionMap(angular, 'markup'),
|
||||||
angularAttrMarkup = extensionMap(angular, 'attrMarkup'),
|
angularAttrMarkup = extensionMap(angular, 'attrMarkup'),
|
||||||
angularDirective = extensionMap(angular, 'directive'),
|
angularDirective = extensionMap(angular, 'directive'),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ngdoc overview
|
||||||
|
* @name angular.widget
|
||||||
|
* @namespace Namespace for all widgets.
|
||||||
|
* @description
|
||||||
|
* # Overview
|
||||||
|
* Widgets allow you to create DOM elements that the browser doesn't
|
||||||
|
* already understand. You create the widget in your namespace and
|
||||||
|
* assign it behavior. You can only bind one widget per DOM element
|
||||||
|
* (unlike directives, in which you can use any number per DOM
|
||||||
|
* element). Widgets are expected to manipulate the DOM tree by
|
||||||
|
* adding new elements whereas directives are expected to only modify
|
||||||
|
* element properties.
|
||||||
|
*
|
||||||
|
* Widgets come in two flavors: element and attribute.
|
||||||
|
*
|
||||||
|
* # Element Widget
|
||||||
|
* Let's say we would like to create a new element type in the
|
||||||
|
* namespace `my` that can watch an expression and alert() the user
|
||||||
|
* with each new value.
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* <my:watch exp="name"/>
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* You can implement `my:watch` like this:
|
||||||
|
* <pre>
|
||||||
|
* angular.widget('my:watch', function(compileElement) {
|
||||||
|
* var compiler = this;
|
||||||
|
* var exp = compileElement.attr('exp');
|
||||||
|
* return function(linkElement) {
|
||||||
|
* var currentScope = this;
|
||||||
|
* currentScope.$watch(exp, function(value){
|
||||||
|
* alert(value);
|
||||||
|
* }};
|
||||||
|
* };
|
||||||
|
* });
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* # Attribute Widget
|
||||||
|
* Let's implement the same widget, but this time as an attribute
|
||||||
|
* that can be added to any existing DOM element.
|
||||||
|
* <pre>
|
||||||
|
* <div my-watch="name">text</div>
|
||||||
|
* </pre>
|
||||||
|
* You can implement `my:watch` attribute like this:
|
||||||
|
* <pre>
|
||||||
|
* angular.widget('@my:watch', function(expression, compileElement) {
|
||||||
|
* var compiler = this;
|
||||||
|
* return function(linkElement) {
|
||||||
|
* var currentScope = this;
|
||||||
|
* currentScope.$watch(expression, function(value){
|
||||||
|
* alert(value);
|
||||||
|
* });
|
||||||
|
* };
|
||||||
|
* });
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
angularWidget = extensionMap(angular, 'widget', lowercase),
|
angularWidget = extensionMap(angular, 'widget', lowercase),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -224,6 +283,79 @@ var _undefined = undefined,
|
||||||
|
|
||||||
*/
|
*/
|
||||||
angularFilter = extensionMap(angular, 'filter'),
|
angularFilter = extensionMap(angular, 'filter'),
|
||||||
|
/**
|
||||||
|
* @ngdoc overview
|
||||||
|
* @name angular.formatter
|
||||||
|
* @namespace Namespace for all formats.
|
||||||
|
* @description
|
||||||
|
* # Overview
|
||||||
|
* The formatters are responsible for translating user readable text in an input widget to a
|
||||||
|
* data model stored in an application.
|
||||||
|
*
|
||||||
|
* # Writting your own Fromatter
|
||||||
|
* Writing your own formatter is easy. Just register a pair of JavaScript functions with
|
||||||
|
* `angular.formatter`. One function for parsing user input text to the stored form,
|
||||||
|
* and one for formatting the stored data to user-visible text.
|
||||||
|
*
|
||||||
|
* Here is an example of a "reverse" formatter: The data is stored in uppercase and in
|
||||||
|
* reverse, while it is displayed in lower case and non-reversed. User edits are
|
||||||
|
* automatically parsed into the internal form and data changes are automatically
|
||||||
|
* formatted to the viewed form.
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* function reverse(text) {
|
||||||
|
* var reversed = [];
|
||||||
|
* for (var i = 0; i < text.length; i++) {
|
||||||
|
* reversed.unshift(text.charAt(i));
|
||||||
|
* }
|
||||||
|
* return reversed.join('');
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* angular.formatter('reverse', {
|
||||||
|
* parse: function(value){
|
||||||
|
* return reverse(value||'').toUpperCase();
|
||||||
|
* },
|
||||||
|
* format: function(value){
|
||||||
|
* return reverse(value||'').toLowerCase();
|
||||||
|
* }
|
||||||
|
* });
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* <script>
|
||||||
|
* function reverse(text) {
|
||||||
|
* var reversed = [];
|
||||||
|
* for (var i = 0; i < text.length; i++) {
|
||||||
|
* reversed.unshift(text.charAt(i));
|
||||||
|
* }
|
||||||
|
* return reversed.join('');
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* angular.formatter('reverse', {
|
||||||
|
* parse: function(value){
|
||||||
|
* return reverse(value||'').toUpperCase();
|
||||||
|
* },
|
||||||
|
* format: function(value){
|
||||||
|
* return reverse(value||'').toLowerCase();
|
||||||
|
* }
|
||||||
|
* });
|
||||||
|
* </script>
|
||||||
|
* Formatted: <input type="text" name="data" value="<angular/>" ng:format="reverse"/><br/>
|
||||||
|
* Stored: <input type="text" name="data"/><br/>
|
||||||
|
* <pre>{{data}}</pre>
|
||||||
|
*
|
||||||
|
* @scenario
|
||||||
|
* it('should store reverse', function(){
|
||||||
|
* expect(element('.example :input:first').val()).toEqual('<angular/>');
|
||||||
|
* expect(element('.example :input:last').val()).toEqual('>/RALUGNA<');
|
||||||
|
*
|
||||||
|
* this.addFutureAction('change to XYZ', function($window, $document, done){
|
||||||
|
* $document.elements('.example :input:last').val('XYZ').trigger('change');
|
||||||
|
* done();
|
||||||
|
* });
|
||||||
|
* expect(element('.example :input:first').val()).toEqual('zyx');
|
||||||
|
* });
|
||||||
|
*/
|
||||||
angularFormatter = extensionMap(angular, 'formatter'),
|
angularFormatter = extensionMap(angular, 'formatter'),
|
||||||
angularService = extensionMap(angular, 'service'),
|
angularService = extensionMap(angular, 'service'),
|
||||||
angularCallbacks = extensionMap(angular, 'callbacks'),
|
angularCallbacks = extensionMap(angular, 'callbacks'),
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,76 @@ function toString(obj) {
|
||||||
var NUMBER = /^\s*[-+]?\d*(\.\d*)?\s*$/;
|
var NUMBER = /^\s*[-+]?\d*(\.\d*)?\s*$/;
|
||||||
|
|
||||||
angularFormatter.noop = formatter(identity, identity);
|
angularFormatter.noop = formatter(identity, identity);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ngdoc formatter
|
||||||
|
* @name angular.formatter.json
|
||||||
|
*
|
||||||
|
* @description
|
||||||
|
* Formats the user input as JSON text.
|
||||||
|
*
|
||||||
|
* @returns {string} A JSON string representation of the model.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* <div ng:init="data={name:'misko', project:'angular'}">
|
||||||
|
* <input type="text" size='50' name="data" ng:format="json"/>
|
||||||
|
* <pre>data={{data}}</pre>
|
||||||
|
* </div>
|
||||||
|
*
|
||||||
|
* @scenario
|
||||||
|
* it('should format json', function(){
|
||||||
|
* expect(binding('data')).toEqual('data={\n \"name\":\"misko\",\n \"project\":\"angular\"}');
|
||||||
|
* input('data').enter('{}');
|
||||||
|
* expect(binding('data')).toEqual('data={\n }');
|
||||||
|
* });
|
||||||
|
*/
|
||||||
angularFormatter.json = formatter(toJson, fromJson);
|
angularFormatter.json = formatter(toJson, fromJson);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ngdoc formatter
|
||||||
|
* @name angular.formatter.boolean
|
||||||
|
*
|
||||||
|
* @description
|
||||||
|
* Use boolean formatter if you wish to store the data as boolean.
|
||||||
|
*
|
||||||
|
* @returns Convert to `true` unless user enters (blank), `f`, `false`, `0`, `no`, `[]`.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* Enter truthy text:
|
||||||
|
* <input type="text" name="value" ng:format="boolean" value="no"/>
|
||||||
|
* <input type="checkbox" name="value"/>
|
||||||
|
* <pre>value={{value}}</pre>
|
||||||
|
*
|
||||||
|
* @scenario
|
||||||
|
* it('should format boolean', function(){
|
||||||
|
* expect(binding('value')).toEqual('value=false');
|
||||||
|
* input('value').enter('truthy');
|
||||||
|
* expect(binding('value')).toEqual('value=true');
|
||||||
|
* });
|
||||||
|
*/
|
||||||
angularFormatter['boolean'] = formatter(toString, toBoolean);
|
angularFormatter['boolean'] = formatter(toString, toBoolean);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ngdoc formatter
|
||||||
|
* @name angular.formatter.number
|
||||||
|
*
|
||||||
|
* @description
|
||||||
|
* Use number formatter if you wish to convert the user entered string to a number.
|
||||||
|
*
|
||||||
|
* @returns parse string to number.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* Enter valid number:
|
||||||
|
* <input type="text" name="value" ng:format="number" value="1234"/>
|
||||||
|
* <pre>value={{value}}</pre>
|
||||||
|
*
|
||||||
|
* @scenario
|
||||||
|
* it('should format numbers', function(){
|
||||||
|
* expect(binding('value')).toEqual('value=1234');
|
||||||
|
* input('value').enter('5678');
|
||||||
|
* expect(binding('value')).toEqual('value=5678');
|
||||||
|
* });
|
||||||
|
*/
|
||||||
angularFormatter.number = formatter(toString, function(obj){
|
angularFormatter.number = formatter(toString, function(obj){
|
||||||
if (obj == _null || NUMBER.exec(obj)) {
|
if (obj == _null || NUMBER.exec(obj)) {
|
||||||
return obj===_null || obj === '' ? _null : 1*obj;
|
return obj===_null || obj === '' ? _null : 1*obj;
|
||||||
|
|
@ -16,6 +84,31 @@ angularFormatter.number = formatter(toString, function(obj){
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ngdoc formatter
|
||||||
|
* @name angular.formatter.list
|
||||||
|
*
|
||||||
|
* @description
|
||||||
|
* Use number formatter if you wish to convert the user entered string to a number.
|
||||||
|
*
|
||||||
|
* @returns parse string to number.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* Enter a list of items:
|
||||||
|
* <input type="text" name="value" ng:format="list" value=" chair ,, table"/>
|
||||||
|
* <input type="text" name="value" ng:format="list"/>
|
||||||
|
* <pre>value={{value}}</pre>
|
||||||
|
*
|
||||||
|
* @scenario
|
||||||
|
* it('should format lists', function(){
|
||||||
|
* expect(binding('value')).toEqual('value=["chair","table"]');
|
||||||
|
* this.addFutureAction('change to XYZ', function($window, $document, done){
|
||||||
|
* $document.elements('.example :input:last').val(',,a,b,').trigger('change');
|
||||||
|
* done();
|
||||||
|
* });
|
||||||
|
* expect(binding('value')).toEqual('value=["a","b"]');
|
||||||
|
* });
|
||||||
|
*/
|
||||||
angularFormatter.list = formatter(
|
angularFormatter.list = formatter(
|
||||||
function(obj) { return obj ? obj.join(", ") : obj; },
|
function(obj) { return obj ? obj.join(", ") : obj; },
|
||||||
function(value) {
|
function(value) {
|
||||||
|
|
@ -28,6 +121,31 @@ angularFormatter.list = formatter(
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ngdoc formatter
|
||||||
|
* @name angular.formatter.trim
|
||||||
|
*
|
||||||
|
* @description
|
||||||
|
* Use trim formatter if you wish to trim extra spaces in user text.
|
||||||
|
*
|
||||||
|
* @returns {String} Trim excess leading and trailing space.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* Enter text with leading/trailing spaces:
|
||||||
|
* <input type="text" name="value" ng:format="trim" value=" book "/>
|
||||||
|
* <input type="text" name="value" ng:format="trim"/>
|
||||||
|
* <pre>value={{value|json}}</pre>
|
||||||
|
*
|
||||||
|
* @scenario
|
||||||
|
* it('should format trim', function(){
|
||||||
|
* expect(binding('value')).toEqual('value="book"');
|
||||||
|
* this.addFutureAction('change to XYZ', function($window, $document, done){
|
||||||
|
* $document.elements('.example :input:last').val(' text ').trigger('change');
|
||||||
|
* done();
|
||||||
|
* });
|
||||||
|
* expect(binding('value')).toEqual('value="text"');
|
||||||
|
* });
|
||||||
|
*/
|
||||||
angularFormatter.trim = formatter(
|
angularFormatter.trim = formatter(
|
||||||
function(obj) { return obj ? trim("" + obj) : ""; }
|
function(obj) { return obj ? trim("" + obj) : ""; }
|
||||||
);
|
);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue