How can I get the user inputs from index.html, process in node and output the result back into the index.html? Instead of outputting - as currently does - to a new page.
Form file
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.get('/', function(req, res){
res.sendFile('index.html', { root: __dirname});
app.post('/mess', function(req, res){ //means same dir
var userNum1 = req.body.num1;
var userNum2 = req.body.num1;
var answer = parseInt (userNum1) + parseInt (userNum2);
res.send ('The answer is ' + answer);
});
app.listen(80);
index.html
<!DOCTYPE html>
<html>
<head>
<title>Forms></title>
</head>
<body>
<form action="mess" method="post">
<p>Enter a number:</p>
<input type="text" name="num1" placeholder="..." />
<br>
<p>Enter a number:</p>
<input type="text" name="num2" placeholder="..." />
<br>
<button type="submit">Submit</button>
<br>
</form>
</body>
</html>
Probably the easiest way is to use ejs.
First npm install ejs. Then add this to your Express app code:
app.set('view engine', 'ejs');
// this allows you to render .html files as templates in addition to .ejs
app.engine('html', require('ejs').renderFile);
In your route handler you just do something like:
res.render('form', { answer: 'foo' });
and then your template (e.g. ./views/form.html) would look like:
<html>
<p> The answer is <%= answer %> </p>
</html>
An alternative to the EJS is to use socket.io. You can attach an event handler to each entry, or to the submit button and then use socket.io to send it from client to server, process it and have it sent back. Then you page can update on receiving the data from the server.
Related
This is a simple calculator that can add numbers.
The html form loads correct to the browser but then once I submit the form, I get a 404 error code
Error code : Cannot POST /index.html
index.html:
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>Calculator</title>
</head>
<body>
<h1>Calculator</h1>
<form action="index.html" method="post">
<input type="text" name="num1" placeholder="First Number">
<input type="text" name="num2" placeholder="Second Number">
<button type="submit" name="submit">Calculate</button>
</form>
</body>
</html>
calculator.js :
//jshint esversion:6
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.urlencoded({extended: true}));
//sending response
app.get("/",function(req, res){
res.sendFile(__dirname + "/index.html");
});
//post
app.post("/",function(req,res){
var num1 = Number(req.body.num1);
var num2 = Number(req.body.num2);
var result = num1 + num2;
res.send("The result is: "+result);
});
//listen to port 3000
app.listen(3000, function(){
console.log("Server listening on port 3000");
});
In your express server you are expecting the post calls to / and you are telling the form that has to send the form-data to index.html.
That means your form will be sending data to http://localhost:3000/index.html instead of http://localhost:3000/.
You should change action="index.html" to action="/".
so I've been doin this bmiCalculator where I enter 2 numbers and these 2 numbers are calculated in my server and the answer is displayed but I have been facing troubling in receiving my output.when I click submit i am getting a list of all my files in the index of c but not the answer. Can someone please help me w this?
my HTML code
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<h1>BMI calculator</h1>
<form action="/" method="post">
<input type="text" name="num1">
<input type="text" name="num2">
<input type="button" value="submit">
</form>
</body>
</html>
my js code
let express = require("express")
let bodyParser = require("body-parser")
let app = express()
app.use(bodyParser.urlencoded({extended: true}))
app.listen(3000,function(){
console.log("working")
})
app.get('/',function(request,respond){
respond.sendFile(__dirname+"/bmiCalculator.html")
})
app.post('/',function(req,res){
let num1 = Number(req.body.num1)
let num2 = Number(req.body.num2)
let result = num1/num2*num2
res.send(result)
})
According to Express res.send([body]) docs:
The body parameter can be a Buffer object, a String, an object, or an Array
You can't send a number by itself. So you could send a string using result.toString()
You should use <input type="submit" value="submit"> to submit the form.
E.g.
server.js:
let express = require('express');
let bodyParser = require('body-parser');
let app = express();
app.use(bodyParser.urlencoded({ extended: true }));
app.listen(3000, function() {
console.log('working');
});
app.get('/', function(request, respond) {
respond.sendFile(__dirname + '/bmiCalculator.html');
});
app.post('/', function(req, res) {
console.log(req.body);
let num1 = Number(req.body.num1);
let num2 = Number(req.body.num2);
let result = (num1 / num2) * num2;
res.send(result.toString());
});
bmiCalculator.html:
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<h1>BMI calculator</h1>
<form action="/" method="post">
<input type="text" name="num1">
<input type="text" name="num2">
<input type="submit" value="submit">
</form>
</body>
</html>
Server logs after submit the form in client-side:
working
{ num1: '1', num2: '2' }
This is my function to fetch data:
let a = showbtn.addEventListener('click',function(){
list.innerHTML='';
fetch('http://localhost:3000/products')
.then ( response =>response.json())
.then( data => {
data.forEach( product => {
let li =document.createElement('li');
li.textContent=` ${product.id} - ${product.name} - $ ${product.price} `;
list.appendChild(li);
});
})
})
My App.js looks like this:
let express=require('express');
app=express();
//after completing index.html we set index.html as a home page like this by introducing public client folder:
app.use(express.static('public'));
productsArray=[];
//every products must have an id number:
let id=1;
app.use(express.json());
//showing all products:
app.get('/products',(req,res)=>{
res.send(productsArray);
})
//creating ptoducts(posts):
app.post('/products',(req,res)=>{
let newProduct=req.body;
newProduct.id=id;
id++;
productsArray.push(newProduct);
res.send('new product created by newProduct=req.body and added to array by push method: Array.push(newProduct)')
})
This is my HTML file:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>shop</title>
</head>
<body>
<h1>shop</h1>
<h2>show all products</h2>
<button class="show-products">show</button>
<!-- //everyl ist item is a separate product -->
<ul class="product-list"></ul>
<!-- //.................................................................... -->
<h2>add product</h2>
<form class="add-product-form">
<p>
<label for="add-product-name">
product:
</label>
<input id="add-product-name" type="text" >
</p>
<p>
<label for="add-product-price">
price:
</label>
<input id="add-product-price" type="text" >
</p>
<button>add</button>
</form>
<script src="js/script.js"></script>
</body>
</html>
The problem is that when i open chrome on localhost:3000 and type something in the field of products and price after that i click show button but i get this result something like this:
1 - undefined - $ undefined
the first one is it's id and the second is product name but is undefined and price as well. I think something is wrong with value but i can't solve this problem.
Thank you in advance.
When handling POST bodies in express you need to user body-parser
http://expressjs.com/en/resources/middleware/body-parser.html
npm install body-parser
var bodyParser = require('body-parser')
Code from the docs
var express = require('express')
var bodyParser = require('body-parser')
var app = express()
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))
// parse application/json
app.use(bodyParser.json())
in the js file remove the semicolon and replace it with comma
Thanks for reading, hopefully my presentation is clear to the reader and aptly shows my lack of understanding. I am very new to node.
I am using node.js with eonasdan datetime.
The problem I need to solve is to print epoch time from console.log in epoch.js from a date sent by a button click in epoch.ejs. Epoch.ejs is viewed in a browser and the html/ejs code easily shows an alert with the epoch in it.
But I am having troubles sending the data back to be printed out from console.log in epoch format (1548694980). I can only print it out in console.log in this format: 01/28/2019 12:03 PM
I do not care if I convert it in the epoch.ejs or in epoch.js.
At present, when I capture the date in the ejs file, and use body-parser to send it to the node epoch.ejs file.
I believe rightly or perhaps wrongly that he format is available within the javascript function. One solution may be to use a global variable and get this into the body. Some attempts have a failed. Described below.
Putting this at the top of the script in the html has caused the datetimepicker to be unable to display the initial date. So making a global variable in javascript has a conflice which I cannot find:
var start = $('#dateTimeStart').data('DateTimePicker').date().unix()
alert(start)
The node.js code (started with 'node epoch.js'):
//setup
var express = require('express'),
app = express(),
bodyParser = require('body-parser'),
path = require('path')
app.set('view engine','ejs');
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())
app.use(express.static(path.join(__dirname, 'public')));
app.get("/", function(req, res, next){
res.render("epoch")
});
app.post("/postDateTimeStart", function(req, res, next) {
console.log(req.body.start);
times(req.body, res);
);
pp.get('/getJson', function (req, res) {
// If it's not showing up, just use req.body to see what is actually being passed.
console.log(req.body.selectpicker);
});
function times(parms, res){
//get parms based on input name attribute from html and parse
var startTime = parms.dateTimeStart;
var dateStart = parms.start
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end("start time: " + startTime);
console.log(startTime, dateStart)
}
app.listen(3000,function(){
console.log("serving test demo on port 3000")
});
The html (ending in ejs):
<!DOCTYPE html>
<header>
<title>Send Epoch to Node Test</title>
<script src="/jquery.js" type="text/javascript"></script>
<script src="/moment.js" type="text/javascript"></script>
<script src="/bootstrap.js" type="text/javascript"></script>
<script src="/bootstrap-datetimepicker.min.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="/bootstrap.css"></link>
<link rel="stylesheet" type="text/css" href="/bootstrap-datetimepicker.css"></link>
<script type="text/javascript">
$(function () {
$('#dateTimeStart').datetimepicker({
daysOfWeekDisabled: [0, 6]
});
});
function getValue() {
var dTstart = $('#dateTimeStart').data("DateTimePicker").date();
if( dTstart ){
/* HOW DO I GET THIS VARIABLE TO BE SEEN BY NODE? */
alert(dTstart.unix());
}
}
$('#dateTimeStart').datetimepicker();
var start = $('#dateTimeStart').data('DateTimePicker').date().unix()
alert(start)
</script>
</header>
<body>
<form action="/postDateTimeStart" method="post">
<div class="col-md-12">
<div class="col-md-1">
<div class="form-group">
<label for="exampleFormControlSelect1">Draw</label>
<p><button onclick="getValue()" type="submit" class="btn btn-custom btn-block">Graph it!</button></p>
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<label for='dateTimeStart'>Start Date-and-Time</label>
<div class='input-group date' id='dateTimeStart'>
<input type='text' class="form-control" name='dateTimeStart' />
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar">
</span>
</span>
</div>
</div>
</div>
</div>
</body>
</html>
Expected results would be in the console log when clicking the button:
1548695940
01/28/2019 12:19 PM 1548695940
Actual results after clicking the button:
undefined
01/28/2019 12:18 PM undefined
Changing the javascript where the alert was previously posted from:
if( dTstart ){
alert(dTstart.unix());
}
to:
if( dTstart ){
document.getElementById("dTstart").value = dTstart.unix();
}
and adding this to the last line of the body:
<input type="hidden" id="dTstart" name="dTstart" value="">
Result as expected:
1548681480 01/28/2019 8:18 AM 1548681480
I have the following express app which just renders the sample.ejs page. On that page when I press the button the attached script changes the div text to
"THIS IS FROM J QUERY. I want the same thing to happen but I want the data to be coming from a database. In my express app if I try to use res.render(); every time I click the button then it reloads the page which I don't want. So is there a way to achieve this without reloading page and only update part of page?
I have searched stack overflow and the web but can't get an appropriate answer or maybe I just am unable to understand. I know this is a very basic thing to ask.
APP.js
var express = require('express');
var app = express();
app.use(express.static('public'));
app.use(express.static('./src/views'));
app.set('views', './src/views');
app.set('view engine' , 'ejs');
app.listen(3000 , (err)=>{console.log('Listening')});
app.get('/' , function(req , res) {
res.render('sample' , {result_from_database: res.body} );
});
sample.ejs
<!doctype html>
<html lang="en">
<head>
<title>Sample HTML File</title>
</head>
<body>
<div id="holder">
WELCOME
</div>
<form>
<button type="button" id="HButton"> HELLO </button>
</form>
</body>
<script>
$(document).ready(function () {
var form = $("#holder");
$("#HButton").on("click", function () {
form.html("THIS IS FROM J QUERY");
});
});
</script>
<script src="/lib/jquery/dist/jquery.js"></script>
</html>
Now this is what I want to do
<!doctype html>
<html lang="en">
<head>
<title>Sample HTML File</title>
</head>
<body>
<div id="holder">
<%= result_from_database %>
</div>
<form>
<button type="button" id="HButton"> HELLO </button>
</form>
</body>
<script>
$(document).ready(function () {
var my_div = $("#holder");
$("#HButton").on("click", function () {
/* Tell app.js that I clicked a button and then app.js
query the database and using ejs or something else update the
my_div inner html with the database result without
reloading page */
});
});
</script>
<script src="/lib/jquery/dist/jquery.js"></script>
</html>
NOTE: I'm not asking how to query the database
-Thanks
You have to define and endpoint in your back end that return the information you want to display:
app.js
var express = require('express');
var app = express();
app.use(express.static('public'));
app.use(express.static('./src/views'));
app.set('views', './src/views');
app.set('view engine' , 'ejs');
app.listen(3000 , (err)=>{console.log('Listening')});
app.get('/' , function(req , res) {
res.render('sample' , {result_from_database: res.body} );
});
app.get('/api/books', function(req, res) {
res.json({
message: 'Your database information'
});
});
then on your front end you need to make a call to api endpoint like:
sample.ejs
<script>
$(document).ready(function () {
var my_div = $("#holder");
$("#HButton").on("click", function () {
$.ajax({
url: "/api/books"
})
.done(function( data ) {
console.log( "Sample of data:", data );
$('#holder').html(data.message);
});
});
});
</script>
You can find more information on ajax call with jquery here.
However i would suggest you to use any framework like angular or react to make it easier to render the data in your html, otherwise you will have to write a lot of code using jquery.