4

I am trying to build a contact form which is very similar to the one used in the keystone demo but i have hit a road block, While trying to save to db, I get the following errors

    { message: 'Validation failed',
  name: 'ValidationError',
  errors: 
   { name: 
      { name: 'ValidatorError',
        path: 'name',
        message: 'Name is required',
        type: 'required' } } }

I have checked the fields on the form and also the request in the backend by doing a console.log but for some reason i still keep on getting the same error.

Here is what I have in my jade file

section#contact-container
   section#contact.contact-us
    .container
      .section-header
        // SECTION TITLE
        h2.white-text Get in touch
        // SHORT DESCRIPTION ABOUT THE SECTION
        h6.white-text
          | Have any question? Drop us a message. We will get back to you in 24 hours.

      if enquirySubmitted
       .row
          h3.white-text.wow.fadeInLeft.animated(data-wow-offset='30', data-wow-duration='1.5s', data-wow-delay='0.15s') Thanks for getting in touch.
      else
        .row
          form#contact.contact-form(method="post")
             input(type='hidden', name='action', value='contact')
             .wow.fadeInLeft.animated(data-wow-offset='30', data-wow-duration='1.5s', data-wow-delay='0.15s')
              .col-lg-4.col-sm-4(class=validationErrors.name ? 'has-error' : null)
                input.form-control.input-box(type='text', name='name', value=formData.name, placeholder='Your Name')
              .col-lg-4.col-sm-4
                input.form-control.input-box(type='email', name='email', value=formData.email, placeholder='Your Email')
              .col-lg-4.col-sm-4
                div(class=validationErrors.enquiryType ? 'has-error' : null)
                input.form-control.input-box(type='text', name='enquiryType', placeholder='Subject', value=formData.enquiryType)
             .col-md-12(class=validationErrors.message ? 'has-error' : null)
             .col-md-12.wow.fadeInRight.animated(data-wow-offset='30', data-wow-duration='1.5s', data-wow-delay='0.15s')
               textarea.form-control.textarea-box(name='message', placeholder='Your Message')= formData.message
             button.btn.btn-primary.custom-button.red-btn.wow.fadeInLeft.animated(data-wow-offset='30', data-wow-duration='1.5s', data-wow-delay='0.15s', type='submit') Send Message

and this is how my schema and route file looks like

    var keystone = require('keystone'),
    Types = keystone.Field.Types;

var Enquiry = new keystone.List('Enquiry', {
    nocreate: true,
    noedit: true
});

Enquiry.add({
    name: { type: Types.Name, required: true },
    email: { type: Types.Email, required: true },
    enquiryType: { type: String },
    message: { type: Types.Markdown, required: true },
    createdAt: { type: Date, default: Date.now }
});

Enquiry.schema.pre('save', function(next) {
    this.wasNew = this.isNew;
    next();
});

Enquiry.schema.post('save', function() {
    if (this.wasNew) {
        this.sendNotificationEmail();
    }
});

Enquiry.schema.methods.sendNotificationEmail = function(callback) {

    var enqiury = this;

    keystone.list('User').model.find().where('isAdmin', true).exec(function(err, admins) {

        if (err) return callback(err);

        new keystone.Email('enquiry-notification').send({
            to: admins,
            from: {
                name: 'Wheatcroft Accounting',
                email: 'contact@abc.com'
            },
            subject: 'New Enquiry for **',
            enquiry: enqiury
        }, callback);

    });

};

Enquiry.defaultSort = '-createdAt';
Enquiry.defaultColumns = 'name, email, enquiryType, createdAt';
Enquiry.register();

This is the route file

  var keystone = require('keystone'),
     async = require('async'),
     Enquiry = keystone.list('Enquiry');


 exports = module.exports = function(req, res) {

     var view = new keystone.View(req, res),
         locals = res.locals;

     locals.section = 'contact';
     locals.formData = req.body || {};
     locals.validationErrors = {};
     locals.enquirySubmitted = false;

     view.on('post', { action: 'contact' }, function(next) {
         var newEnquiry = new Enquiry.model();
         var updater = newEnquiry.getUpdateHandler(req);
         updater.process(req.body, {
             flashErrors: true,
             fields: 'name, email, enquiryType, message',
             errorMessage: 'There was a problem submitting your enquiry:'
         }, function(err) {
             if (err) {
                 locals.validationErrors = err.errors;
                 console.log(err);
             } else {
                 locals.enquirySubmitted = true;
             }
             next();
         });

     });

     view.render('contact');

 }
Bazinga777
  • 5,140
  • 13
  • 53
  • 92

1 Answers1

3

I believe the problem has to do with the way KeystoneJS handles Types.Name field types internally.

In your jade file, you should reference your name field using a path to its virtual name.full property. Internally name.full has a setter that splits the name into name.first and name.last. So, if you wish to have separate input for the first and last name you should use name.first and name.last. If you want a single input to enter the full name you should use name.full.

Try replacing the input control for your name field:

input.form-control.input-box(type='text', name='name', value=formData.name, placeholder='Your Name')

with this:

input.form-control.input-box(type='text', name='name.full', value=formData['name.full'])
JME
  • 3,592
  • 17
  • 24