WebFund 2014W: Assignment 1

From Soma-notes

The solutions for this assignment are now available

In this assignment you are to examine, modify, and answer questions regarding the form-demo sample node application. The files of this application are also listed below. You can run this code by running the commands

node app.js

in the unzipped directory within the class Lubuntu VM (or your own node.js environment). Note the zip file includes the needed node_modules, so you do not need to run npm install.

Please submit your answers as a single zip file called "<username>-comp2406-assign1.zip" (where username is your MyCarletonOne username). This zip file should unpack into a directory of the same name (minus the .zip extension of course). This directory should contain:

  • your modified version of form-demo (one version with all code changes) and
  • a text file called "answers.txt" or "answers.pdf" at the top level (in text or PDF format, respectively) that contains the answers to the all of the questions, with the first four lines being "COMP 2406 Assignment 1", your name, student number, and the date. For questions requiring code changes (Part B), explain in your answers file which parts of the program were changed. You may wish to format answers.txt in Markdown to improve its appearance.

No other formats will be accepted. Submitting in another format will likely result in your assignment not being graded and you receiving no marks for this assignment. In particular do not submit an MS Word or OpenOffice file as your answers document!

Questions

There are 60 points below in three parts. Answer all questions.

Part A

What happens when you change the following lines in form-demo? Describe the change in behaviour as if each deletion is the only change made to the application. If a runtime error is generated please describe the error and briefly explain why that error was produced. (two points each, 16 total)

  1. app.js, line 13: delete
  2. app.js, line 14: delete
  3. app.js, line 29: delete
  4. routes/index.js, line 6: delete
  5. routes/index.js, line 18: delete
  6. views/layout.jade, line 10: delete
  7. views/index.jade, line 6: delete
  8. views/index.jade, line 8: change method="post" to method="get"

Part B

Describe how to change the code to add the following features/change the following behaviour. If the changes are small, specify the line(s) to changed. If the changes are more substantial, you may just list the entire modified file. These changes are cumulative, so the changes for the third question should take into account those made previously.

  1. (2 points) Make the application listen on port 3200.
  2. (2 points) Add a "Home" link to the submit results screen (/add) that takes you back to the form screen.
  3. (4 points) Add a "Phone" field to the end of the form that behaves similarly to all of the other form entries.
  4. (6 points) Change the output page views/add.jade to output a table that is nicely formatted using bootstrap. You'll probably want to embed the table inside of a panel and/or a well. The "Home" link should be at the very bottom of the page.
  5. (10 points) Implement an erase all records operation with confirmation:
    • Add a link to the bottom of the initial page (defined in views/index.jade) that says "Erase All Records". This should link to /erase
    • /erase will bring up a page that has a single question on it: "Are you sure you want to erase all records?", followed by two links/buttons: Erase and Cancel. Cancel should go back to /. Erase should do a post to "/erase" with a hidden form value of "confirmed=yes". Make sure to make both Erase and Cancel look the same (even if you implement them differently).
    • The server should check that it got a yes for confirmed and then should erase all records. It should return to the browser a page that says "All records erased." with a link that says "Home" and goes back to /.

Part C

  1. (5 points) Why are the functions in routes/index.js assigned to be properties of the exports object?
  2. (5 points) When are lines 36 and 37 of app.js (the calls to app.get() and app.post()) run? What do these lines do?
  3. (5 points) When is views/layout.jade used, and what does it do?
  4. (5 points) Explain how the #{item.country} in views/add.jade gets its value. Specifically outline, with reference to specific functions and data structures, how the country entered by the user on the initial page ends up output by this statement.

Source

app.js

  
/**
 * Module dependencies.
 */

// set NODE_ENV environment variable.  Defaults to development so
// not needed.  Can also set on the command line with
// "NODE_ENV=development node app.js"
//process.env.NODE_ENV = 'development';

var express = require('express');
var routes = require('./routes');
var user = require('./routes/user');
var http = require('http');
var path = require('path');

var app = express();

// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.json());
app.use(express.urlencoded());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));

// development only
if ('development' == app.get('env')) {
  app.use(express.errorHandler());
}

app.get('/', routes.index);
app.post('/add', routes.add);

http.createServer(app).listen(app.get('port'), function(){
  console.log('Express server listening on port ' + app.get('port') +
	      ' in ' + app.get('env') + ' mode.');
});


routes/index.js

  
/*
 * GET home page.
 */

var state = [];

exports.index = function(req, res){
    res.render('index', { title: 'COMP 2406 Simple form demo' });
};

exports.add = function(req, res){
    var obj = { name: req.body.name,
		city: req.body.city,
                country: req.body.country,
                birthday: req.body.birthday,
                email: req.body.email };
    state.push(obj);
    res.render('add', { title: 'People Listing', items: state });
};


views/layout.jade

doctype html
html
  head
    title= title
    script(src="/vendor/jquery/jquery.js")
    script(src="/vendor/bootstrap/dist/js/bootstrap.js")
    link(rel='stylesheet', href='/vendor/bootstrap/dist/css/bootstrap.css')
    block header
  body
    block content


views/index.jade

extends layout

block content
  h1= title

  div.well
    p Fill out your info
    form(method="post", action="/add")
      div.control-group.input-append
        input#name(type="text", name="name", data-required)
        label.add-on(for="name")
          | Name
      div.control-group.input-append
        input#country(type="text", name="city", data-required)
        label.add-on(for="city")
          | City
      div.control-group.input-append
        input#country(type="text", name="country")
        label.add-on(for="country")
          | Country
      div.control-group.input-append
        input#birthday(type="text", name="birthday")
        label.add-on(for="birthday")
          | Birthday
      div.control-group.input-append
        input#email(type="text", name="email")
        label.add-on(for="email")
          | Email
      button(type="submit") Submit


views/add.jade

extends layout

block content
  h1= title

  each item in items
    p Name: #{item.name}
    p City: #{item.city}
    p Country: #{item.country}
    p Birthday: #{item.birthday}
    p Email: #{item.email}
    br