I am dynamically building a TableView in my controller, which works fine: The initial table displays the initial collections data as expected.
The problem is that the TableView's 'click' event listener is ignored when I click on the table rows. I am testing in the browser, and I never even see the console event file (see comments in controller file). All relevant code snippets below:
In my alloy.js
I setup a backbone collection:
function defaultTodo(name) { return {name: name, done: false}; }
function doneTodo(name) { return {name: name, done: true}; }
Alloy.Collections.todos = new Backbone.Collection();
Alloy.Collections.todos.reset([
defaultTodo('Apples'), // create not yet done todo
defaultTodo('Banana'),
defaultTodo('Paper Towels'),
defaultTodo('Broccoli'),
doneTodo('Beans'), // create already done todo
doneTodo('Water'),
doneTodo('Blueberries'),
doneTodo('Stir Fry')
])
Here is my index.js
controller:
var todos = Alloy.Collections.todos;
function redrawTable() {
// clear all the old data
// See http://developer.appcelerator.com/question/49241/delete-all-rows-in-a-tableview-with-a-single-click
$.table.setData([]);
// Create and add the TableViewSections
var alreadyDone = Ti.UI.createTableViewSection({ headerTitle: "Already Done" });
var needsDoing = Ti.UI.createTableViewSection({ headerTitle: "Needs Doing" });
$.table.appendSection(needsDoing);
$.table.appendSection(alreadyDone);
// Add the todo to the appropriate sections
todos.forEach(function(todo) {
var section = todo.get('done') ? alreadyDone : needsDoing;
addEntry(todo, section);
});
// Add the click listener
// THIS LISTENER IS IGNORED ********************************
$.table.addEventListener('click', function(e) {
console.log(e);
todos.at(e.index).set('done', true);
todos.trigger('change');
});
// Helper function to add a row to a section
function addEntry(todo, section) {
var row = Ti.UI.createTableViewRow({
title: todo.get('name'),
className: "row"
});
section.add(row);
}
}
// Redraw our table each time our todos collection changes
todos.on('change', redrawTable);
// Trigger a change event to draw the initial table
todos.trigger('change');
$.index.open();
And here is index.xml
view file:
<Alloy>
<Window class="container">
<Label id="test" class="header">My Grocery List</Label>
<TextField id="newItem"/>
<TableView id="table">
</TableView>
</Window>
</Alloy>
UPDATE: Working Code
In addition to the changes below, I also added onClick="markDone"
to the xml.
function markDone(e) {
console.log(e.row.todo);
e.row.todo.set('done', true);
todos.trigger('change');
}
function redrawTable() {
// clear all the old data
// See http://developer.appcelerator.com/question/49241/delete-all-rows-in-a-tableview-with-a-single-click
$.table.setData([]);
var rows = [];
var done = [];
var doing = [];
// Add the todo to the appropriate sections
todos.forEach(function(todo) {
var row = Ti.UI.createTableViewRow({
title: todo.get('name'),
className: "row"
});
row.todo = todo;
todo.get('done') ? done.push(row) : doing.push(row);
});
// Create and add the TableViewSections
rows.push(Ti.UI.createTableViewSection({ headerTitle: "Needs Doing" }));
rows = rows.concat(doing);
rows.push(Ti.UI.createTableViewSection({ headerTitle: "Already Done" }));
rows = rows.concat(done);
$.table.setData(rows);
};