Sorter.html
6.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>The source code</title>
<link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
<script type="text/javascript" src="../resources/prettify/prettify.js"></script>
<style type="text/css">
.highlight { display: block; background-color: #ddd; }
</style>
<script type="text/javascript">
function highlight() {
document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
}
</script>
</head>
<body onload="prettyPrint(); highlight();">
<pre class="prettyprint lang-js"><span id='Ext-util-Sorter'>/**
</span> * Represents a single sorter that can be applied to a Store. The sorter is used
* to compare two values against each other for the purpose of ordering them. Ordering
* is achieved by specifying either:
*
* - {@link #property A sorting property}
* - {@link #sorterFn A sorting function}
*
* As a contrived example, we can specify a custom sorter that sorts by rank:
*
* Ext.define('Person', {
* extend: 'Ext.data.Model',
* fields: ['name', 'rank']
* });
*
* Ext.create('Ext.data.Store', {
* model: 'Person',
* proxy: 'memory',
* sorters: [{
* sorterFn: function(o1, o2){
* var getRank = function(o){
* var name = o.get('rank');
* if (name === 'first') {
* return 1;
* } else if (name === 'second') {
* return 2;
* } else {
* return 3;
* }
* },
* rank1 = getRank(o1),
* rank2 = getRank(o2);
*
* if (rank1 === rank2) {
* return 0;
* }
*
* return rank1 < rank2 ? -1 : 1;
* }
* }],
* data: [{
* name: 'Person1',
* rank: 'second'
* }, {
* name: 'Person2',
* rank: 'third'
* }, {
* name: 'Person3',
* rank: 'first'
* }]
* });
*/
Ext.define('Ext.util.Sorter', {
<span id='Ext-util-Sorter-cfg-property'> /**
</span> * @cfg {String} property
* The property to sort by. Required unless {@link #sorterFn} is provided. The property is extracted from the object
* directly and compared for sorting using the built in comparison operators.
*/
<span id='Ext-util-Sorter-cfg-sorterFn'> /**
</span> * @cfg {Function} sorterFn
* A specific sorter function to execute. Can be passed instead of {@link #property}. This sorter function allows
* for any kind of custom/complex comparisons. The sorterFn receives two arguments, the objects being compared. The
* function should return:
*
* - -1 if o1 is "less than" o2
* - 0 if o1 is "equal" to o2
* - 1 if o1 is "greater than" o2
*/
<span id='Ext-util-Sorter-cfg-root'> /**
</span> * @cfg {String} root
* Optional root property. This is mostly useful when sorting a Store, in which case we set the root to 'data' to
* make the filter pull the {@link #property} out of the data object of each item
*/
<span id='Ext-util-Sorter-cfg-transform'> /**
</span> * @cfg {Function} transform
* A function that will be run on each value before it is compared in the sorter. The function will receive a single
* argument, the value.
*/
<span id='Ext-util-Sorter-cfg-direction'> /**
</span> * @cfg {String} direction
* The direction to sort by.
*/
direction: "ASC",
constructor: function(config) {
var me = this;
Ext.apply(me, config);
//<debug>
if (me.property === undefined && me.sorterFn === undefined) {
Ext.Error.raise("A Sorter requires either a property or a sorter function");
}
//</debug>
me.updateSortFunction();
},
<span id='Ext-util-Sorter-method-createSortFunction'> /**
</span> * @private
* Creates and returns a function which sorts an array by the given property and direction
* @return {Function} A function which sorts by the property/direction combination provided
*/
createSortFunction: function(sorterFn) {
var me = this,
property = me.property,
direction = me.direction || "ASC",
modifier = direction.toUpperCase() == "DESC" ? -1 : 1;
//create a comparison function. Takes 2 objects, returns 1 if object 1 is greater,
//-1 if object 2 is greater or 0 if they are equal
return function(o1, o2) {
return modifier * sorterFn.call(me, o1, o2);
};
},
<span id='Ext-util-Sorter-method-defaultSorterFn'> /**
</span> * @private
* Basic default sorter function that just compares the defined property of each object
*/
defaultSorterFn: function(o1, o2) {
var me = this,
transform = me.transform,
v1 = me.getRoot(o1)[me.property],
v2 = me.getRoot(o2)[me.property];
if (transform) {
v1 = transform(v1);
v2 = transform(v2);
}
return v1 > v2 ? 1 : (v1 < v2 ? -1 : 0);
},
<span id='Ext-util-Sorter-method-getRoot'> /**
</span> * @private
* Returns the root property of the given item, based on the configured {@link #root} property
* @param {Object} item The item
* @return {Object} The root property of the object
*/
getRoot: function(item) {
return this.root === undefined ? item : item[this.root];
},
<span id='Ext-util-Sorter-method-setDirection'> /**
</span> * Set the sorting direction for this sorter.
* @param {String} direction The direction to sort in. Should be either 'ASC' or 'DESC'.
*/
setDirection: function(direction) {
var me = this;
me.direction = direction ? direction.toUpperCase() : direction;
me.updateSortFunction();
},
<span id='Ext-util-Sorter-method-toggle'> /**
</span> * Toggles the sorting direction for this sorter.
*/
toggle: function() {
var me = this;
me.direction = Ext.String.toggle(me.direction, "ASC", "DESC");
me.updateSortFunction();
},
<span id='Ext-util-Sorter-method-updateSortFunction'> /**
</span> * Update the sort function for this sorter.
* @param {Function} [fn] A new sorter function for this sorter. If not specified it will use the default
* sorting function.
*/
updateSortFunction: function(fn) {
var me = this;
fn = fn || me.sorterFn || me.defaultSorterFn;
me.sort = me.createSortFunction(fn);
}
});</pre>
</body>
</html>