Skip to content

Instantly share code, notes, and snippets.

@someguycrafting
Created November 6, 2014 12:57
Show Gist options
  • Save someguycrafting/e6ec2dfaca44c4511479 to your computer and use it in GitHub Desktop.
Save someguycrafting/e6ec2dfaca44c4511479 to your computer and use it in GitHub Desktop.
Sample implementation of collapsable list view sections in Titanium (Common JS)
/*
* Sample implementation of collapsable list view sections in Titanium (Common JS)
* by Renato Costa (renato (dot) duino (at) gmail (dot) com)
*/
var indicatorOpened = '[-]';
var indicatorClosed = '[+]';
var exampleList;
//Simple window for demo purposes
var window = Titanium.UI.createWindow({
backgroundColor: 'white',
fullscreen: true,
title : 'Collapsible listview example'
});
setupList();
addHeaders();
window.open();
function setupList() {
// *** Start by setting up the templates
// This will be our fake expandable header
var expandableHeaderTemplate = {
properties: {
accessoryType: Ti.UI.LISTACCESSORYTYPENONE,
selectionStyle: Ti.Platform.osname == 'android' ? null : Titanium.UI.iPhone.ListViewCellSelectionStyle.NONE, //setting this will disable listview item from getting selected in iOS
height: Ti.UI.SIZE,
width: Ti.UI.FILL,
isExpanded: false // this is our custom property that will maintain expansion status
},
events: {
click: headerSelected
},
childTemplates: [
{
type: 'Ti.UI.View',
properties: {
touchEnabled: true,
height: Ti.UI.SIZE,
width: Ti.UI.FILL,
top: '10dp', //Adds some padding between headers
layout: 'composite', //Actually this is the default view layout, I'm just putting this for example purposes,
backgroundColor: '#f9f9f9'
},
childTemplates: [
//Header title
{
type: 'Ti.UI.Label',
bindId: 'title',
properties: {
touchEnabled: false,
color: '#000000',
font: {fontSize: '16sp'},
height: Ti.UI.SIZE,
width: Ti.UI.SIZE,
top: '10dp',
bottom: '10dp',
left: '10dp',
right: '30dp' //Add some padding to the right so we don't overlap with our expanded indicator
}
},
//Expand indicator
{
type: 'Ti.UI.Label',
bindId: 'expand',
properties: {
touchEnabled: false,
font: {fontSize: '16sp', fontWeight: 'bold'},
color: '#0099cc',
text : indicatorClosed,
height: Ti.UI.SIZE,
width: Ti.UI.SIZE,
right: '10dp'
}
}
]
}
]
};
// This will be fake child template (a simple image in this example)
var imageTemplate = {
properties: {
accessoryType: Ti.UI.LISTACCESSORYTYPENONE,
height: 64,
width: 64,
},
events: {
click: function () {
alert('Hey, you just clicked me!');
}
},
childTemplates: [
{
type: 'Ti.UI.ImageView',
bindId: 'icon',
properties: {
width: Ti.UI.Size,
height: Ti.UI.Size,
hires: true //Setting this in iOS disable retina scaling for remote images
}
}
]
};
//Setup our list
exampleList = Ti.UI.createListView({
top: Ti.Platform.osname == 'android' ? 0 : 20, //iOS specific padding
width: Ti.UI.FILL,
height: Ti.UI.FILL,
separatorColor: 'transparent',
touchEnabled: true,
templates: { 'header': expandableHeaderTemplate , 'image': imageTemplate }, //Notice how templates are associated
defaultItemTemplate: 'header', //Use header template by default
showVerticalScrollIndicator: true
});
window.add(exampleList);
}
function addHeaders() {
//Add some fake expandable headers. Each header will correspond to a new ListSection
var dummyHeaders = [
{ template: 'header', title: {text: 'Weather icons' }, expand: {text: indicatorClosed }, isExpanded: false },
{ template: 'header', title: {text: 'Document icons' }, expand: {text: indicatorClosed }, isExpanded: false },
];
var sections = [];
for(var i=0,j=dummyHeaders.length; i<j; i++){
sections.push(Ti.UI.createListSection({
items: [dummyHeaders[i]],
id: i
}));
};
exampleList.setSections(sections);
}
function headerSelected(e) {
//When our fake header is clicked we'll handle it here
var header = e.section.getItemAt(e.itemIndex);
var items = e.section.getItems();
//Check if it is expanded - remember our custom property?
if (header.isExpanded) {
//It's expanded, so we'll 'close' it, remove all header children rows that is
// Position 0 of the list section is the header, so we start at position 1
var totDel = items.length - e.itemIndex+1;
e.section.deleteItemsAt(e.itemIndex+1, totDel);
header.expand.text = indicatorClosed;
}
else {
//It's closed, so we'll expand it, add children rows, that is
showSectionItems(e.section);
header.expand.text = indicatorOpened;
}
//Update our header so it reflect the changes
header.isExpanded = !header.isExpanded;
e.section.updateItemAt(e.itemIndex, header);
}
function showSectionItems(section) {
var dummyIcons;
switch (section.id) {
case 0:
//Show some weather icons
dummyIcons = [
{ template: 'image', icon: {image: 'http://findicons.com/icon/download/440711/weathersunny/128/png' } },
{ template: 'image', icon: {image: 'http://findicons.com/icon/download/440760/weatherrain/128/png' } },
{ template: 'image', icon: {image: 'http://findicons.com/icon/download/440715/weathersnow/128/png' } },
];
break;
case 1:
//Show some document icons
dummyIcons = [
{ template: 'image', icon: {image: 'http://findicons.com/icon/download/71512/filedoc/128/png' } },
{ template: 'image', icon: {image: 'http://findicons.com/icon/download/71485/filexml/128/png' } },
{ template: 'image', icon: {image: 'http://findicons.com/icon/download/71485/filepdf/128/png' } },
];
break;
}
section.appendItems(dummyIcons);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment