Thursday 14 August 2014

user todo list application or sample project using node.js with express

Standard

In previous article i have told you how you install and create  a node.js application and also i have told you how you connect with database so now i will give a sample project .
here you can see how database will connect with mysql server and how we manipulate data in node.js
without practice now knowledge is enough so you need a target what you create and how you create that's why i will give a sample project where user can create signup and login and also user can create,edit and delete to do list where you can see project structure and you can idea how a node.js projects work.

so i gave you lots of chitchat and blah blah blah...... now time to work



ok first of i give a file and folder structure screen shot :

handler folder hold all controller file.
public folder hold all static file.
views folder hold all html file(here ejs file).
app.js file for main app file.
config file for server config file.
routes.js file for application route file.

ok now edit your app.js file and delete all content and save below content:
app.js -
var http=require('http');
var express=require('express');
var redisStore=require('connect-redis')(express);
var iniparser=require('iniparser');
var mysql = require('mysql');
var config=iniparser.parseSync('./config.ini');
var fs=require('fs');
var connection  = require('express-myconnection');

var app=express();

app.use(express.bodyParser({keepExtentions:true}));
app.use(express.cookieParser());
app.use(express.cookieSession({
        store:new redisStore({
                host:'127.0.0.1',
                port:5345,
                prefix:'sess',
            }),
        secret:'superkey'
    }));
/*****************mysql connection*******************/
app.use(
    connection(mysql,{
        host: 'localhost',
        user: 'root',
        password : 'root',
        port : 3306,
        database:'node_store'
    },'request')
);
/*****************************************/
var routes=require('./routes')(app);

app.set('view engine', 'ejs');
app.set('views', __dirname + '/views');
app.use(express.static(__dirname + '/public'));
app.use(app.router);
app.use(express.errorHandler());
app.use(express.logger({
        format:'tiny',
        stream:fs.createWriteStream('app.log',{'flagd':'w'})
    }));
app.use(function(req,res){
        res.status(400);
        res.send('File Not Found');
    });

http.createServer(app).listen(config.port,function(){
        console.log('App started on port '+config.port)
    });


next create routes.js file and copy below content and save:
routes.js -
var routes_index=require('./handlers');
var routes_signup=require('./handlers/signup');
var routes_login=require('./handlers/login');
var routes_logout=require('./handlers/logout');
var routes_todo=require('./handlers/todo');

module.exports=function(app){
        app.get('/',routes_index.index);
        app.post('/signup',routes_signup.signup);
        app.post('/login',routes_login.login);
        app.get('/logout',routes_logout.logout);
        app.get('/add-todo',routes_todo.add_todo);
        app.post('/save-todo',routes_todo.save_todo);
        app.get('/edit-todo/:id',routes_todo.edit_todo);
        app.get('/delete-todo/:id',routes_todo.delete_todo);
    }


again create config.ini file same as copy below content and save:
config.ini-
title= My test app
port=3000
message=this is test project


next rename route folder to handler and create a file index.js for home page and copy below content and save in file:
index.js -
var dateFormat = require('dateformat');
exports.index = function(req, res){
    if(typeof req.session.id!='undefined'){
        var todo=[];
        req.getConnection(function(err,connection){
            var query=connection.query("select * from todo where user_id="+req.session.id,function(err,rows){
                    data={title:req.session.fname+' | home',fname:req.session.fname,todo:rows,dateFormat:dateFormat};
                    res.render('home',data);
                });
        });
    }
    else{
        data={title:'login|signup'};
        res.render('index',data);
    }
};


next create login.js for login a user and paste below content:
login.js -
var md5 = require('MD5');
exports.login=function(req,res){
    var input=JSON.parse(JSON.stringify(req.body));
    req.getConnection(function(err,connection){
        var data={
            email:input.email,
            password:md5(input.password)
        };
        var query=connection.query("select * from user where email='"+data.email+"' and password='"+data.password+"'",function(err,rows){
                if(err){
                    res.redirect('/');
                }
                else{
                    if(rows.length>0){
                        req.session.fname=rows[0].fname;
                        req.session.id=rows[0].id;
                    }
                    res.redirect('/');       
                }
            });
    });
};


next create signup.js file for create a user and copy below content:
signup.js -
var md5 = require('MD5');
exports.signup=function(req,res){
    var input = JSON.parse(JSON.stringify(req.body));
    req.getConnection(function (err, connection) {
        passwd=md5(input.password);
        dt_join=Math.round(+new Date()/1000);
        var data = {
            fname    : input.fname,
            lname : input.lname,
            email   : input.email,
            password   : passwd,
            date_join: dt_join
        };
        var query = connection.query("INSERT INTO user set ? ",data, function(err, rows)
        {
            if (err){
                res.redirect('/');
            }
            else{
                req.session.fname=input.fname;
                req.session.id=rows.insertId;
                res.redirect('/');       
            }
        });
    });
};


next create a logout.js file for user logout and copy below content and save:
logout.js -
exports.logout=function(req,res){
    delete req.session;
    res.redirect('/');
};


