Titanium Community Questions & Answer Archive

We felt that 6+ years of knowledge should not die so this is the Titanium Community Questions & Answer Archive

Automatically add alphabetical headers in tableview?

In the kitchensink the Tableview with Headers example lists names with headers for each letter of the alphabet. This is hard coded. Is there any example code for Titanium to automatically sort your table rows and add a header for each letter of the alphabet?

— asked December 7th 2010 by Stephen Flynn
  • headers
  • tableview
0 Comments

3 Answers

  • Hi, here is my solution.
    members is an array list from a db query, the response is an array ready to be push to a tableView

    var table = {
        create_rows: function(members){
            var mlen = members.length,
                    trows = [],
                    cheader = '';
    
            for( var i = 0; i < mlen; i++ ){
                var rdata = {
                        title: members[i].display_name,
                        hasChild: true,
                        className: 'member-row',
                        zdata: { member: members[i].id }
                    };
    
                if(rdata.title[0] !== cheader){
                    cheader = rdata.title[0];
                    rdata.header = rdata.title[0];
                }
    
                trows.push(rdata);
            }
    
            return trows;
        }
    };
    
    — answered December 7th 2010 by Hernan Fernandez
    permalink
    2 Comments
    • kinda looks similar… but you are using the whole title as the header which wont work with a list of names

      — commented December 7th 2010 by Aaron Saunders
    • Hi Aaron, just the first letter, rdata.header = rdata.title[0];

      — commented December 7th 2010 by Hernan Fernandez
  • this is how i do it… not to elegant but it works. the assumption is that I have a sorted list of user names. what i do is check to see if the initial of the last name has changed, then set the row header

    for ( var i = 0; i < sorted_items.length; i++) {
    
        var user = sorted_items[i];
    
        if (user) {
            // append first name and last name
            var user_string = user.getElementsByTagName("firstName")
                    .item(0).text
                    + " "
                    + user.getElementsByTagName("lastName").item(0).text;
    
            // add the name as the row title
            var row = Ti.UI.createTableViewRow({
                title: user_string,
                className : "@row"
            });
    
            // get the first initial for the header
            var fi = user.getElementsByTagName("lastName").item(0).text[0]
                    .toUpperCase();
    
            // if the first initial is not the same as the last,
            // then set the header appropriately
            if (lastHeader == "" || lastHeader != first_initial) {
                row.header = first_initial;
                lastHeader = first_initial;
            }
            dataArray[i] = row;
        }
    }
    
    — answered December 7th 2010 by Aaron Saunders
    permalink
    0 Comments
  • Hi Stephen,
    I know you asked this question a really long time ago but I think I have an elegant answer for those of us who already have a "for" statement looping our results and want to automatically put headers on there.

    Here's the code, replace "name" with whatever you want to sort by.

    var headerLetter = null; // Place me outside the loop!
    for (var c=0;c < resultsList.length;c++) { // resultsList refers to the XML results retrieved
        // All your variable definitions go here, including defining name
        var name = null; // Establish the variable
        name = resultsList.item(c).getElementsByTagName("name").item(0).text; // From XML
        var row = Ti.UI.createTableViewRow({height:66, hasChild: true});
            // Figure out what header this goes under
        if(name[0] != headerLetter) {
            row.header = name[0];
            headerLetter = name[0];
        }
        data[c] = row; // add the row to the data array
    }
    // Create the list
    var list = Titanium.UI.createTableView({
        data:data,
        search:search,
        filterAttribute:'hiddenfilter'
    });    
    // Add it to the current window
    win.add(list); // only works if you define current window as win
    

    Hope that helps! It's just a simple if statement which checks what the first letter of the result is. It starts defined as null, so that the first element (whether it stats with 'a' or 'x' will start the headers. From there, it only ever changes the header when a new first letter shows up.

    — answered March 16th 2011 by Walker Williams
    permalink
    2 Comments
    • Ahh that code ended up ugly, sorry about that. Hope it helps.

      — commented March 16th 2011 by Walker Williams
    • looks pretty similar to the solution I posted below four months ago :-)

      — commented March 16th 2011 by Aaron Saunders
The ownership of individual contributions to this community generated content is retained by the authors of their contributions.
All trademarks remain the property of the respective owner.