Alphabetical scroll bar
Does anyone know how to create an alphabetical scroll bar on the right side of a TableView on the iphone (and possibly android) like what is on the iphone's contacts screen?
6 Answers
-
Hi Joseph
Apologies, I have had to edit this post because I had missed a couple of important lines….
to configure what you want, you need to insert an "index" object in your tableview row for the start of each alphabetical section.
I'm going to show a couple of more advanced techniques here and like any such solution, its full of different ways in which you could do things. This is just my way.
So if I have a database that contains the list I want displayed, then I would do as follows.
First write the database function to retrieve the list. I separate the database functions from the rest. To do this I would put this in a file dbfunctions.js
var db = (function() { var api = {}; var conn = Titanium.Database.open('mydb'); api.all_item_names = function() { if (debug){ Titanium.API.info('api.all_item_names'); } var results = []; var resultSet = conn.execute('select * from items' ); while ( resultSet.isValidRow()) { results.push({ item_name: resultSet.fieldByName('item_name') }); resultSet.next(); } resultSet.close(); return results; }; return api; }());
Next the code to display the list in the tableview. First we include the database function, then we set a few variables that we are going to use to store the data and then we retrieve the list using our database function above. I would put the rest of the code in a new file e.g. listitems.js
Titanium.include('dbfunctions.js'); var tvrow; var curheader = 'A'; //the first letter of the list. var list = []; var index = []; var isAndroid = (Titanium.Platform.name == 'android'); list = ( db.all_item_names() );
We then need to cycle through the retrieved list from start to finish.
Our little bit of 'magic' to add the list on the right hand side is create an index based upon the curheader variable. If the curheader value is not the same as the first character of the list item, then we
1) set the curheader variable to the new value;
2) add it to our createTableViewRow for this item in the list with "header: curheader"; and
3) we push the new curheader onto our index array. The index array simply contains that curheader value and the position in our list where that value occurs.Otherwise we just create a new TableViewRow without the header and do not change the index array.
for ( var ipos=0; ipos<ilist.length;ipos++){ if( list[ipos].item_name[0] != curheader){ curheader = list[ipos].item_name[0]; tvrow = Titanium.UI.createTableViewRow({ height: 20, header: curheader }); index.push({ title: curheader, index: ipos }); } else { tvrow = Titanium.UI.createTableViewRow({height:20 }); }
Next we add the list item to the new TableViewRow
var title= Titanium.UI.createLabel({ left: 5, top: 2, height: '15', color: '#000', font: { fontSize: 11, fontWeight: 'normal', fontFamily: (isAndroid?'sans-serif':'Helvetica Neue') }, text: list[ipos].item_name }); tvrow.add(title); data.push(tvrow); }
Then we populate the Tableview with the data array we have created and add to it the index which we created.
var tableView = Titanium.UI.createTableView({ data: data, index: index separatorStyle: Titanium.UI.iPhone.TableViewStyle.GROUPED, top: 1, width: 300 }); win.add(tableView);
You will see that I did not set the first index to "A". The reason for this is that if the first character is a number, it will come up at the top of the list.
Thats it, corrections included. Hope this helps you.
Greg -
If anyone is interested, I came up with a nice custom Alphabetical scrollbar that allows you to style your Table however you want and not be stuck using Table Groups.
It works very similar to the iPhone Contacts listing, where it updates the table position on touchMove.
This has been tested on Titanium 1.7.5 and iPhone 5.0.
var model = [ { Title:'Alphabits' }, { Title:'Biscuits' }, { Title:'Cake' }, { Title:'Candy' }, { Title:'Green Beans' }, { Title:'Oranges' }, { Title:'Pasta' }, { Title:'Tangerines' }, { Title:'Trix' }, { Title:'Zucchini Bread' } ]; var table = Ti.UI.createTableView({ backgroundColor: '#fff', width:320, rowHeight:100 }); win.add(table); var alphaTable = Ti.UI.createTableView({ separatorStyle:Ti.UI.iPhone.TableViewSeparatorStyle.NONE, opacity:0.65, scrollable:false, right:5, top:5, width:28, height:355, borderRadius:13, backgroundColor:"#000" }); // alpha table must be on top of other table win.add(alphaTable); var curheader = '0'; var index = []; var rows = []; var alphaRowCount = 0; // loop through model to add rows to table for (var i = 0, l = model.length; i < l; i++) { // first determine how many rows there will be // use substring to get only first letter if( model[i].Title.substring(0,1) != curheader) { curheader = model[i].Title.substring(0,1); alphaRowCount++; } var row = Ti.UI.createTableViewRow({ title:model[i].Title }); rows.push( row ); } // reset curheader var curheader = '0'; // determine Row height by dividing by Alpha Table height var rowHeight = 355/alphaRowCount; // now loop through model again to actually add the alpha rows for (var i = 0, l = model.length; i < l; i++) { if( model[i].Title.substring(0,1) != curheader) { curheader = model[i].Title.substring(0,1); var alphaRow = Ti.UI.createTableViewRow({ color:'#fff', width:28, backgroundColor:"transparent", backgroundSelectedColor:"transparent", selectedBackgroundColor: "transparent" }); alphaRow.height = rowHeight; // define IndexRow for main Table alphaRow.indexRow = i; var alphaLabel = Ti.UI.createLabel({ top:0, width:28, left: 0, font: { fontSize: 10, fontFamily: 'Helvetica Neue' }, color: '#fff', textAlign: 'center' }); alphaLabel.text = curheader; alphaLabel.height = rowHeight; alphaRow.add( alphaLabel ); index.push( alphaRow ); } } table.setData( rows ); alphaTable.setData( index ); var previousIndex = 0; alphaTable.addEventListener('touchmove', function(e) { // subtract from global point to find position var newPointY = e.globalPoint.y - 70; // determine the index var newIndex = Math.ceil( newPointY/rowHeight) - 1; // scroll to index on main Table, and make sure its on the TOP position // to make sure it doesnt jiggle, check to make sure newIndex is not the same as previousIndex if( newIndex != previousIndex ) { table.scrollToIndex(newIndex,{animated:true,position:Ti.UI.iPhone.TableViewScrollPosition.TOP}); previousIndex = newIndex; } });
-
I've searched in Kitchen Sink but didn't find an alphabetical scroll bar.
I'm using KS 1.4 built with Titanium SDK 1.3 (won't work with SDK.14).
Where could I find this? -
I'm interested in this too. As far as i know there is nothing in KS for this.
-
Alright, I got a custom alphabetical listing working using Titanium SDK 1.8.0.1 R3.
The major difference with this code and the one I posted earlier is that I'm using convertPointToView instead of globalPoint which was depreciated.
The only bummer about this custom alphabetical listing is that nots nearly as fast as the default one. If you slide your finger up and down on the device, its a bit sluggish (aalthough its lightning fast on the simulator).
Heres the code:
-
Check out the KitchenSink, there should be an example in there…