PDA

View Full Version : ASC Sorting Compromised by Capital Letters



markwyner
14 Jun 2011, 3:11 PM
Sencha Touch version tested:

1.1.0


Platform tested against:

iOS 4
Android 2.2


Description:

I have discovered that when I add records to localStorage and then call them into a select menu their sorting is impacted by the case of the first letter in a word. Here is a screen shot that shows a select menu with two entries for the same word (tofu), one with a capital T and the other with a lower case T:


http://i.imgur.com/x9F5g.png

Test Case:


var all_items = [{text: 'Choose an Item',value: null},];
StoreItems.each(function(rec) {
all_items.push({
value: rec.get('itemName'),
text: rec.get('itemName')
});
});
var list_item_select = new Ext.form.Select({
name: 'ListItems',
id: 'List_Items',
cls: 'Rounded',
options: all_items
});
Ext.regModel('Items', {
fields: ['id', 'itemName', 'itemCat', 'itemImg'],
proxy: {
type: 'localstorage',
id: 'item_list'
}
});
var StoreItems = new Ext.data.Store({
model: 'Items',
autoLoad: true,
autoSave: true
});

Here is another example of how I'm seeing this issue:

http://i.imgur.com/xu2is.png

This list is set to:


StoreItems.sort('itemName','ASC');

Which means the order should be "Zebra" then "ZZebra." But this bug shows "ZZebra" first. This is because the second "Z" in "ZZebra" is given sequential precedence over the lower-case "e" in "Zebra" solely because it is capitalized.

Steps to reproduce the problem:

Create a store with a simple list of records, some beginning with capital letters and some beginning with lowercase letters.
Display the store in a select menu or list panel sorting by name in alphabetical order (ASC).


The result that was expected:

All items listed alphabetically.


The result that occurs instead:

Items listed alphabetically with sorting preference given to capital letters. Lower case letters which precede capital letters in the alphabet are listed after letters which follow them alphabetically if they are capitalized.


Debugging already done:

none


Possible fix:

not provided

bwg
14 Jun 2011, 9:46 PM
This is not a bug.

Open up a Javascript console:



test = ['ZZebra', 'zzebra', 'Zebra', 'Yak', 'Xerus'];
test.sort(); // returns ["Xerus", "Yak", "ZZebra", "Zebra", "zzebra"]
If you want a more intelligent sorting method, you should look at the Ext.Store sorters property and writing your own custom sorter using Ext.util.Sorter and its sorterFn property.

markwyner
15 Jun 2011, 6:35 AM
Hmm…that's interesting.

Okay, I now have a nice filter which sorts alphabetically for humans. Can you help me understand how to apply it to the sorterFn? I read the documentation but don't completely understand. I'd love to learn how so I can share it in the "examples" section of the forums.

Thanks in advance.

bwg
15 Jun 2011, 10:46 AM
Based on the documentation, you should do something similar to



var sorter = new Ext.util.Sorter({
property : 'myField',
sorterFn: function(o1, o2) { // compare o1 and o2 }
});

var store = new Ext.data.Store({
model: 'myModel',
sorters: [sorter]
});

store.sort();
If you look at the comments in the source code, your comparison function should be like:


createSortFunction: function(sorterFn) {
var me = this,
property = me.property,
direction = me.direction,
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);
};
},
TIP: Read the source code if you have it. Often better than the documentation which can and often does lag.

I have not tested the above code.