aboutsummaryrefslogtreecommitdiffstats
path: root/src/widgets.js
diff options
context:
space:
mode:
authorDi Peng2011-08-16 16:00:16 -0700
committerIgor Minar2011-08-30 02:11:09 -0700
commite068addadb14b44374ebb5353b860700731c866f (patch)
tree73d43d7df45af3ba46ac89bbcb515ad0452d6488 /src/widgets.js
parent0da4902e9db4f6f494b8be74c41f21d5e5520b79 (diff)
downloadangular.js-e068addadb14b44374ebb5353b860700731c866f.tar.bz2
feat(widget): add ng:pluralize as an Angular widget
Diffstat (limited to 'src/widgets.js')
-rw-r--r--src/widgets.js192
1 files changed, 192 insertions, 0 deletions
diff --git a/src/widgets.js b/src/widgets.js
index 16053b08..a1c4c5d6 100644
--- a/src/widgets.js
+++ b/src/widgets.js
@@ -1445,3 +1445,195 @@ angularWidget('ng:view', function(element) {
compiler.directives(true);
}
});
+
+
+/**
+ * @ngdoc widget
+ * @name angular.widget.ng:pluralize
+ *
+ * @description
+ * # Overview
+ * ng:pluralize is a widget that displays messages according to en-US localization rules.
+ * These rules are bundled with angular.js and the rules can be overridden
+ * (see {@link guide/dev_guide.i18n Angular i18n} dev guide). You configure ng:pluralize by
+ * specifying the mappings between
+ * {@link http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html
+ * plural categories} and the strings to be displayed.
+ *
+ * # Plural categories and explicit number rules
+ * There are two
+ * {@link http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html
+ * plural categories} in Angular's default en-US locale: "one" and "other".
+ *
+ * While a pural category may match many numbers (for example, in en-US locale, "other" can match
+ * any number that is not 1), an explicit number rule can only match one number. For example, the
+ * explicit number rule for "3" matches the number 3. You will see the use of plural categories
+ * and explicit number rules throughout later parts of this documentation.
+ *
+ * # Configuring ng:pluralize
+ * You configure ng:pluralize by providing 2 attributes: `count` and `when`.
+ * You can also provide an optional attribute, `offset`.
+ *
+ * The value of the `count` attribute can be either a string or an {@link guide/dev_guide.expressions
+ * Angular expression}; these are evaluated on the current scope for its binded value.
+ *
+ * The `when` attribute specifies the mappings between plural categories and the actual
+ * string to be displayed. The value of the attribute should be a JSON object so that Angular
+ * can interpret it correctly.
+ *
+ * The following example shows how to configure ng:pluralize:
+ *
+ * <pre>
+ * <ng:pluralize count="personCount"
+ when="{'0': 'Nobody is viewing.',
+ * 'one': '1 person is viewing.',
+ * 'other': '{} people are viewing.'}">
+ * </ng:pluralize>
+ *</pre>
+ *
+ * In the example, `"0: Nobody is viewing."` is an explicit number rule. If you did not
+ * specify this rule, 0 would be matched to the "other" category and "0 people are viewing"
+ * would be shown instead of "Nobody is viewing". You can specify an explicit number rule for
+ * other numbers, for example 12, so that instead of showing "12 people are viewing", you can
+ * show "a dozen people are viewing".
+ *
+ * You can use a set of closed braces(`{}`) as a placeholder for the number that you want substituted
+ * into pluralized strings. In the previous example, Angular will replace `{}` with
+ * <span ng:non-bindable>`{{personCount}}`</span>. The closed braces `{}` is a placeholder
+ * for <span ng:non-bindable>{{numberExpression}}</span>.
+ *
+ * # Configuring ng:pluralize with offset
+ * The `offset` attribute allows further customization of pluralized text, which can result in
+ * a better user experience. For example, instead of the message "4 people are viewing this document",
+ * you might display "John, Kate and 2 others are viewing this document".
+ * The offset attribute allows you to offset a number by any desired value.
+ * Let's take a look at an example:
+ *
+ * <pre>
+ * <ng:pluralize count="personCount" offset=2
+ * when="{'0': 'Nobody is viewing.',
+ * '1': '{{person1}} is viewing.',
+ * '2': '{{person1}} and {{person2}} are viewing.',
+ * 'one': '{{person1}}, {{person2}} and one other person are viewing.',
+ * 'other': '{{person1}}, {{person2}} and {} other people are viewing.'}">
+ * </ng:pluralize>
+ * </pre>
+ *
+ * Notice that we are still using two plural categories(one, other), but we added
+ * three explicit number rules 0, 1 and 2.
+ * When one person, perhaps John, views the document, "John is viewing" will be shown.
+ * When three people view the document, no explicit number rule is found, so
+ * an offset of 2 is taken off 3, and Angular uses 1 to decide the plural category.
+ * In this case, plural category 'one' is matched and "John, Marry and one other person are viewing"
+ * is shown.
+ *
+ * Note that when you specify offsets, you must provide explicit number rules for
+ * numbers from 0 up to and including the offset. If you use an offset of 3, for example,
+ * you must provide explicit number rules for 0, 1, 2 and 3. You must also provide plural strings for
+ * plural categories "one" and "other".
+ *
+ * @param {string|expression} count The variable to be bounded to.
+ * @param {string} when The mapping between plural category to its correspoding strings.
+ * @param {number=} offset Offset to deduct from the total number.
+ *
+ * @example
+ <doc:example>
+ <doc:source>
+ Person 1:<input type="text" name="person1" value="Igor" /><br/>
+ Person 2:<input type="text" name="person2" value="Misko" /><br/>
+ Number of People:<input type="text" name="personCount" value="1" /><br/>
+
+ <!--- Example with simple pluralization rules for en locale --->
+ Without Offset:
+ <ng:pluralize count="personCount"
+ when="{'0': 'Nobody is viewing.',
+ 'one': '1 person is viewing.',
+ 'other': '{} people are viewing.'}">
+ </ng:pluralize><br>
+
+ <!--- Example with offset --->
+ With Offset(2):
+ <ng:pluralize count="personCount" offset=2
+ when="{'0': 'Nobody is viewing.',
+ '1': '{{person1}} is viewing.',
+ '2': '{{person1}} and {{person2}} are viewing.',
+ 'one': '{{person1}}, {{person2}} and one other person are viewing.',
+ 'other': '{{person1}}, {{person2}} and {} other people are viewing.'}">
+ </ng:pluralize>
+ </doc:source>
+ <doc:scenario>
+ it('should show correct pluralized string', function(){
+ expect(element('.doc-example-live .ng-pluralize:first').text()).
+ toBe('1 person is viewing.');
+ expect(element('.doc-example-live .ng-pluralize:last').text()).
+ toBe('Igor is viewing.');
+
+ using('.doc-example-live').input('personCount').enter('0');
+ expect(element('.doc-example-live .ng-pluralize:first').text()).
+ toBe('Nobody is viewing.');
+ expect(element('.doc-example-live .ng-pluralize:last').text()).
+ toBe('Nobody is viewing.');
+
+ using('.doc-example-live').input('personCount').enter('2');
+ expect(element('.doc-example-live .ng-pluralize:first').text()).
+ toBe('2 people are viewing.');
+ expect(element('.doc-example-live .ng-pluralize:last').text()).
+ toBe('Igor and Misko are viewing.');
+
+ using('.doc-example-live').input('personCount').enter('3');
+ expect(element('.doc-example-live .ng-pluralize:first').text()).
+ toBe('3 people are viewing.');
+ expect(element('.doc-example-live .ng-pluralize:last').text()).
+ toBe('Igor, Misko and one other person are viewing.');
+
+ using('.doc-example-live').input('personCount').enter('4');
+ expect(element('.doc-example-live .ng-pluralize:first').text()).
+ toBe('4 people are viewing.');
+ expect(element('.doc-example-live .ng-pluralize:last').text()).
+ toBe('Igor, Misko and 2 other people are viewing.');
+ });
+
+ it('should show data-binded names', function(){
+ using('.doc-example-live').input('personCount').enter('4');
+ expect(element('.doc-example-live .ng-pluralize:last').text()).
+ toBe('Igor, Misko and 2 other people are viewing.');
+
+ using('.doc-example-live').input('person1').enter('Di');
+ using('.doc-example-live').input('person2').enter('Vojta');
+ expect(element('.doc-example-live .ng-pluralize:last').text()).
+ toBe('Di, Vojta and 2 other people are viewing.');
+ });
+ </doc:scenario>
+ </doc:example>
+ */
+angularWidget('ng:pluralize', function(element) {
+ var numberExp = element.attr('count'),
+ whenExp = element.attr('when'),
+ offset = element.attr('offset') || 0;
+
+ return annotate('$locale', function($locale, element) {
+ var scope = this,
+ whens = scope.$eval(whenExp),
+ whensExpFns = {};
+
+ forEach(whens, function(expression, key) {
+ whensExpFns[key] = compileBindTemplate(expression.replace(/{}/g,
+ '{{' + numberExp + '-' + offset + '}}'));
+ });
+
+ scope.$watch(function() {
+ var value = parseFloat(scope.$eval(numberExp));
+
+ if (!isNaN(value)) {
+ //if explicit number rule such as 1, 2, 3... is defined, just use it. Otherwise,
+ //check it against pluralization rules in $locale service
+ if (!whens[value]) value = $locale.pluralCat(value - offset);
+ return whensExpFns[value](scope, element, true);
+ } else {
+ return '';
+ }
+ }, function(scope, newVal) {
+ element.text(newVal);
+ });
+ });
+});