The flatiron library is no more. So, other than reading stuff, there just isn't all that much relevant stuff, here.

This post continues the creation of a to-do list with flatiron.js.

Previous Stories in this Series

Last but not least: we need to allow the user to delete a listed item. So, we can change the template used to create the list items to include a delete button. Here’s what I have, simple and ugly.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
app.router.get('/', function() {
var self = this;
fs.readFile('index.html', function(err, data) {
if(err) {
self.res.writeHead(404);
self.res.end();
return;
}
var listContent = "";
var listItemTemplate = '<button>Delete Item</button>' +
'<span id="ctime" class="ctime"></span>' +
'I need to <span id="desc" class="desc"></span>' +
'<input type="hidden" name="method" value="DELETE" />' +
'<input type="hidden" id="id" name="id" value="" />';
if(typeof self.req.session.tasks === 'undefined') {
self.req.session.tasks = [];
}
var options = {
'id': ['id', 'value'],
'ctime': 'id',
'desc': 'id'
};
self.req.session.tasks.forEach(function(task) {
var data = {
'desc': task.desc,
'ctime': new Date(task.ctime).toDateString().substr(4),
'id': task._id
};
listContent += '<li>' +
'<form method="post" action="/">' +
plates.bind(listItemTemplate, data, options) +
'</form>' +
'</li>';
});
data = plates.bind(data, {'task-list': listContent});
self.res.writeHead(200, {'Content-Type': 'text/html'});
self.res.end(data);
})
});

Now, we need to take into account the post for that Delete button. Because we have made this a POST, we can handle it in the POST handler that we defined in Story 3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
app.router.post('/', function() {
var self = this;
if(self.req.body.method && self.req.body.method === "DELETE") {
var taskId = self.req.body.id;
var task = Task.get(taskId);
var tasks = self.req.session.tasks;
tasks = tasks.splice(0, tasks.indexOf(task)).concat(tasks.splice(1));
self.req.session.tasks = tasks;
Task.destroy(taskId);
} else {
var task = new (Task)({desc: self.req.body.desc});
if(task.validate().valid) {
task.save();
if(!self.req.session.tasks) {
self.req.session.tasks = [];
}
self.req.connection = {encrypted: false};
self.res.emit('header');
self.req.session.tasks.push(task);
}
}
self.res.writeHead(303, {'Location': '/'});
self.res.end();
});

And, that’s it. Everything works. It’s not pretty: the UI, the code. It would be nice to convert the POST that destroys a task into a DELETE message; however, that’s deeper than this article should go.

And, obviously, plates leaves a lot to be desired. I actually had a different implementation in my GET handler for this story and found that plates falls apart with its “simple” (read: buggy) HTML parser. I would like a DOM to actually handle this; however, as they mention in the documentation, those options do not perform quickly enough.

But, this is it: flatiron. Overall, I like its unobtrusive nature. I think I will find it easy to build applications atop this framework.

And, here’s the completed code.