Horizontal List/table view for iOS or Mobile web?

You must Login before you can answer or comment on any questions.

Is there a way to take a dataset that's displayed in a typical Table view (like this, mobile web):

tableview

As display it horizontally, something more like this:

horizontal

I need this to work in Mobile Web, but working on iPad would be great too.


SDK 2.1.1, OS 10.8

1 Answer

Accepted Answer

Hi Steve

Very easy - since 2.0.

You can add an attribute called layout: that has really flourished with the benefit of the changes to the sizes that have appeared.

This is an example using a scrollview with children, but you can also do this on any view or window.

Add this as the parent - think of it as the container above - light yellow background

var scrollView = Ti.UI.createScrollView({
    contentHeight: 'auto',
    contentWidth: 'auto',
    height: Ti.UI.FILL,
    layout: 'horizontal',
    showHorizontalScrollIndicator: true,
    showVerticalScrollIndicator: true,
    width: Ti.UI.FILL
});
win.add(scrollView);
Add as many of these as you need - use loop to iterate your data of course
// hold each thumnail view
var viewChild = Ti.UI.createView({
    height: Ti.UI.SIZE,
    layout: 'vertical',
    width: Ti.UI.SIZE
});
scrollView.add(viewChild);
//image of thumbnail view
var imageChild = Ti.UI.createImageView({
    height: Ti.UI.SIZE,
    image: 'image.png',
    width: Ti.UI.SIZE
});
viewChild.add(imageChild);
// label of thumbnail view (shown under image)
var lblChild = Ti.UI.createLabel({
    height: Ti.UI.SIZE,
    text: 'Caption',
    width: Ti.UI.SIZE
});
viewChild.add(lblChild);
You can use normal textAlign for the label to center it and use top, bottom, left & right as if they were margins - for example, changint eh label code to this;
// label of thumbnail view (shown under image)
var lblChild = Ti.UI.createLabel({
    height: Ti.UI.SIZE,
    text: 'Caption',
    textAlign: 'center',
    top: 10,
    width: Ti.UI.SIZE
});
viewChild.add(lblChild);
Will align the text to center and push the label 10 pixels DOWN from the previous view added to this parent.

The magic is the use of the layout property as mentioned. With horizontal all views are added from top left across right and until they run out of space and then move down to the next line. Using vertical things appear underneath each other.

Makes very light work laying out your work.

— answered 10 months ago by Malcolm Hollingsworth
answer permalink
15 Comments
  • @malcolm This is great, thanks. One question, though, how can I get info about which item the user selects, and affect its display accordingly? In my current app with the table view, I have an event on the table view:

    tv1.addEventListener('click', function(e) {
    var rowNum = e.index;
    var currentRow = tv1.data[0].rows[rowNum];
    if (currentRow.isChosen == false && !maxReached) {
        currentRow.isChosen = true;
        currentRow.children[2].backgroundImage ='images/checked.png';
    } else if (currentRow.isChosen == true) {
        currentRow.isChosen = false;
        currentRow.children[2].backgroundImage ='images/unchecked.png';
    } else {
        showMaxAlert();
    }
    
    checkAmounts(tv1,step2min,step2max,nextBtn);
    
    Ti.API.info('Row is '+currentRow.isChosen);
    
    });
    

    — commented 10 months ago by Steve Lombardi

  • An easy way would be to add the property touchEnabled: false to both the image and label and then add an event listener to the viewChild variable from my example.

    By turning of touch on the children you only have to worry about getting the events from its parent - simplifies things greatly.

    You can then use the same technique you have already by setting your custom isChosen property correctly. In the eventlistener you can toggle it by using e.source.isChosen for example;

    viewChild.addEventlistener('click', function (e) {
            // loop through the other children to turn off their isChosen property
            // then set this one as the correct one
        e.source.isChosen = true;
            // use border, background color or image or whatever you want to show as chosen
    });
    You can obviously encapsulate my code above and this into a neet re-usable CommonJS model and handle all the logic of selecting etc inside that and simply pass the original data and a select handler.

    — commented 10 months ago by Malcolm Hollingsworth

  • @malcolm It works great, thanks. See below. There's no way to get a grid-like layout this way, is there?

    — commented 10 months ago by Steve Lombardi

  • Show 12 more comments

Your Answer

Think you can help? Login to answer this question!