|
6 | 6 | * @function
|
7 | 7 | *
|
8 | 8 | * @description
|
9 |
| - * Creates a new array containing only a specified number of elements in an array. The elements |
10 |
| - * are taken from either the beginning or the end of the source array, as specified by the |
11 |
| - * value and sign (positive or negative) of `limit`. |
| 9 | + * Creates a new array or string containing only a specified number of elements. The elements |
| 10 | + * are taken from either the beginning or the end of the source array or string, as specified by |
| 11 | + * the value and sign (positive or negative) of `limit`. |
12 | 12 | *
|
13 | 13 | * Note: This function is used to augment the `Array` type in Angular expressions. See
|
14 | 14 | * {@link ng.$filter} for more information about Angular arrays.
|
15 | 15 | *
|
16 |
| - * @param {Array} array Source array to be limited. |
17 |
| - * @param {string|Number} limit The length of the returned array. If the `limit` number is |
18 |
| - * positive, `limit` number of items from the beginning of the source array are copied. |
19 |
| - * If the number is negative, `limit` number of items from the end of the source array are |
20 |
| - * copied. The `limit` will be trimmed if it exceeds `array.length` |
21 |
| - * @returns {Array} A new sub-array of length `limit` or less if input array had less than `limit` |
22 |
| - * elements. |
| 16 | + * @param {Array|string} input Source array or string to be limited. |
| 17 | + * @param {string|number} limit The length of the returned array or string. If the `limit` number |
| 18 | + * is positive, `limit` number of items from the beginning of the source array/string are copied. |
| 19 | + * If the number is negative, `limit` number of items from the end of the source array/string |
| 20 | + * are copied. The `limit` will be trimmed if it exceeds `array.length` |
| 21 | + * @returns {Array|string} A new sub-array or substring of length `limit` or less if input array |
| 22 | + * had less than `limit` elements. |
23 | 23 | *
|
24 | 24 | * @example
|
25 | 25 | <doc:example>
|
26 | 26 | <doc:source>
|
27 | 27 | <script>
|
28 | 28 | function Ctrl($scope) {
|
29 | 29 | $scope.numbers = [1,2,3,4,5,6,7,8,9];
|
30 |
| - $scope.limit = 3; |
| 30 | + $scope.letters = "abcdefghi"; |
| 31 | + $scope.numLimit = 3; |
| 32 | + $scope.letterLimit = 3; |
31 | 33 | }
|
32 | 34 | </script>
|
33 | 35 | <div ng-controller="Ctrl">
|
34 |
| - Limit {{numbers}} to: <input type="integer" ng-model="limit"> |
35 |
| - <p>Output: {{ numbers | limitTo:limit }}</p> |
| 36 | + Limit {{numbers}} to: <input type="integer" ng-model="numLimit"> |
| 37 | + <p>Output numbers: {{ numbers | limitTo:numLimit }}</p> |
| 38 | + Limit {{letters}} to: <input type="integer" ng-model="letterLimit"> |
| 39 | + <p>Output letters: {{ letters | limitTo:letterLimit }}</p> |
36 | 40 | </div>
|
37 | 41 | </doc:source>
|
38 | 42 | <doc:scenario>
|
39 |
| - it('should limit the numer array to first three items', function() { |
40 |
| - expect(element('.doc-example-live input[ng-model=limit]').val()).toBe('3'); |
41 |
| - expect(binding('numbers | limitTo:limit')).toEqual('[1,2,3]'); |
| 43 | + it('should limit the number array to first three items', function() { |
| 44 | + expect(element('.doc-example-live input[ng-model=numLimit]').val()).toBe('3'); |
| 45 | + expect(element('.doc-example-live input[ng-model=letterLimit]').val()).toBe('3'); |
| 46 | + expect(binding('numbers | limitTo:numLimit')).toEqual('[1,2,3]'); |
| 47 | + expect(binding('letters | limitTo:letterLimit')).toEqual('abc'); |
42 | 48 | });
|
43 | 49 |
|
44 | 50 | it('should update the output when -3 is entered', function() {
|
45 |
| - input('limit').enter(-3); |
46 |
| - expect(binding('numbers | limitTo:limit')).toEqual('[7,8,9]'); |
| 51 | + input('numLimit').enter(-3); |
| 52 | + input('letterLimit').enter(-3); |
| 53 | + expect(binding('numbers | limitTo:numLimit')).toEqual('[7,8,9]'); |
| 54 | + expect(binding('letters | limitTo:letterLimit')).toEqual('ghi'); |
47 | 55 | });
|
48 | 56 |
|
49 | 57 | it('should not exceed the maximum size of input array', function() {
|
50 |
| - input('limit').enter(100); |
51 |
| - expect(binding('numbers | limitTo:limit')).toEqual('[1,2,3,4,5,6,7,8,9]'); |
| 58 | + input('numLimit').enter(100); |
| 59 | + input('letterLimit').enter(100); |
| 60 | + expect(binding('numbers | limitTo:numLimit')).toEqual('[1,2,3,4,5,6,7,8,9]'); |
| 61 | + expect(binding('letters | limitTo:letterLimit')).toEqual('abcdefghi'); |
52 | 62 | });
|
53 | 63 | </doc:scenario>
|
54 | 64 | </doc:example>
|
55 | 65 | */
|
56 | 66 | function limitToFilter(){
|
57 |
| - return function(array, limit) { |
58 |
| - if (!(array instanceof Array)) return array; |
| 67 | + return function(input, limit) { |
| 68 | + if (!isArray(input) && !isString(input)) return input; |
| 69 | + |
59 | 70 | limit = int(limit);
|
| 71 | + |
| 72 | + if (isString(input)) { |
| 73 | + //NaN check on limit |
| 74 | + if (limit) { |
| 75 | + return limit >= 0 ? input.slice(0, limit) : input.slice(limit, input.length); |
| 76 | + } else { |
| 77 | + return ""; |
| 78 | + } |
| 79 | + } |
| 80 | + |
60 | 81 | var out = [],
|
61 | 82 | i, n;
|
62 | 83 |
|
63 |
| - // check that array is iterable |
64 |
| - if (!array || !(array instanceof Array)) |
65 |
| - return out; |
66 |
| - |
67 | 84 | // if abs(limit) exceeds maximum length, trim it
|
68 |
| - if (limit > array.length) |
69 |
| - limit = array.length; |
70 |
| - else if (limit < -array.length) |
71 |
| - limit = -array.length; |
| 85 | + if (limit > input.length) |
| 86 | + limit = input.length; |
| 87 | + else if (limit < -input.length) |
| 88 | + limit = -input.length; |
72 | 89 |
|
73 | 90 | if (limit > 0) {
|
74 | 91 | i = 0;
|
75 | 92 | n = limit;
|
76 | 93 | } else {
|
77 |
| - i = array.length + limit; |
78 |
| - n = array.length; |
| 94 | + i = input.length + limit; |
| 95 | + n = input.length; |
79 | 96 | }
|
80 | 97 |
|
81 | 98 | for (; i<n; i++) {
|
82 |
| - out.push(array[i]); |
| 99 | + out.push(input[i]); |
83 | 100 | }
|
84 | 101 |
|
85 | 102 | return out;
|
|
0 commit comments