Search code examples
node.jsexpresspugstormpath

Checkbox with Stormpath + Jade + node.js + express


I've been trying to expand the form from this tutorial (https://stormpath.com/blog/build-nodejs-express-stormpath-app) for my web app. I want to have a checkbox and currently have the following code in my jade file:

div.form-group
      label.col-sm-4 Sports
      div.col-sm-8
        input.form-control(placeholder='e.g. What sports are you interested in?',
          name='sports',
          type='checkbox',
          value="true")

My .js file on the server side is as follows:

var profileForm = forms.create({
  givenName: forms.fields.string({
    required: true
  }),
  surname: forms.fields.string({ required: true }),
  city: forms.fields.string(),
  state: forms.fields.string(),
  zip: forms.fields.string(),
  sports: forms.fields.string()
});

// A render function that will render our form and
// provide the values of the fields, as well
// as any situation-specific locals

function renderForm(req,res,locals){
  res.render('profile', extend({
    title: 'My Profile',
    csrfToken: req.csrfToken(),
    givenName: req.user.givenName,
    surname: req.user.surname,
    city: req.user.customData.city,
    state: req.user.customData.state,
    zip: req.user.customData.zip,
    sports: req.user.customData.sports
  },locals||{}));
}

// Export a function which will create the
// router and return it

module.exports = function profile(){

  var router = express.Router();

  router.use(cookieParser());

  router.use(bodyParser.urlencoded({ extended: true }));

  router.use(csurf({ cookie: true }));

  // Capture all requests, the form library will negotiate
  // between GET and POST requests

  router.all('/', function(req, res) {
    profileForm.handle(req,{
  success: function(form){
    // The form library calls this success method if the
    // form is being POSTED and does not have errors

    // The express-stormpath library will populate req.user,
    // all we have to do is set the properties that we care
    // about and then call save() on the user object:
    req.user.givenName = form.data.givenName;
    req.user.surname = form.data.surname;
    req.user.customData.city = form.data.city;
    req.user.customData.state = form.data.state;
    req.user.customData.zip = form.data.zip;
    req.user.customData.sports = form.data.sports;
    req.user.customData.save();
    req.user.save(function(err){
      if(err){
        if(err.developerMessage){
          console.error(err);
        }
        renderForm(req,res,{
          errors: [{
            error: err.userMessage ||
            err.message || String(err)
          }]
        });
      }else{
        renderForm(req,res,{
          saved:true
        });
      }
    });
  },

It appears as though the checkbox status is not saved because when I refresh it always returns to the same status. Does anyone know how I can create checkboxes that save state in the customData Stormpath allows you to save 10MB in?


Solution

  • The issue appears to be with the markup for the input element, you'll need to tell it how to set the checked attribute for the element, based on the sports variable that you are passing down to the template:

    input.form-control(placeholder='e.g. What sports are you interested in?',
        name='sports',
        type='checkbox',
        value="true"
        checked=(sports ? "checked" : undefined))
    

    I hope this helps! I work at Stormpath and I wrote the tutorial article that you've been looking at :)