Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Node.js, Express and Jade - Forms

I'm using Node.js, Express and Jade and I'm trying to figure out how to post, validate & process form data.

In my jade file I create a contact form:

div#contact-area
    form(method='post',action='')
        label(for='name') Name:
        input(type='text',name='name',id='name')        
        label(for='email') Email:
        input(type='text',name='email',id='email')  
        input(type='submit',name='submit',value='Submit').submit-button

I'm then utilising the module 'express-validator' to validate the form as follows:

var express = require('express')
    ,routes = require('./routes')
    ,http = require('http')
    ,path = require('path')
    ,expressValidator = require('express-validator')
;

var app = express.createServer();

app.configure(function(){
    app.set('views', __dirname + '/views');
    app.set('view engine', 'jade'); //not needed if we provide explicit file extension on template references e.g. res.render('index.jade');
    app.use(express.bodyParser());
    app.use(expressValidator);
    app.use(express.methodOverride());
    app.use(app.router);
});

//display the page for the first time
app.get('/mypage', function(req,res){
    res.render('mypage', { 
        title: 'My Page'        
    });            
});
//handle form submission
app.post('/mypage', function(req,res){
    req.assert('name', 'Please enter a name').notEmpty();
    req.assert('email', 'Please enter a valid email').len(6,64).isEmail();

    var errors = req.validationErrors();
    if( !errors){   
        sendEmail(function(){
            res.render('mypage', { 
                title: 'My Page',
                success: true
            });
        });
    }
    else {
        res.render('mypage', { 
            title: 'My Page',
            errors: errors
        });
    }
 });

So there are three scenarios where my pages is rendered, and each one has access to different local variables:

  1. When the page is loaded for the first time (errors=undefined,success=undefined)
  2. When the form is submitted and there are errors (errors=array,success=undefined)
  3. When the form is submitted and there are no errors (errors=undefined,success=true)

So my main problems are that:

  1. When my Jade page is loaded, it seems to throw an error when I attempt to access a variable that doesn't exist. For example, I want to see if the variable 'success' is set, and if it is I want to hide the form and display a "thanks" message. Is there an easy way to handle a variable in Jade that will either be undefined or a value?
  2. When the form has been submitted and there are validation errors, I want to show an error message (this isn't a problem) but also populate the form with the variables that were previously submitted (e.g. if the user provided a name but no email, the error should reference the blank email but the form should retain their name). At the moment the error message is displayed but my form is reset. Is there an easy way to set the input values of the fields to the values in the post data?
like image 357
Craig Myles Avatar asked Nov 13 '22 00:11

Craig Myles


1 Answers

  1. You can fix that by using locals.variable instead of just variable. Also you can use javascript in jade.

    -locals.form_model = locals.form_data || {};

  2. I used two ways to solve this problem. The first one is to re-render the view and you pass the req.body as a local. I have a convention that my forms use form_model.value for their field values. This method is works well for simple forms but it starts to breakdown a little when you form is relying on data.

    The second method is to pass your req.body to session then redirect to a route that renders the form. Have that route looking for a certain session variable and use those values in your form.

like image 89
Pickels Avatar answered Nov 16 '22 17:11

Pickels