I'm trying to use Nodemailer to send emails by clicking submit on a web form. The test strings of the embedded script are being printed, but after that the script fails with this message in the console:
ReferenceError: require is not defined
What's interesting is that I receive emails from this script when I run it directly from the terminal, but when I try to trigger it from my web form, I get this error.
Almost everywhere I've looked people present a script such as the one directly below as being the only thing needed to send emails using Nodemailer. Neither the Nodemailer website nor W3Schools make reference to anything else. What am I missing?
Thank you for your time,
-Joel
<script>
const myForm = document.getElementById('myForm');
console.log("Testing!");
myForm.addEventListener("click", () => {
var nodemailer = require('nodemailer');
var transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
user: 'angleritemailer#gmail.com',
pass: 'hammertime80'
}
});
const mailOptions = {
from: 'angleritemailer#gmail.com',
to: 'joelnashjobs#yahoo.com',
subject: 'hey',
text : 'text',
html: '<p>Your html here</p>'
}
transporter.sendMail(mailOptions, function(err, info) {
if (err)
console.log(err)
else
console.log(info);
});
});
</script>
<form" class = "col-sm-6" action = "/" method = "POST" id = "myForm">
<div class = "row form-row form-group">
<div class = "col-sm-5">
<input type = "text" class = "form-control-plaintext full-width" id = "name" placeholder = "Your name here">
</div>
<div class = "col-sm-2">
</div>
<div class = "col-sm-5 widen-slightly">
<input type = "text" class = "form-control-plaintext full-width" id = "staticEmail" placeholder = "email#example.com">
</div>
</div>
<div class = "row form-row form-group">
<div class = "col-sm-12 widen-slightly">
<input type = "text" class = "form-control-plaintext full-width" id = "phone" placeholder = "Phone number with area code">
</div>
</div>
<div class = "row form-row form-group">
<div class = "col-sm-12 widen-slightly">
<input type = "text" class = "form-control-plaintext full-width" id = "subject" placeholder = "Subject">
</div>
</div>
<div class = "row form-row form-group">
<div class = "col-sm-12 widen-slightly">
<textarea rows = "6" class = "form-control-plaintext full-width" id = "Description" placeholder = "Description"></textarea>
</div>
</div>
<div class = "row form-row form-group">
<label class = "col-sm-3 col-form-label" >Any Photos</label>
<div class = "col-sm-7">
<input type = "file" class = "form-control-file full-width" id = "">
</div>
<div class = "cl-sm-2">
<button type="submit" class="btn btn-default" id = "submit">Submit</button>
</div>
</div>
</form>
Related
In the form I am making, there is a section that requires users to enter the amount of people in their family. After they provide it, the form generates enough input fields so that the user can enter information for each family member.
What I am having trouble with is none of the attributes that I am trying to apply to the input element actually work.
function addHouseMembers(that){
var family = document.getElementById("family-input-container");
while(family.hasChildNodes()){
family.removeChild(family.lastChild);
}
for(var i = 1; i < that.value; i++){
family.appendChild(document.createTextNode("Family Member " + (i+1)));
family.appendChild(document.createElement("br"));
//name
family.appendChild(document.createTextNode("Name: " ));
var input = document.createElement("input");
input.type = "text";
input.name = "member" + i + "_name";
input.pattern = "/^[a-zA-Z ]*$/";
input.required = true;
family.appendChild(input);
family.appendChild(document.createElement("br"));
}
}
The parameter that refers to the input where the user would put in the number of people in their family.
And here is the relevant HTML:
<form>
<div class="form-group">
<label class="col-lg-3 control-label">What is the total amount of people living in your household?</label>
<div class="col-lg-3 inputGroupContainer">
<div class = "input-group">
<input type="text" class="form-control" name="household-size" required onchange="addHouseMembers(this);"/>
</div>
</div>
</div>
<div class="form-group", id="family-info">
<label class="col-lg-12">Information for other Family Members</label>
<div class="col-lg-3 inputGroupContainer">
<div class = "input-group" id = "family-input-container" required>
</div>
</div>
</div>
</form>
The element shows up as it should, and is submitted with the form when the user hits the submit button, but the regex pattern and required attributes are not enforced.
in addHouseMembers(that) the value of that is a string, not a number, and you have to check if is value can be 'translated' in an integer value.
use the "onchange" event on the input field household-size is not a good idea because this event is triggered each time a digit of the number entered, which has the effect of erasing and completely rewrite the family-input-container part
I Imagine you are looking for something like that ?
const myForm = document.getElementById('my-form')
, familyElm = document.getElementById('family-input-container')
, parserDOM = new DOMParser()
;
function newHouseMember(ref)
{
let div=
` <div>
Family Member ${ref}<br>Name: <br>
<input type="text" name="member${ref}_name" pattern="/^[a-zA-Z ]*$/" required >
</div>`
return parserDOM.parseFromString( div, 'text/html').body.firstChild
}
myForm.btPeoples.onclick=_=>
{
let nbPeoples = parseInt(myForm['household-size'].value)
if (!isNaN(nbPeoples) && nbPeoples > 0 )
{
familyElm.innerHTML = ''
for (let i=1; i<=nbPeoples; i++)
{
familyElm.appendChild( newHouseMember(i) )
}
}
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet" >
<form id="my-form">
<div class="form-group">
<label class="col-lg-3 control-label">What is the total amount of people living in your household?</label>
<div class="col-lg-3 inputGroupContainer">
<div class = "input-group">
<input class="form-control" name="household-size" required value="" placeholder="number of peoples" pattern="\d*" />
<button name="btPeoples" class="btn btn-info" type="button" >check it!</button>
</div>
</div>
</div>
<div class="form-group", id="family-info">
<label class="col-lg-12">Information for other Family Members</label>
<div class="col-lg-3 inputGroupContainer">
<div class="input-group" id="family-input-container">
</div>
</div>
</div>
</form>
I'm trying to create an HTML form that will send an email using the information inputed. For now however, I just hard coded the information into the script itself, so the field inputs don't matter. However, whenever I press the Submit button, is simply displays the Javascript to the screen instead of executing it. The script is in the same directory as the HTML.
I tested it by running it directly from the Ubuntu terminal and successfully received an email from it.
I'm running this on Ubuntu 16.04, Node v6.14.3. The HTMl uses Bootstrap 4, and the email process is with Nodemailer. Thank you very much for your time.
-Joel
var nodemailer = require('nodemailer');
var transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
user: 'redacted',
pass: 'redacted'
}
});
const mailOptions = {
from: 'redacted',
to: 'redacted',
subject: 'hey',
text : 'text',
html: '<p>Your html here</p>',
attachments:[
{
filename: 'anglerite.png',
path: '/home/joel/Desktop/Anglerite/img/anglerite.png'
}
]
};
transporter.sendMail(mailOptions, function (err, info) {
if(err)
console.log(err)
else
console.log(info);
});
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Required meta tags always come first -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="node_modules/bootstrap/dist/css/bootstrap.min.css">
<link rel="stylesheet" href="node_modules/font-awesome/css/font-awesome.css">
<link rel="stylesheet" href="css/bootstrap-social.css">
<link rel="stylesheet" href="css/styles.css">
<title>Redacted</title>
</head>
<form" class = "col-sm-6" action = "app4.js" method = "POST" >
<div class = "row form-row form-group">
<div class = "col-sm-5">
<input type = "text" class = "form-control-plaintext full-width" id = "name" placeholder = "Your name here">
</div>
<div class = "col-sm-2">
</div>
<div class = "col-sm-5 widen-slightly">
<input type = "text" class = "form-control-plaintext full-width" id = "staticEmail" placeholder = "email#example.com">
</div>
</div>
<div class = "row form-row form-group">
<div class = "col-sm-12 widen-slightly">
<input type = "text" class = "form-control-plaintext full-width" id = "phone" placeholder = "Phone number with area code">
</div>
</div>
<div class = "row form-row form-group">
<div class = "col-sm-12 widen-slightly">
<input type = "text" class = "form-control-plaintext full-width" id = "subject" placeholder = "Subject">
</div>
</div>
<div class = "row form-row form-group">
<div class = "col-sm-12 widen-slightly">
<textarea rows = "6" class = "form-control-plaintext full-width" id = "Description" placeholder = "Description"></textarea>
</div>
</div>
<div class = "row form-row form-group">
<label class = "col-sm-3 col-form-label" >Any Photos</label>
<div class = "col-sm-7">
<input type = "file" class = "form-control-file full-width" id = "">
</div>
<div class = "cl-sm-2">
<button type="submit" class="btn btn-default" id = "submit">Submit</button>
</div>
</div>
</form>
EDIT: Chris Happy's answer proposed moving the Javascript from an external file referenced only by the action property, to references to a in the same page.
I suspect you are redirecting to your script file rather than running the code on submit.
In other words, your form looks something like this:
<form action"script-file.js" method="GET">
<input type="text" value="Some text">
<input type="submit" value="Save">
</form>
However, that will redirect to your script file and it will display on the browser as plain text.
Instead, display your form and code like this:
<form id="myForm" action="/" method="GET">
<input type="text" value="Some text">
<input type="submit" value="Save">
</form>
<!-- Use: <script src="myscripts.js"></script> or -->
<script>
const myForm = document.getElementById('myForm');
myForm.addEventListener("click", () => {
var nodemailer = require('nodemailer');
var transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
user: 'redacted',
pass: 'redacted'
}
});
const mailOptions = {
from: 'redacted',
to: 'redacted',
subject: 'hey',
text: 'text',
html: '<p>Your html here</p>',
attachments: [{
filename: 'anglerite.png',
path: '/home/joel/Desktop/Anglerite/img/anglerite.png'
}]
};
transporter.sendMail(mailOptions, function(err, info) {
if (err)
console.log(err)
else
console.log(info);
});
});
</script>
The outcome of the scripts below is to have the HTML call the Java file, and have that Java file execute with the text that was extracted from the HTML text-boxes. I've made sure the API's (servlet, APEX) are correctly installed.
Java
import java.io.*;
import javax.servlet.ServletException;
import javax.servlet.http.*;
#SuppressWarnings("serial")
public class webConnAPI extends HttpServlet {
#Override
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
User temp = new User();
temp.setfname(request.getParameter("fname"));
temp.setlname(request.getParameter("lname"));
temp.setEmail(request.getParameter("email"));
temp.setPword(request.getParameter("pword"));
EmailServer addUser = new EmailServer();
addUser.Users.add(temp);
}
JavaScript Function Called by the button
<script>
function addData(){
try{
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
var data = xhr.responseText;
alert(data);
}
}
xhr.open('GET', 'webConnAPI', true);
xhr.send(null);
}catch(Excetpion){
alert('didnt work');
}
}
</script>
HTML
The Text boxes and the buttons.
<form name="form" action="${pageContext.request.contextPath}/webConnAPI" method="post">
<fieldset>
<legend>
<h2>
<!--Not Useful to Question-->
</h2>
</legend>
<div class="separator"></div>
<p>
<!-- not Important to Question-->
</p>
<p>
<label>Email</label>
<input type = "text"
id = "email"
value = "Email"
name = "email"/>
</p>
<p>
<label>Password</label>
<input type = "password"
id = "pword"
value = "password"
name = "pword"/>
</p>
<p>
<label>First Name</label>
<input type = "text"
id = "fname"
value = "First Name"
name = "fname"/>
</p>
<p>
<label>Last Name</label>
<input type = "text"
id = "lname"
value = "Last Name"
name = "lname"/>
</p>
<div>
<button type="submit" id="buttonJoin" onclick="addDate()">Join</button>
</div>
<div>
<button onclick="buttonLogin" type="submit" name="buttonLogin">Login</button>
</div>
<div>
<button onclick="buttonReset" type="reset" nwame="buttonReset">Reset</button>
</div>
</fieldset>
<div id="data"></div>
<div id="showDiv" style="display:none;">Thanks</div>
</form>
I really don't understand the problem and I would be very grateful if I could get some help. Thanks in advance.
<button type="submit" id="buttonJoin" onclick="addDate()">Join</button>
you misspelled addData() method in onClick event of Join Button.
I'm trying to validate my form but when I hit the submit button it always refresh the page and didn't validate anything. So the first process start at the
accountDashboard.blade.php
#section ('content')
<div class = "row">
<div class = "col-xs-12 col-md-8">
<div class = "panel panel-default">
<div class = "panel-heading">
<h2>Account Dashboard</h2>
<hr>
</div>
<div class = "panel-body">
<button type = "button" class = "btn btn-info" id = "register">Register Employee</button>
<button type = "button" class = "btn btn-info" id = "searchEmployee">Search Employee</button>
<div class = "row">
<br>
<div class="col-md-10">
<div class = "panel panel-default">
<div class = "panel-body" style = "height: 500px" id = "accountBottomContainer">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
accountDashboard.blade.php (routes)
Route::get('/accountDashboard',
[
'uses' => '\App\Http\Controllers\AccountController#getAccountDashboard',
'as' => 'account.accountDashboard',
]);
As you can see above I have two button one for the register and searchRegister. For instance I hit #register button the blade template will append it on my second panel-body with the id of #accountBottomContainer. Script below of my javascript.
<script>
$(document).on("click", "#register", function ()
{
$.get("accountRegister", function (data)
{
$("#accountBottomContainer").empty();
$("#accountBottomContainer").append(data);
});
});
</script>
accountRegister.blade.php
This is my blade template that I will append from panel-body which works fine I'm just having problem with the validation.
<form class = "form-vertical" role = "form" method = "post" action = "{{ route ('account.accountRegister') }}">
<div class = "form-group {{ $errors->has('email') ? ' has-error' : '' }}">
<label for = "email" class = "control-label">Email Address</label>
<input type = "text" name = "email" class = "form-control" value = "{{ Request::old('email') ?: '' }}">
#if ($errors->has('email'))
<span class = "help-block">{{ $errors->first('email') }}</span>
#endif
</div>
<div class = "form-group {{ $errors->has('username') ? ' has-error' : '' }}">
<label for = "username" class = "control-label">Username</label>
<input type = "text" name = "username" class = "form-control" value = "{{ Request::old('username') ?: '' }}">
#if ($errors->has('username'))
<span class = "help-block">{{ $errors->first('username') }}</span>
#endif
</div>
<div class = "form-group {{ $errors->has('password') ? ' has-error' : '' }}">
<label for = "password" class = "control-label">Password</label>
<input type = "password" name = "password" class = "form-control">
#if ($errors->has('password'))
<span class = "help-block">{{ $errors->first('password') }}</span>
#endif
</div>
<div class = "form-group">
<button type = "submit" class = "btn btn-default">Sign Up</button>
</div>
<input type = "hidden" name = "_token" value = "{{ Session::token() }}">
</form>
Controller
public function postRegister(Request $request)
{
//VALIDATION
$this->validate($request, [
//This will be unique in users table
'email' => 'required|unique:users|email|max:255',
'username' => 'required|unique:users|alpha_dash|max:20',
'password' => 'required|min:6',
]);
User::create
([
'username' => $request->input('username'),
'email' => $request->input('email'),
'password' => bcrypt($request->input('password')),
]);
return redirect()->route('account.accountRegister');
}
routes for accountRegister.blade.php
Route::get('/accountRegister',
[
'uses' => '\App\Http\Controllers\AccountController#getRegister',
'as' => 'account.accountRegister',
]);
Route::post('/accountRegister',
[
'uses' => '\App\Http\Controllers\AccountController#postRegister',
]);
<div class="form-group #if($errors->has('username')) has-error #endif">
<label for="username" class="col-sm-2 control-label"></label>
<div class="col-sm-10">
<input type="text" class="form-control" name="username" value="{{ Request::old('username') ?: '' }}" readonly="readonly" />
#if($errors->has('username'))
<span class="help-block">{{ $errors->first('username') }}</span>
#endif
</div>
</div>
i'm new to using javascript plugins to validate data in forms and therefore am having problems. Currently, the first validation works fine and executes the correct jquery, however the second validation for the second section of the form resets the page when valid data is entered.
Here's a jsfiddle to demonstrate the problem:
http://jsfiddle.net/epn63vk3/2/
You can also check out the version with the css fully working at :
http://178.62.85.190/index.html
Javascript:
<script type="text/javascript">
$(document).ready(function () {
$("#buttonToSecondaryDetailsSection").click(function (e) {
$('#primaryDetailsForm').validate({ // initialize the plugin
rules: {
forenameInput: {
required: true,
minlength: 2
},
surnameInput: {
required: true,
minlength: 2
},
emailInput: {
required: true,
email: true
}
}
});
var primaryValid = $('#primaryDetailsForm').valid();
if (primaryValid) {
e.preventDefault();
$("#primaryDetailsForm").slideUp("slow");
$("#secondaryDetailsForm").slideDown("slow");
} else {
}
});
$("#buttonToCommentsSection").click(function (f) {
$('#secondaryDetailsForm').validate({ // initialize the plugin
rules: {
telephoneInput: {
required: true,
minlength: 11,
maxlength: 11
},
genderInput: {
required: true,
},
dobInput: {
required: true,
dateFormat: true
}
}
});
var secondaryValid = $('#secondaryDetailsForm').valid();
if (secondaryValid) {
f.preventDefault();
$("#secondaryDetailsForm").slideUp("slow");
$("#commentsDetailsForm").slideDown("slow");
} else {
}
});
});
Forms :
<div id = "sections">
<div id = "titlePanel">
<p id = "sectionTitle">
Step 1: Your primary details
</p>
</div>
<form id = "primaryDetailsForm" method = "POST">
<label for "forenameInput" id = "labels"> First Name </label>
<br>
<input id = "forenameInput" name = "forenameInput" type = "text" class = "input-block-level">
<br>
<label for "surnameInput" id = "label1"> Surname </label>
<br>
<input id = "surnameInput" name = "surnameInput" type = "text" class = "input-block-level">
<br>
<label for "emailInput" id = "label2"> Email Address:</label>
<br>
<input id = "emailInput" name = "emailInput" type = "email" class = "input-block-level">
<br>
<div id = "registrationButtonWrapper">
<button id = "buttonToSecondaryDetailsSection" class = "btn btn-default"> next > </button>
</div>
</form>
</div>
<div id = "Div1">
<div id = "Div2">
<p id = "P1">
Step 2: Additional details
</p>
</div>
<form id = "secondaryDetailsForm" method = "POST">
<label for "telephoneInput" id = "label3"> Telephone Number </label>
<br>
<input id = "telephoneInput" name = "telephoneInput" type = "number" class = "input-block-level">
<br>
<label for "genderInput" id = "label4"> Gender </label>
<br>
<select id = "genderInput" name="genderInput">
<option value="male"> Male </option>
<option value="female"> Female </option>
</select>
<br>
<label for "dateOfBirthInput" id = "label5"> Date Of Birth </label>
<br>
<input id = "dateOfBirthInput" name = "dobInput" type = "date" class = "input-block-level">
<br>
<div id = "Div3">
<button id = "buttonToCommentsSection" class = "btn btn-default" > next > </button>
</div>
</form>
</div>
Firstly you are adding the validation on each click, you should first check if it was added. Also the date validation looks like its failing. Where is dateFormat from? If you use date it will work.