Up until now we’ve only did GET requests: when we load a page, we ask the server to send us a page and its assets.
In order for a user to send information to the server, we need a POST form.
You need a <form> element with 2 attributes:
the method post
the action /contact
We’re going to use 3 types of form elements:
the text input
the select dropdown
the multiline textarea
<formclass="form"method="post"action="/contact"><divclass="field"><labelclass="label">Name</label><inputclass="input"type="text"name="name"value="{{formBody.name}}"></div><divclass="field"><labelclass="label">Email</label><inputclass="input"type="email"name="email"value="{{formBody.email}}"></div><divclass="field"><labelclass="label">Subject</label><divclass="select"><selectname="subject"><optionvalue="press">Press inquiry</option><optionvalue="work">Work opportunity</option><optionvalue="hi">Just to say hi!</option></select></div></div><divclass="field"><labelclass="label">Message</label><textareaclass="textarea"name="message">{{formBody.message}}</textarea></div><divclass="field no-label"><buttonclass="button">Send</button></div></form>
When we submit the form by clicking “Send”, we’re sending a POST request to the server.
In the request object req we can find all the information sent. The req.body will contact all the values based on the name attribute of each form element.
Because we have <textarea name="message"> we can retrive its value with req.body.message.
For now, we are only going to create a formBody object and log it, and pass the value back to the template, so that we don’t lose the already submitted data.
// Handle the contact form submissionapp.post('/contact',function(req,res){varformBody={'name':req.body.name,'email':req.body.email,'subject':req.body.subject,'message':req.body.message,};console.log(formBody);res.render('contact',{formBody,});});
As we don’t want to receive an email if the name, email address, or message is empty, let’s check the values of each.
If any of them is empty, we are going to display an error message, explaining:
why there was an error
how to fix that error
We’re going to pass more data to the template:
an error boolean
a message string
a boolean for each missing field
Make sure to return the response, so that we don’t render the template twice.
varmissingName=(formBody.name==='');varmissingEmail=(formBody.email==='');varmissingMessage=(formBody.message==='');if(missingName||missingEmail||missingMessage){returnres.render('contact',{error:true,message:'Some fields are missing.',formBody:formBody,missingName:missingName,missingEmail:missingEmail,missingMessage:missingMessage,});}
The {{#if}}...{{/if}} block allows to display HTML only if the boolean is true.
We add a error block which displays the message, only if error is true.
After each field, we show a missing block, only if that field is empty.
{{#iferror}}<pclass="error">{{message}}</p>{{/if}}<form><!-- Name field -->{{#ifmissingName}}<pclass="missing">The name is required.</p>{{/if}}<!-- Email field -->{{#ifmissingEmail}}<pclass="missing">The email is required.</p>{{/if}}<!-- Textarea -->{{#ifmissingMessage}}<pclass="missing">The message is required.</p>{{/if}}<!-- Send button --></form>
When all the fields are present, we need to create an emailOptionsobject with all the required data:
the sender from
the recipient to
the subject
the content of the email
As sending the email is not guaranteed, we need to handle that error case as well. We need to make sure to pass the formBody data, so that the user doesn’t lose the fields they’ve already filled.
// Email optionsvaremailOptions={from:formBody.name+' <'+formBody.email+'>',to:'[email protected]',subject:'Website contact form - '+formBody.subject,text:formBody.message,};// Try send the emailmailgun.messages().send(emailOptions,function(error,response){if(error){res.render('contact',{error:true,message:'The message was not sent. Please try again.',formBody:formBody,});}else{res.render('contact',{success:true,message:'Your message has been successfully sent!',});}});