next create todo.js file for create,edit and delete todo list copy below content and paste:
todo.js -
exports.add_todo = function(req, res){
    if(typeof req.session.id!='undefined'){
        data={title:'Add todo | '+req.session.fname,fname:req.session.fname};
        res.render('add_todo',data);
    }
    else{
        res.redirect('/');
    }
};
exports.save_todo=function(req,res){
    var input=JSON.parse(JSON.stringify(req.body));
    req.getConnection(function(err,connection){
        var data={
            job:input.job,
            add_date:Math.round(+new Date()/1000),
            user_id:req.session.id
        };
        if(typeof input.id=="undefined"){
        var query=connection.query("insert into todo set ?",data,function(err,rows){
                if(err){
                    res.redirect('/add-todo');
                }
                else{
                    res.redirect('/');       
                }
            });
            }
        else{
        var query=connection.query("update todo set job='"+input.job+"' where id="+input.id+" and user_id="+req.session.id,function(err,rows){
                if(err){
                    console.log(err);
                    res.redirect('/');
                }
                else{
                    res.redirect('/');       
                }
            });
            }

    });
};
exports.edit_todo=function(req,res){
    req.getConnection(function(err,connection){
        var query=connection.query("select * from todo where id="+req.params.id,function(err,rows){
        data={title:'Edit todo | '+req.session.fname,fname:req.session.fname,todo:rows};
                    res.render('edit_todo',data);
            });
    });
};
exports.delete_todo=function(req,res){
    req.getConnection(function(err,connection){
        var query=connection.query("delete from todo where id="+req.params.id,function(err,rows){
                    res.redirect('/');
            });
    });
};


now i will use template using template engine al ready i have write article on jade template but today i will use ejs template engine i think it more better for developer where you use row html
so now create index.ejs file in view folder for home page and copy bellow content:
index.ejs -
<%- include layout/header.ejs %>
<div class="mid">
<div class="left small-div">
<h1>Signup</h1>
<form action="signup" method="post">
<label>First Name</label>
<input type="text" name="fname" required>
<label>Last Name</label>
<input type="text" name="lname" required>
<label>Email</label>
<input type="text" name="email" required>
<label>Password</label>
<input type="password" name="password" required>
<input type="submit" value="signup">
</form>
</div>
<div class="right small-div">
<h1>Login</h1>
<form action="login" method="post">
<label>Email</label>
<input type="text" name="email" required>
<label>Password</label>
<input type="password" name="password" required>
<input type="submit" value="Login">
</form>
</div>
<div style="clear:both;"></div>
</div>
<%- include layout/footer.ejs %>


now create home.ejs file in view folder for user will redirect this page after login copy bellow content :
home.ejs -
<%- include layout/header.ejs %>
<div class="mid">
<div><b><%=data.fname%></b>&nbsp;|&nbsp;<a href="/logout">Logout</a></div>
<h1>Todo List</h1>
<a href="add-todo">Add Todo</a>
<table width="100%" cellpadding="5">
<tr>
<td width="5%">Sl.</td><td width="20%">Date</td><td width="70%">Job</td><td width="5%">&nbsp;</td>
</tr>
<%for(i=0;i<todo.length;i++){%>
<tr><td><%=i+1%></td><td><%=dateFormat(todo[i].add_date*1000, "dd-mm-yyyy")%></td><td><%=todo[i].job%></td><td><a href="/edit-todo/<%=todo[i].id%>">Edit</a>&nbsp;|&nbsp;<a href="/delete-todo/<%=todo[i].id%>">Delete</a></td></tr>
<%}%>
</table>
</div>
<%- include layout/footer.ejs %>


again create add_todo.ejs for add todo and copy bellow content :
add_todo.ejs -
<%- include layout/header.ejs %>
<div class="mid">
<div><b><%=data.fname%></b>&nbsp;|&nbsp;<a href="/logout">Logout</a></div>
<h1>Add Todo List</h1>
<form action="save-todo" method="post">
<label>Job</label>
<textarea name="job" required></textarea>
<input type="submit" value="Add">
</form>
</div>
<%- include layout/footer.ejs %>


again create edit_todo.ejs for edit todo and copy bellow content :
edit_todo.ejs -
<%- include layout/header.ejs %>
<div class="mid">
<div><b><%=data.fname%></b>&nbsp;|&nbsp;<a href="/logout">Logout</a></div>
<h1>Edit Todo List</h1>
<form action="/save-todo" method="post">
<label>Job</label>
<textarea name="job" required><%=todo[0]['job']%></textarea>
<input type="hidden" value="<%=todo[0]['id']%>" name="id">
<input type="submit" value="Add">
</form>
</div>
<%- include layout/footer.ejs %>


now i will create a template layout like header,footer so i will create a folder layout in view folder and create two file one header.ejs and another footer.ejs and copy bellow content:
header.ejs -
<html>
<body>
<head>
<title><%=data.title%></title>
<style>
.mid{
display:block;
min-height:400px;
width:700px;
}
.small-div{
width:30%;
float:left;
padding:10px;
}
input,label{
display:block;
margin:10px 0;
}
.left{
border-right:1px solid #000;
}
table tr:first-child td{
    font-weight:bold;
    font-size:20px;
    border-bottom:1px solid #000;
    }
.footer{
    margin-top:50px;
    border-top:1px solid #000;
    }
</style>
</head>


footer.ejs -
<div class="footer">
copyright 2014
</div>
</body>
</html>


you have create all file that area require now time to start your server first go to terminal and next change your directory where you have developed your app next type bellow command:

node app

now open your browser and type http://localhost:3000 and enter then open your login and singup page.

ok now sample project screen shot bellow:
Home page

after login home page

add todo list

edit todo list

now you have sample code and sample project so dont stop go forward