Skip to content

Commit a5d96c4

Browse files
author
Jeremy Wilken
committed
feat(sliceFilter): create slice filter
This creates a new filter that passes a string or array to native slice() method. This could be useful for pagination, because the limitTo filter only allows a limit, not a start and ending position. Creating a new filter is more intuitive and reflective of native Javascript rather than extending limitTo. angular#5355
1 parent 0c9abc3 commit a5d96c4

File tree

4 files changed

+180
-0
lines changed

4 files changed

+180
-0
lines changed

angularFiles.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ angularFiles = {
3939
'src/ng/filter/filters.js',
4040
'src/ng/filter/limitTo.js',
4141
'src/ng/filter/orderBy.js',
42+
'src/ng/filter/slice.js',
4243

4344
'src/ng/directive/directives.js',
4445
'src/ng/directive/a.js',

src/ng/filter.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ function $FilterProvider($provide) {
116116
lowercaseFilter: false,
117117
numberFilter: false,
118118
orderByFilter: false,
119+
sliceFilter: false,
119120
uppercaseFilter: false,
120121
*/
121122

@@ -127,5 +128,6 @@ function $FilterProvider($provide) {
127128
register('lowercase', lowercaseFilter);
128129
register('number', numberFilter);
129130
register('orderBy', orderByFilter);
131+
register('slice', sliceFilter);
130132
register('uppercase', uppercaseFilter);
131133
}

src/ng/filter/slice.js

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
'use strict';
2+
3+
/**
4+
* @ngdoc filter
5+
* @name slice
6+
* @function
7+
*
8+
* @description
9+
* Creates a new array or string containing only the elements specified. The elements are extracted
10+
* from an index value up to either the end of the array or string, or to the optional end index specified.
11+
*
12+
* @param {Array|string} input Source array or string to be limited.
13+
* @param {string|number} begin The zero-based index to begin extracting from the array or string.
14+
* If the `begin` number is positive, slice counts to `begin` starting with 0. If the `begin`
15+
* number is negative, `slice` extracts that number of items from the end of the source array/string.
16+
* @param {string|number} end The zero-based index to end extracting from the array or string.
17+
* @returns {Array|string} A new sub-array or substring starting at the index `begin` or less if input array
18+
* had less than `limit` elements.
19+
*
20+
* @example
21+
<example>
22+
<file name="index.html">
23+
<script>
24+
function Ctrl($scope) {
25+
$scope.numbers = [1,2,3,4,5,6,7,8,9];
26+
$scope.letters = "abcdefghi";
27+
$scope.begin = 3;
28+
$scope.end = 6;
29+
}
30+
</script>
31+
<div ng-controller="Ctrl">
32+
Slice input from index <input type="integer" ng-model="begin"> to <input type="integer" ng-model="end">
33+
<p>Output numbers: {{ numbers | slice:begin:end }}</p>
34+
<p>Output letters: {{ letters | slice:begin:end }}</p>
35+
</div>
36+
</file>
37+
<file name="protractor.js" type="protractor">
38+
var beginInput = element(by.model('begin'));
39+
var endInput = element(by.model('end'));
40+
var slicedNumbers = element(by.binding('numbers | slice:begin:end'));
41+
var slicedLetters = element(by.binding('letters | slice:begin:end'));
42+
43+
it('should limit the number array to first three items', function() {
44+
expect(beginInput.getAttribute('value')).toBe('3');
45+
expect(endInput.getAttribute('value')).toBe('6');
46+
expect(slicedNumbers.getText()).toEqual('Output numbers: [4,5,6]');
47+
expect(slicedLetters.getText()).toEqual('Output letters: def');
48+
});
49+
50+
it('should update the output when -3 is entered', function() {
51+
beginInput.clear();
52+
beginInput.sendKeys('-3');
53+
endInput.clear();
54+
endInput.sendKeys('');
55+
expect(slicedNumbers.getText()).toEqual('Output numbers: [7,8,9]');
56+
expect(slicedLetters.getText()).toEqual('Output letters: ghi');
57+
});
58+
59+
it('should not exceed the maximum size of input array', function() {
60+
beginInput.clear();
61+
beginInput.sendKeys('0');
62+
endInput.clear();
63+
endInput.sendKeys('100');
64+
expect(slicedNumbers.getText()).toEqual('Output numbers: [1,2,3,4,5,6,7,8,9]');
65+
expect(slicedLetters.getText()).toEqual('Output letters: abcdefghi');
66+
});
67+
</file>
68+
</example>
69+
*/
70+
function sliceFilter(){
71+
return function(input, begin, end) {
72+
if (!isArray(input) && !isString(input)) return input;
73+
74+
begin = int(begin);
75+
76+
// Slice needs end to be undefined if blank or invalid, or it can give it a value of 0
77+
if ((isString(end) && end) || isNumber(end)) {
78+
end = int(end);
79+
} else {
80+
end = undefined;
81+
}
82+
83+
return input.slice(begin, end);
84+
};
85+
}

test/ng/filter/sliceSpec.js

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
'use strict';
2+
3+
describe('Filter: slice', function() {
4+
var items;
5+
var str
6+
var slice;
7+
8+
beforeEach(inject(function($filter) {
9+
items = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'];
10+
str = "stuvwxyz";
11+
slice = $filter('slice');
12+
}));
13+
14+
it('should return all items after index X when X is positive', function() {
15+
expect(slice(items, 4)).toEqual(['e', 'f', 'g', 'h']);
16+
expect(slice(items, '4')).toEqual(['e', 'f', 'g', 'h']);
17+
18+
expect(slice(str, 4)).toEqual("wxyz");
19+
expect(slice(str, '4')).toEqual("wxyz");
20+
});
21+
22+
it('should return the last X items when X is negative', function() {
23+
expect(slice(items, -3)).toEqual(['f', 'g', 'h']);
24+
expect(slice(items, '-3')).toEqual(['f', 'g', 'h']);
25+
26+
expect(slice(str, -3)).toEqual("xyz");
27+
expect(slice(str, '-3')).toEqual("xyz");
28+
});
29+
30+
it('should return an extracted array between index X and X', function () {
31+
expect(slice(items, 3, 6)).toEqual(['d', 'e', 'f']);
32+
expect(slice(items, '3', '6')).toEqual(['d', 'e', 'f']);
33+
34+
expect(slice(str, 3, 6)).toEqual("vwx");
35+
expect(slice(str, '3', '6')).toEqual("vwx");
36+
});
37+
38+
it('should return a string or array the same as slice()', function () {
39+
expect(slice(items, -2, -4)).toEqual([]);
40+
expect(slice(items, -4, -2)).toEqual(['e', 'f']);
41+
expect(slice(items, 2, -2)).toEqual(['c', 'd', 'e', 'f']);
42+
expect(slice(items, 2, -8)).toEqual([]);
43+
44+
expect(slice(str, -2, -4)).toEqual("");
45+
expect(slice(str, -4, -2)).toEqual("wx");
46+
expect(slice(str, 2, -2)).toEqual("uvwx");
47+
expect(slice(str, -2, -8)).toEqual("");
48+
});
49+
50+
it('should return the source array when X cannot be parsed', function() {
51+
expect(slice(items, 'bogus')).toEqual(items);
52+
expect(slice(items, 'null')).toEqual(items);
53+
expect(slice(items, 'undefined')).toEqual(items);
54+
expect(slice(items, null)).toEqual(items);
55+
expect(slice(items, undefined)).toEqual(items);
56+
});
57+
58+
it('should return the source string when X cannot be parsed', function() {
59+
expect(slice(str, 'bogus')).toEqual(str);
60+
expect(slice(str, 'null')).toEqual(str);
61+
expect(slice(str, 'undefined')).toEqual(str);
62+
expect(slice(str, null)).toEqual(str);
63+
expect(slice(str, undefined)).toEqual(str);
64+
});
65+
66+
it('should return input if not String or Array', function() {
67+
expect(slice(1,1)).toEqual(1);
68+
expect(slice(null, 1)).toEqual(null);
69+
expect(slice(undefined, 1)).toEqual(undefined);
70+
expect(slice({}, 1)).toEqual({});
71+
});
72+
73+
it('should return an empty array or string if X is positive and exceeds input length', function () {
74+
expect(slice(items, 9)).toEqual([]);
75+
expect(slice(items, '9')).toEqual([]);
76+
77+
expect(slice(str, 9)).toEqual("");
78+
expect(slice(str, '9')).toEqual("");
79+
80+
expect(slice(items, 9)).not.toBe(items);
81+
expect(slice(str, 9)).not.toBe(str);
82+
});
83+
84+
it('should return the source array or string if X is negative and exceeds input length', function() {
85+
expect(slice(items, -9)).toEqual(items);
86+
expect(slice(items, '-9')).toEqual(items);
87+
88+
expect(slice(str, -9)).toEqual(str);
89+
expect(slice(str, '-9')).toEqual(str);
90+
});
91+
92+
});

0 commit comments

Comments
 (0)