You can use Alloy for this, but you have to use create the sections and index in your controller.
views/index.xml
Define the list view and its templates in the XML. We're not doing data binding here because we need to define sections in the controller.
<Alloy>
<Window>
<ListView id="list" defaultItemTemplate="title">
<Templates>
<ItemTemplate name="title" height="50">
<Label bindId="title" class="title"/>
</ItemTemplate>
</Templates>
</ListView>
</Window>
</Alloy>
models/info.js
You'll need a model to define your storage structure. You could leave off the id column and idAttribute -- I just grabbed some existing code that had those and didn't bother testing without them. I'm extending the collection with a method that will sort the collection automatically on fetch().
exports.definition = {
config: {
columns: {
id: 'INTEGER PRIMARY KEY AUTOINCREMENT',
title: 'TEXT'
},
adapter: {
type: 'sql',
collection_name: 'info',
idAttribute: 'id'
}
},
extendCollection: function(Collection) {
_.extend(Collection.prototype, {
// Implement the comparator method,
// which is used to sort the collection
comparator : function(name) {
return name.get('title');
}
}); // end extend
return Collection;
}
};
controllers/index.js
Here's how I created the functionality. I loop through an array of letters, which will be my index, creating the section for each letter if there are names that begin with that letter
var info = Alloy.createCollection('info');
info.fetch();
var sections = [];
var sectionIndexArray = [];
var letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' ];
_.each(letters, function(letter) {
var data = info.filter(function(name) {
var n = name.get('title');
if(n.charAt(0).toLowerCase() === letter) {
return name;
}
});
if(data && data.length >0 ) {
var section = Ti.UI.createListSection();
var items = _.map(data, function(item) {
return { title: {text: item.get('title')}};
});
section.setItems(items);
sections.push(section);
sectionIndexArray.push({index: (sections.length -1 ), title: letter.toUpperCase() });
}
});
$.list.sections = sections;
$.list.sectionIndexTitles = sectionIndexArray;
$.index.open();
Finally, you need to populate your collection. For my testing, I added the following to my alloy.js file. It could have been in the index.js.
var firstLadies = [
"Adams, Abigail",
"Adams, Louisa Catherine",
"Arthur, Ellen Herndon",
"Bush, Barbara",
"Bush, Laura",
"Carter, Rosalynn",
"Cleveland, Frances Folsom",
"Clinton, Hillary Rodham",
"Coolidge, Grace Goodhue",
"Eisenhower, Mamie Doud",
"Fillmore, Abigail Powers",
"Ford, Betty",
"Garfield, Lucretia Rudolph",
"Grant, Julia Dent",
"Harding, Florence Kling",
"Harrison, Anna Tuthill Symmes",
"Harrison, Caroline Lavinia Scott",
"Harrison, Mary Lord",
"Hayes, Lucy Webb",
"Hoover, Lou Henry",
"Jackson, Rachel",
"Johnson, Eliza McCardle",
"Johnson, Lady Bird",
"Kennedy, Jacqueline",
"Lincoln, Mary Todd",
"Madison, Dolley",
"McKinley, Ida Saxton",
"Nixon, Pat",
"Obama, Michelle",
"Pierce, Jane Means",
"Polk, Sarah Childress",
"Reagan, Nancy",
"Roosevelt, Edith Kermit Carow",
"Roosevelt, Eleanor",
"Taft, Helen Herron",
"Truman, Bess Wallace",
"Van Buren, Hannah Hoes",
"Washington, Martha",
"Wilson, Edith Bolling Galt",
"Wilson, Ellen Axson"
];
if (!Ti.App.Properties.hasProperty('seeded')) {
for(var i=0,j=firstLadies.length;i<j;i++) {
Alloy.createModel('info', { title: firstLadies[i]}).save();
}
Ti.App.Properties.setString('seeded', 'yes');
}