More splitting, and more test specs.
Showing
6 changed files
with
349 additions
and
0 deletions
src/scripts/solr/model/Facet.js
0 → 100644
1 | define(function(require) { | ||
2 | 'use strict'; | ||
3 | var _ = require('underscore'); | ||
4 | var Backbone = require('backbone'); | ||
5 | var Sort = require('./Sort'); | ||
6 | |||
7 | function getItemKeyAccessor(item) { | ||
8 | return item.get('key'); | ||
9 | } | ||
10 | |||
11 | function wrapComparatorForAllBeforeAfter(comparator, doBefore, doAfter) { | ||
12 | if (!doBefore && !doAfter) { | ||
13 | return comparator; | ||
14 | } | ||
15 | return function beforeAfterComparator(a, b) { | ||
16 | if (doBefore) { | ||
17 | if (a === 'before') { | ||
18 | return -1; | ||
19 | } else if (b === 'before') { | ||
20 | return 1; | ||
21 | } | ||
22 | } | ||
23 | if (doAfter) { | ||
24 | if (a === 'after') { | ||
25 | return 1; | ||
26 | } else if (b === 'after') { | ||
27 | return -1; | ||
28 | } | ||
29 | } | ||
30 | return comparator.call(this, a, b); | ||
31 | }; | ||
32 | } | ||
33 | var Facet = Backbone.Model.extend({ | ||
34 | defaults: function defaults() { | ||
35 | return { | ||
36 | formName: null, | ||
37 | query: null, | ||
38 | suggestions: [], | ||
39 | }; | ||
40 | }, | ||
41 | initialize: function(data, options) { | ||
42 | this.set('all', true); | ||
43 | this.on('change:queryMax change:queryMin', function() { | ||
44 | this.set('hasQuery', this.get('queryMin') !== undefined && this.get('queryMax') !== undefined); | ||
45 | }, this); | ||
46 | (function(self) { | ||
47 | var skipCallback; | ||
48 | self.on('item-change change:queryMax change:queryMin', function() { | ||
49 | switch (skipCallback) { | ||
50 | case 'change:checkedKeys': | ||
51 | case 'change:all': | ||
52 | return; | ||
53 | } | ||
54 | var checkedKeys = []; | ||
55 | this.get('items').each(function(facetItem) { | ||
56 | if (facetItem.get('checked')) { | ||
57 | checkedKeys.push(facetItem.get('key')); | ||
58 | } | ||
59 | }); | ||
60 | var checkedCount = checkedKeys.length; | ||
61 | if (this.get('queryMin') !== undefined && this.get('queryMax') !== undefined) { | ||
62 | checkedCount++; | ||
63 | } | ||
64 | skipCallback = 'item-change'; | ||
65 | try { | ||
66 | this.set({ | ||
67 | all: checkedCount === 0, | ||
68 | checkedKeys: checkedKeys, | ||
69 | |||
70 | }); | ||
71 | } finally { | ||
72 | skipCallback = null; | ||
73 | } | ||
74 | }, self); | ||
75 | self.on('change:all', function() { | ||
76 | switch (skipCallback) { | ||
77 | case 'change:checkedKeys': | ||
78 | case 'item-change': | ||
79 | return; | ||
80 | } | ||
81 | skipCallback = 'change:all'; | ||
82 | try { | ||
83 | this.get('items').invoke('set', {checked: false}); | ||
84 | this.set({ | ||
85 | checkedKeys: [], | ||
86 | queryMax: undefined, | ||
87 | queryMin: undefined, | ||
88 | }); | ||
89 | } finally { | ||
90 | skipCallback = null; | ||
91 | } | ||
92 | }, self); | ||
93 | self.on('change:checkedKeys', function() { | ||
94 | switch (skipCallback) { | ||
95 | case 'item-change': | ||
96 | case 'change:all': | ||
97 | return; | ||
98 | } | ||
99 | var checkedKeys = {}; | ||
100 | _.each(this.get('checkedKeys'), function(value, i) { | ||
101 | checkedKeys[value] = true; | ||
102 | }); | ||
103 | skipCallback = 'change:checkedKeys'; | ||
104 | var checkedCount = 0; | ||
105 | if (this.get('queryMin') !== undefined && this.get('queryMax') !== undefined) { | ||
106 | checkedCount++; | ||
107 | } | ||
108 | try { | ||
109 | this.get('items').each(function(facetItem) { | ||
110 | var newChecked = checkedKeys[facetItem.get('key')]; | ||
111 | var currentChecked = facetItem.get('checked'); | ||
112 | if (newChecked !== currentChecked) { | ||
113 | facetItem.set('checked', newChecked); | ||
114 | } | ||
115 | if (facetItem.get('checked')) { | ||
116 | checkedCount++; | ||
117 | } | ||
118 | }); | ||
119 | this.set({ | ||
120 | all: checkedCount === 0, | ||
121 | }); | ||
122 | } finally { | ||
123 | skipCallback = null; | ||
124 | } | ||
125 | }, self); | ||
126 | })(this); | ||
127 | var sortKeyExtractor = options.sortKeyExtractor; | ||
128 | if (!sortKeyExtractor) { | ||
129 | sortKeyExtractor = getItemKeyAccessor; | ||
130 | } | ||
131 | var comparator = options.comparator; | ||
132 | if (!comparator) { | ||
133 | comparator = Sort.standard; | ||
134 | } else if (typeof comparator === 'string') { | ||
135 | comparator = Sort[comparator]; | ||
136 | } | ||
137 | switch (options.facetType) { | ||
138 | case 'year': | ||
139 | case 'range': | ||
140 | case 'interval': | ||
141 | comparator = wrapComparatorForAllBeforeAfter(comparator, ['all', 'before'].indexOf(options.other) !== -1, ['all', 'after'].indexOf(options.other) !== -1); | ||
142 | break; | ||
143 | } | ||
144 | var formatter = options.formatter; | ||
145 | if (!formatter) { | ||
146 | var labelMap = options.labelMap; | ||
147 | if (labelMap) { | ||
148 | formatter = function(item) { | ||
149 | var value = item.get('key'); | ||
150 | var label = options.labelMap[value.toUpperCase()]; | ||
151 | return label ? label : value; | ||
152 | }; | ||
153 | } else { | ||
154 | formatter = getItemKeyAccessor; | ||
155 | } | ||
156 | } | ||
157 | this.formatter = formatter; | ||
158 | comparator = (function(comparator) { | ||
159 | return function facetItemValue(a, b) { | ||
160 | var keyA = sortKeyExtractor(a); | ||
161 | var keyB = sortKeyExtractor(b); | ||
162 | switch (this.get('orderByDirection')) { | ||
163 | case 'desc': | ||
164 | var tmp = keyA; | ||
165 | keyA = keyB; | ||
166 | keyB = tmp; | ||
167 | break; | ||
168 | } | ||
169 | return comparator.call(this, sortKeyExtractor(a), sortKeyExtractor(b)); | ||
170 | }; | ||
171 | })(comparator); | ||
172 | this.set('items', new ItemCollection([], {comparator: comparator})); | ||
173 | this.facetType = options.facetType; | ||
174 | this.facetStats = options.facetStats; | ||
175 | this.other = options.other; | ||
176 | this.facetField = options.facetField; | ||
177 | this.queryField = options.queryField; | ||
178 | this.queryValue = options.queryValue; | ||
179 | this.bins = options.bins; | ||
180 | switch (this.facetType) { | ||
181 | case 'year': | ||
182 | this.rangeStart = options.start; | ||
183 | this.rangeEnd = options.end; | ||
184 | this.rangeGap = '+' + (options.gap ? options.gap : 1) + 'YEAR'; | ||
185 | break; | ||
186 | case 'range': | ||
187 | this.rangeStart = options.start; | ||
188 | this.rangeEnd = options.end; | ||
189 | this.rangeGap = options.gap; | ||
190 | break; | ||
191 | case 'field': | ||
192 | case 'year-field': | ||
193 | case 'interval': | ||
194 | break; | ||
195 | default: | ||
196 | var e = new Error('Unsupported facet type: ' + this.facetType); | ||
197 | e.facet = this; | ||
198 | throw e; | ||
199 | } | ||
200 | return Facet.__super__.initialize.apply(this, arguments); | ||
201 | }, | ||
202 | /* | ||
203 | toJSON: function toJSON(options) { | ||
204 | if (!!options.facetSuggestions) { | ||
205 | return { | ||
206 | rows: 0, | ||
207 | facet: true, | ||
208 | wt: 'json', | ||
209 | q: '*:*', | ||
210 | 'facet.contains': this.get('query'), | ||
211 | 'facet.contains.ignoreCase': true, | ||
212 | 'facet.field': this.queryField, | ||
213 | 'facet.mincount': 1, | ||
214 | }; | ||
215 | } | ||
216 | }, | ||
217 | parse: function parse(data, options) { | ||
218 | if (!!options.facetSuggestions) { | ||
219 | var suggestions = []; | ||
220 | var key; | ||
221 | _.each(data.facet_counts.facet_fields[this.queryField], function(value, index) { | ||
222 | if (index % 2 === 0) { | ||
223 | key = value; | ||
224 | } else if (value > 0) { | ||
225 | suggestions.push({key: key, value: value}); | ||
226 | } | ||
227 | }); | ||
228 | return { | ||
229 | suggestions: suggestions, | ||
230 | }; | ||
231 | } | ||
232 | return null; | ||
233 | }, | ||
234 | */ | ||
235 | }); | ||
236 | var ItemCollection = Backbone.Collection.extend({ | ||
237 | remove: function() { | ||
238 | } | ||
239 | }); | ||
240 | var Item = Facet.Item = Backbone.Model.extend({ | ||
241 | idAttribute: 'key', | ||
242 | defaults: { | ||
243 | checked: false, | ||
244 | hidden: false, | ||
245 | }, | ||
246 | _initialize: function(data, options) { | ||
247 | this.on('add', function(model, parent, options) { | ||
248 | // added to a collection | ||
249 | this.on('change:checked', function() { | ||
250 | parent.trigger('item-change'); | ||
251 | }); | ||
252 | }, this); | ||
253 | return Item.__super__.initialize.apply(this, arguments); | ||
254 | } | ||
255 | }); | ||
256 | |||
257 | return Facet; | ||
258 | }); |
This diff is collapsed.
Click to expand it.
src/scripts/solr/model/Sort.js
0 → 100644
1 | define(function(require) { | ||
2 | 'use strict'; | ||
3 | |||
4 | var Sort = { | ||
5 | standard: function standardSort(a, b) { | ||
6 | if (a < b) { | ||
7 | return -1; | ||
8 | } else if (a > b) { | ||
9 | return 1; | ||
10 | } else { | ||
11 | return 0; | ||
12 | } | ||
13 | }, | ||
14 | date: function dateSort(a, b) { | ||
15 | return Sort.standard.call(this, a, b); | ||
16 | }, | ||
17 | number: function numberSort(a, b) { | ||
18 | return Sort.standard.call(this, parseInt(a), parseInt(b)); | ||
19 | }, | ||
20 | }; | ||
21 | |||
22 | return Sort; | ||
23 | }); |
test/specs/Facet.js
0 → 100644
test/specs/Facets.js
0 → 100644
test/specs/Sort.js
0 → 100644
1 | define(function(require) { | ||
2 | 'use strict'; | ||
3 | var _ = require('underscore'); | ||
4 | var Backbone = require('backbone'); | ||
5 | var Sort = require('solr/model/Sort'); | ||
6 | |||
7 | describe('Sort', function() { | ||
8 | it('loads', function() { | ||
9 | expect(Sort).toBeDefined(); | ||
10 | }); | ||
11 | it('standard(number)', function() { | ||
12 | var array = [5, 4, 2, 2, 3, 1, 5]; | ||
13 | array.sort(Sort.standard); | ||
14 | expect(array).toEqual([1, 2, 2, 3, 4, 5, 5]); | ||
15 | }); | ||
16 | it('standard(string)', function() { | ||
17 | var array = ['1', '500', '2', '400', '3', '300', '4', '200', '5', '100']; | ||
18 | array.sort(Sort.standard); | ||
19 | expect(array).toEqual(['1', '100', '2', '200', '3', '300', '4', '400', '5', '500']); | ||
20 | }); | ||
21 | it('date', function() { | ||
22 | var array = [ | ||
23 | '2016-02-05T13:25:06-0600', | ||
24 | '2015-02-05T13:25:06-0600', | ||
25 | '2014-02-05T13:25:06-0600', | ||
26 | '2013-02-05T13:25:06-0600', | ||
27 | '2012-02-05T13:25:06-0600', | ||
28 | '2011-02-05T13:25:06-0600', | ||
29 | ]; | ||
30 | array.sort(Sort.date); | ||
31 | expect(array).toEqual([ | ||
32 | '2011-02-05T13:25:06-0600', | ||
33 | '2012-02-05T13:25:06-0600', | ||
34 | '2013-02-05T13:25:06-0600', | ||
35 | '2014-02-05T13:25:06-0600', | ||
36 | '2015-02-05T13:25:06-0600', | ||
37 | '2016-02-05T13:25:06-0600', | ||
38 | ]); | ||
39 | }); | ||
40 | it('number', function() { | ||
41 | var array = ['1', '500', '2', '400', '3', '300', '4', '200', '5', '100']; | ||
42 | array.sort(Sort.number); | ||
43 | expect(array).toEqual(['1', '2', '3', '4', '5', '100', '200', '300', '400', '500']); | ||
44 | }); | ||
45 | }); | ||
46 | }); |
-
Please register or sign in to post a comment