I am trying to create a calculator app using express.js to get request for an html file and a post request that takes the user's input and responds with the answer. However, I want to display my answer inside a html container without the page redirecting. Is there a way to achieve this with vanilla javascript?
index.html
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="stylesheet" href="styles.css" />
<link rel="shortcut icon" href="#" />
<title>Calculator</title>
</head>
<body>
<h1>Calculator App</h1>
<form action="/" method="post" class="ajax">
<label for="userInput">Enter Equation</label>
<input type="text" id="equation" name="equation" />
<button type="submit" id="btn_submit">Calculate</button>
</form>
<div class="container"></div>
</body>
</html>
app.js
const express = require('express');
const app = express();
port = 3000;
app.use(express.urlencoded({ extended : false }));
app.use(express.static('public'));
app.get('/', (req, res) => {
res.sendFile(__dirname + public);
});
app.post('/', (req, res) => {
let equation = req.body.equation;
console.log(equation);
let result = eval(equation);
res.status(200).send('Result is ' + result);
});
app.listen(port, ()=> {
console.log('Hosted on port: ' + port);
});
CalculatorApp
Evaluated Expression
You will need to write front end JavaScript code to make the ajax request instead of having the form action submit the request. The JavaScript will receive the response and can update the value on the HTML.
app.post('/', (req, res) => {
let equation = req.body.equation;
console.log(equation);
let result = eval(equation);
res.status(200).json({ value: `Result is ${result}` });
});
<script>
document.querySelector('form').addEventListener('submit',submitEquation);
function submitEquation(event){
event.preventDefault();
const input = document.querySelector('#equation');
const equation = input.value;
const clearInput = true;
if(clearInput){
input.textContent = '';
}
fetch(window.location.origin, {
method: 'post',
body: JSON.stringify({ equation })
})
.then(response => response.json())
.then(json => {
document.querySelector('.container').textContent = json.value;
})
}
</script>
Related
I'm following this link for the tutorial (via twilio.) and have followed all the
required steps but when I run the localhost and input a number, I get no text message, nor does the window for verification open. It just stays at the same page of "enter your phone number".
Here's my HTML code
<!DOCTYPE HTML>
<HTML>
<head>
<title>Verify SMS Demo</title>
<style>
#verify-form,
#response-text {
display: none;
}
</style>
</head>
<body>
<form id="phone-form">
<h2>Enter your phone number with country code:</h2>
<input type="tel" id="phone-number-input" placeholder="15551235555" />
<input id="phone-submit" type="submit" />
</form>
<form id="verify-form">
<h2>Enter your verification code:</h2>
<input type="number" id="otp-input" placeholder="e.g. 123456" />
<input id="verify-submit" type="submit" />
</form>
<div id="response-text"></div>
</body>
<script type="text/javascript" src = "script.js"></script>
</html>`
And here's my code for script.js:
const phoneForm = document.getElementById('phone-form');
const verifyForm = document.getElementById('verify-form');
const responseText = document.getElementById('response-text');
let phoneNumber;
phoneForm.addEventListener('submit', async e => {
e.preventDefault();
phoneNumber = document.getElementById('phone-number-input').value;
const response = await fetch('/send-notification', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({phoneNumber : phoneNumber })
}).catch(e => console.log(e));
if (response.ok) {
phoneForm.style.display = 'none';
verifyForm.style.display = 'block';
}
});
verifyForm.addEventListener('submit', async e => {
e.preventDefault();
const otp = document.getElementById('otp-input').value;
const data = {
phoneNumber: phoneNumber,
otp: top
};
const response = await fetch('/verify-otp', {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' },
body: JSON.stringify(data)
}).catch(e => console.log(e));
const check = await response.json();
const text = response.ok ? check.status : response.statusText;
responseText.innerHTML = text;
verifyForm.style.display = 'none';
responseText.style.display = 'block';
});
EDIT Here is my index.js file:
const express = require('express');
const path = require('path');
require('dotenv').config();
const client = require('twilio')(process.env.TWILIO_ACCOUNT_SID, process.env.TWILIO_AUTH_TOKEN);
const app = express();
const port = process.env.PORT || 3000;
app.use(express.static(__dirname + '/public'));
app.use(express.urlencoded({extended: true}));
app.use(express.json());
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname, '/views/index.html'));
});
app.post('/send-verification', async (req, res) => {
client.verify.services(verify)
.verifications
.create({to: `+${req.body.phoneNumber}`, channel: 'sms'})
.then(verification => console.log(verification.status))
.catch(e => {
console.log(e)
res.status(500).send(e);
});
res.sendStatus(200);
});
app.post('/verify-otp', async (req, res) => {
const check = await client.verify.services(verify)
.verificationChecks
.create({to: `+${req.body.phoneNumber}`, code: req.body.otp})
.catch(e => {
console.log(e)
res.status(500).send(e);
});
res.status(200).send(check);
});
app.listen(port);
console.log('Server started at http://localhost:' + port);
Your front-end is making a request to /send-notification but your application end point is at /send-verification.
Update your front-end code to:
const response = await fetch('/send-verification', {
and you should be good to go.
Edit
Now, in the server you are getting the error:
sh-3.2$ node index.js Server started at localhost:3000
/Users/username/Downloads/keep_out-3/verify-sms-express/index.js:17
client.verify.services(verify)
^ ReferenceError: verify is not defined
You have the line:
const check = await client.verify.services(verify)
In the blog post this is:
client.verify.services(process.env.VERIFY_SERVICE_SID);
So, you have replaced the verify service sid with a non-existant verify variable. Go back and make sure you have VERIFY_SERVICE_SID set in your .env file and then change the code back to the original, and then you should be good to go!
I'm trying to build a login page for users and need to send the login info to my express server. I'm not too sure about how to call the api for my server and send the information across though.
Right now I get a 405 error method not allowed when I try to submit the form by clicking on the button.
index.html:
<!DOCTYPE html>
<html land="en">
<head>
<meta charset="UTF-8">
<title>Home page</title>
<script src="../app.js"></script>
</head>
<body>
To login
</body>
</html>
login.html:
<!DOCTYPE html>
<html land="en">
<head>
<meta charset="UTF-8">
<title>Login page</title><br><br>
<script src="../app.js"></script>
</head>
<body>
<form id="login-form" method="post" action="/login">
<input type="text" name="username" id="username-field" placeholder="Username" required><br><br>
<!-- TODO: Change type to "password" -->
<input type="text" name="password" id="password-field" placeholder="Password" required><br><br>
<input type="submit" value="Login" id="login-form-submit">
</form>
</body>
</html>
app.js:
const express = require('express')
var bodyParser = require('body-parser')
var port = process.env.PORT || 3000;
var app = express();
app.use(express.json());
app.use(express.urlencoded({"extended": true}));
app.get('/', function (req, res) {
res.render(__dirname + '/views/index.html');
});
app.post('/login', function (req, res) {
res.statusCode = 200;
res.send({ 'body': req.body });
});
// Listen on port 3000, IP defaults to 127.0.0.1
app.listen(port, () => {
console.log('Server listening at http://127.0.0.1:' + port + '/');
});
You can do it using javascript. Add this to your login.html file
<script type="text/javascript" >
async function login(){
// Get values from FORM
let username = document.getElementById("username-field")
let password = document.getElementById("password-field")
// Body payload
let body = { username, password }
// Fetch options
let option = {
method: 'POST',
body: JSON.stringify(body),
headers: {
'Content-Type': 'application/json'
}
}
// Call /login as POST and wait for reply
const response = await fetch(`/login`, options)
const json = await response.json()
// Use json response
alert(json)
}
document.getElementById("login-form-submit").addEventListener("click", login);
</script>
In order for the server to be properly up, you need to make sure you run it as node app.js instead of adding it to the html file.
UPDATE:
Check out this repo for a working solution : https://github.com/rui-costa/stackoverflow-68238492
Please educate me about how am I going to connect the CSS to the server. I've followed two tutorials on youtube, one is using node.js and nodemailer. With this, I use a localhost to run my website but the CSS and js I made from the second tutorial (pop-up when button is clicked) won't work on the localhost but when I clicked the html file itself.
Is this because the tutorials are for different kinds of website? like static and dynamic?
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewpoint" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link href="style.css" rel="stylesheet" type="text/css" />
<title>Document</title>
</head>
<body>
<h1>Welcome to my App</h1>
<form>
<div>
<label for="email">Sender's Email: </label>
<input type="email" id="email" placeholder="Your Email"> <br>
</div>
<div>
<label for="classNum">To whom: R</label>
<input type="number" id="classNum" placeholder="class#" min="1" max="31"> <br>
</div>
<div>
<label for="subject">Subject: </label>
<input type="text" id="subject" placeholder="Subject"> <br>
</div>
<div>
<label for="text">Letter: </label> <br>
<textarea name="text" id="text" cols="30" rows="10"></textarea> <br>
</div>
<input type="submit" value="Submit" class="modal-button" data-modal-target="#modal">
<div class="modal" id="modal">
<div class="modal-header">
<div class="title">Letter Sent!</div>
</div>
<div class="modal-body">
Pressing this button will refresh the page.
<div><button data-close-button class="refresh-button">Send another letter</button></div>
</div>
</div>
<div id="overlay"></div>
</form>
<script src="script.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
$('form').on('submit', (e) => {
e.preventDefault();
const email = $('#email').val().trim();
const subject = $('#subject').val().trim();
const text = $('#text').val().trim();
const classNum = $('#classNum').val().trim();
const data = {
email,
subject,
text,
classNum
};
$.post('/email', data, function(){
console.log('Server received our data')
});
});;
</script>
</body>
</html>
This is the server.js
const express = require('express');
const sendMail = require('./mail')
const log = console.log;
const app = express();
const path = require('path');
const PORT = 8080;
app.use(express.urlencoded({
extended: false
}));
app.use(express.json());
app.post('/email', (req, res) => {
const { subject, email, text, classNum} = req.body;
console.log('Data: ', req.body);
sendMail(email, subject, text, classNum, function(err, data){
if (err){
res.status(500).json({ message: 'Internal Error'});
}
else{
res.json({ message: 'Email sent!' });
}
});
// res.json({ message: 'Message received!' })
});
app.get('/', (req, res) =>{
res.sendFile(path.join(__dirname, 'views', 'index.html'));
});
app.listen(PORT, () => log('Server is starting on PORT: ', 8080));
And this one is for the pop-up, script.js
const openModalButtons = document.querySelectorAll('[data-modal-target]');
const closeModalButtons = document.querySelectorAll('[data-close-button]');
const overlay = document.getElementById('overlay');
var path = require('path') //from stackoverflow
app.use(express.static(path.join(__dirname, 'public')));
openModalButtons.forEach(button => {
button.addEventListener('click', () => {
const modal = document.querySelector(button.dataset.modalTarget)
openModal(modal)
})
})
closeModalButtons.forEach(button => {
button.addEventListener('click', () => {
const modal = button.closest('.modal')
closeModal(modal)
})
})
function openModal(modal) {
if (modal == null) return
modal.classList.add('active')
overlay.classList.add('active')
}
function closeModal(modal) {
if (modal == null) return
window.open("https://www.w3schools.com");
}
Please tell me if I need to include the CSS and the mail.js .
If you want to allow users or browsers to get files from your server, you need to add them to your server-side code. For example, you've added a stylesheet reference to your index.html, so the browser will try to get that file (/style.css) from the server. You haven't put any reference to this on the server side, so the server will respond with 404 Not Found or another error.
In order to make the server respond to a request for "/style.css", you need to add the following to your server-side index.js:
app.get("/style.css" /*name of file in index.html*/, (req, res) => {
res.sendFile(path.join(__dirname, 'views', 'style.css')); //CHANGE THIS TO THE NAME OF THE FILE ON THE SERVER
});
The same needs to happen for your browser script, script.js:
app.get("/script.js" /*name of file in index.html*/, (req, res) => {
res.sendFile(path.join(__dirname, 'views', 'script.js'));
});
app.get tells express to respond to a GET request to the first parameter: in the example, that's "/style.css". If you wanted to respond to a GET request to "/foobar", then you would write app.get("/foobar", (req, res) => {/*SOME CODE HERE*/}); . The reason why it wasn't working was becuase when the browser tried to find style.css and script.js, the server didn't know what to do because you hadn't included app.get for those files, and therefore responded with an error.
This might be confusing due to the architecture of how this works. Look at this diagram:
==== HOW A WEBSITE SENDS A FILE ====
______ ____ ______
/ . . \ GET /file [____] READ / |
| j | ======> [____] ======> | file |
\__===_/ <====== [____] <====== | |
user RESPONSE server |_______|
When I click the subscribe button it redirects my page to 127.0.0.1 and nothing appears in console.log. Why is that
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Abonelik</title>
<link rel="stylesheet"
href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T"
crossorigin="anonymous">
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"
integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM"
crossorigin="anonymous"></script>
<link rel="stylesheet" href="signin.css">
</head>
<body>
<div class="parent-wrapper">
<span class="close-btn glyphicon glyphicon-remove"></span>
<div class="subscribe-wrapper">
<h4>Abone Olun</h4>
<form action="/" method="POST">
<input type="text" name="fname" class="subscribe-input" placeholder="Adınız">
<input type="text" name="lname" class="subscribe-input" placeholder="Soyadınız">
<input type="email" name="email" class="subscribe-input" placeholder="Mail Adresiniz">
<button type="submit">Abone Ol</button>
</form>
</div>
</div>
</body>
</html>
Nodejs
//jshint esversion:6
const express = require("express");
const bodyParser = require("body-parser");
const request = require("request");
const https = require("https");
const app = express();
app.use(express.static("public"));
app.use(bodyParser.urlencoded({
extended: true
}));
app.get("subs", function(req, res) {
res.sendFile(__dirname + "/signup.html");
});
app.post("/", function(req, res) {
const mail = req.body.email;
const ilkad = req.body.fname;
const soyad = req.body.lname;
console.log(fname, lname, email);
const data = {
members: [{
email_address: mail,
status: "Subscribed",
merge_fields: {
FNAME: fname,
LNAME: lname,
}
}]
};
const jData = JSON.stringify(data);
const url = "https://usX.api.mailchimp.com/3.0/lists/";
const option = {
method: "post",
auth: ""
};
const request = https.request(url, options, function(response) {
response.on("data", function() {
console.log(JSON.parse(data));
});
});
request.write(jData);
request.end();
});
app.listen(3000, function() {
console.log("Server Çevrimiçi");
});
I just wanted to apply the subscribe button a function to send data to the hyper terminal when the user logs mail name surname etc. but when I click it redirects me to 127.0.0.1 which is local folder. and I am almost sure that there is something wrong between app.get and form direction but I don't know how to solve this problem. I know it is a long post sorry for that but I really appreciate some help. thank you.
You are printing the wrong variables. Since you do this:
const mail = req.body.email;
const ilkad = req.body.fname;
const soyad = req.body.lname;
you should print the data from request by:
console.log(ilkad, soyad, email);
Also, a good practice is using the object destructuring like this:
const {email, fname, lname} = req.body
and then use:
console.log(fname, lname, email);
I am building a simple web application with HTML, CSS and postgreSQL.
I am building a web back end using Node.js, and trying to store app data using a SQL database. The form collects comments from user, stores in database and also displays the comments in the html. I keep getting an error in my code.
<!DOCTYPE html>
<html>
<head>
<title>Editor</title>
<link rel="stylesheet" href="stylesheets/stylesheet.css">
<link rel="shortcut icon" href="">
</head>
<body>
<div id="commentNav" contenteditable="true">
<h1>Comments</h1>
<form action="/comments" method="POST">
<input type="text" name="name" placeholder="First Name"/>
<textarea rows="4" name="comment">Describe your favorite</textarea>
<input type="submit" value="Submit"/>
</form>
<section id="suggestions">
<h2>Comment List</h2>
</section>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="javascripts/script.js"></script>
</body>
</html>
Script.js
getComments();
function getComments(){
$.get("/comments", function(data){
if(!data){
console.log("No data recieved");
}
console.log("recieved data:");
for(let i = 0; i < data.length; i++){
console.log(data[i].name);
}
showComments(data);
});
}
function showComments(comments){
let commentSection = document.getElementById("suggestions");
// for(let i = 0; i < comments.length; i ++){
for (let i in comments){
let section = document.createElement("section");
section.className += "suggestion";
let heading = document.createElement("h3");
heading.innerHTML = comments[i].name;
let comment = document.createElement("p");
comment.innerHTML = comments[i].comment;
section.appendChild(heading);
section.appendChild(comment);
commentsSection.appendChild(section);
}
}
Server.js
const express = require('express');
let pg = require('pg');
let pg = new pg.Database('db/comments.db');
const app = express();
const PORT = 8080;
app.use(express.static('public'));
app.get('/', (req, res) => {
res.sendFile('index.html', { root: path.join(__dirname, './files') });
});
app.listen(PORT, () => {
console.log(`Example app listening on port ${PORT}!`);
});
app.get('/comments', function(request, response){
console.log("GET request recieved at /comments");
db.all('SELECT * FROM comments', function(err, rows){
if(err){
console.log("Error: " + err);
}
else{
response.send(rows);
}
})
});
app.post('/comments', function(request, response){
console.log('POST request recieved at /comments');
});
Error:
Failed to load resource: the server responded with a status of 404 (Not Found)
Connection to database using node-postgres js module has to be done as following:
const client = new Client({
user: 'dbuser',
host: 'database.server.com',
database: 'mydb',
password: 'secretpassword',
port: 3211,
})
client.connect()
For more info see documentation