I am new to node js. i am trying to learn node js. My question is how can we create dynamic webpages using node js?
PHP
<html>
<body>
<?php .......... ?>
</body>
Like in php we can do this way. How can we do in node js.
First off you would start by installing the nodejs framework expressJS
sudo npm install express
For instance, let's say you want to create a form.
<html>
<body>
<head>
This is a simple form
</head>
<body>
<form action="/" method="POST">
<label for="firstName">First Name:</label>
<input name="firstName">
<br>
<label for="lastName">Last Name:</label>
<input name="lastName">
<br>
<button type="submit">send</button>
This what the server side part would look like
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
var urlencodedParser = bodyParser.urlencoded({ extended: false});
// Set EJS View Engine**
app.set('view engine','ejs');
// Set HTML engine**
app.engine('html', require('ejs').renderFile);
//set directory
app.set('views', __dirname + '/views');
//static folder
app.use(express.static('staticfolder'));
app.get('/form', function(req, res) {
//open form.html from the views directory
res.render('form');
});
app.post('/', urlencodedParser, function(req, res) {
//retrieve first and lastname
var firstName = req.body.firstName;
var lastName = req.body.lastName;
//open submitted.html after the user has submitted the form
res.render('submitted', {output: req.body.firstName});
});
app.listen(3000);
Page that will be displayed when user submits the form. It is called submitted.html in this case
<html>
<body>
<p> you have submitted the form </p>
<!--firstname entered by user-->
<p> your first name is <%= output %></p>
</body>
</html>
You need a template to dynamically change its content.
Step 1: Create a server with Express Node.JS Framework.
Step 2: Use EJS(Embedded JavaScript) to create a template.
Follow the instructions bellow:
https://shockoe.com/ideas/development/creating-dynamic-web-pages-ejs/
Related
In this problem, I tried to render ejs after update the data from UI. Here is my code,
const express = require("express");
const bodyParse = require("body-parser");
const date = require(__dirname + "/date.js");
const app = express();
const port = 3000;
app.set("view engine", "ejs");
app.use(bodyParse.urlencoded({ extends: true }));
var path = require('path');
let items = ["Buy Food", "Cook Food", "Eat Food"];
let itemWorks = [];
app.get("/", function (req, res) {
let day = date.getDay();
res.render(path.join(__dirname + "/views/list.ejs"), { listTitle: day, listItem: items });
items.pop;
app.post("/", function (req, res) {
let item = req.body.foodservice;
if(res.body.list === "work"){
itemWorks.push(item);
res.redirect("/work");
}else{
items.push(item);
res.redirect("/");
}
items.push(item);
res.redirect("/");
});
});
Here is my list.ejs:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>To Do List</title>
</head>
<body>
<h1><%=listTitle%></h1>
<ul>
<% for(var i = 0; i < listItem.length; i++){ %>
<li><%=listItem[i]%></li>
<% } %>
</ul>
<form action="/" method="post">
<input type="text" name="foodservice" placeholder="New Item" autocomplete="off"/><br /><br />
<button type="submit" name="button" value=<%=listTitle%>>+</button>
</form>
</body>
</html>
Here is my project's structure:
BRANDNEW_PROJECT views /list.ejs app.js data.js
However, when I have executed it=> errors have been displayed as bellow
TypeError: Cannot read properties of undefined (reading 'list')
at E:\WEB DEVELOPMENT\NodeJS\BrandNew_Project\app.js:25:15
I have tried to debug by putting log to check whether it already points to file that I want or not and the path is correct and also to tried set up file path like this:
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
However, the issues have not been resolved.
What can be the reason here? Thanks a lot for your help.
Live working URL : https://stackblitz.com/edit/node-dmtquz?file=index.js
Views folder is default in EJS.
Concept:
when render html pages you must take care path will start for other inside views as root
when render html pages you must take care path will start for other inside views as root.
Not render views/layouts/index use layout/index because,EJS make views (or your directory) as active directory for it.
if you want to change the directory use app.set("views", path.join(path.resolve(), < dir name >)).
Structure:
views
-------- layouts
---------------- index.ejs (this file i rendered as root)
-------- partials
-----------------footer.ejs, header.ejs etc
Hope this will clear up your problem
var express = require("express");
var app = express();
// set the view engine to ejs
// app.set("views", __dirname + "/views");
app.set("view engine", "ejs");
// use res.render to load up an ejs view file
// index page
app.get("/", function (req, res) {
res.render("layouts/index" , {
displayTitle: "items viewer",
item: ["item1", "item2"]
});
});
// about page
app.get("/about", function (req, res) {
res.render("layouts/about");
});
app.listen(8080);
console.log("Server is listening on port 8080");
<!-- root dir, views/layout/list.ejs -->
<!DOCTYPE html>
<html lang="en">
<body>
<%= displayTitle%>
<hr />
<% for (let i of items) { %>
<br />
<%= i %> <% } %>
</body>
</html>
I think you need to use path.resolve instead of path.join like this:
res.render(path.resolve(__dirname + "/views/list.ejs"), { listTitle: day, listItem: items });
You might also need to update your import of the date object at the top to use path.resolve like this:
const date = require(path.resolve(__dirname + "/date.js"));
In my code I use path.resolve anytime I use __dirname
I've just started learning Node.js and i'm trying to create a web application that returns the form in users.ejs when http://localhost:8083 is entered. What is going wrong here?
./index.js
var express = require("express");
var mysql=require("mysql");
var app = express();
var usersRouter=require('./routes/users');
app.use("/",usersRouter);
var server = app.listen(8083, function(){
var port = server.address().port;
console.log("Server started at http://localhost:%s", port);
});
./routes/users.js
var express=require("express");
var router=express.Router();
router.get('/',function(req,res){
res.render("./views/users");
})
module.exports = router;
./views/users.ejs
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<div class="user-detail">
<h2>Create User Data</h2>
<form action="/users/create" method="POST">
<label>Full Name</label>
<input type="text" placeholder="Enter Full Name" name="fullName" required>
<label>Email Address</label>
<input type="email" placeholder="Enter Email Address" name="emailAddress" required>
<label>City</label>
<input type="city" placeholder="Enter Full City" name="city" required>
<label>Country</label>
<input type="text" placeholder="Enter Full Country" name="country" required>
<button type="submit">Submit</button>
</div>
</div>
</body>
</html>
The view engine for rendering the template file is not configured.
You need to setup the view engine on the app level via app.set method, by setting view engine to ejs :
view engine
String The default engine extension to use when omitted. NOTE:
Sub-apps will inherit the value of this setting.
https://expressjs.com/en/5x/api.html#app.settings.table
so in index.js add this:
app.set('view engine', 'ejs');
also, you need to install ejs
npm i -S ejs
and include it, so your index.js file should look like this
var ejs = require('ejs');
app.set("view engine", "ejs");
Now the view engine is set, but your users router will fail with this error:
Error: Failed to lookup view "./vies/users" in views directory
It's this method here:
res.render("./views/users");
It's now trying to load users template from views/views, i.e. there's an extra view. It's coming from yet another app setting - views, a directory to store and read view templates:
views
String or Array A directory or an array of directories for the
application's views. If an array, the views are looked up in the order
they occur in the array
Default: process.cwd() + '/views'
https://expressjs.com/en/5x/api.html#app.settings.table
It's configured by setting the views path on the app level, like so:
app.set('views', path.join(__dirname, 'views'));
And as you can see, it's already set to process.cwd() + '/views' by default, so it's optional, which means that's where that extra view is coming from, so you just need to remove views/ in the users router, so it'll pick it up from the root by default:
res.render("./users");
Final code:
./index.js
var express = require("express");
var app = express();
// load ejs template renderer
var ejs = require("ejs");
// register the given template engine
app.set("view engine', 'ejs");
// optional, as it defaults to process.cwd() + '/views'
// needs path too:
// var path = require("path");
//app.set("views", path.join(__dirname, "views"));
var usersRouter = require("./routes/users");
app.use("/", usersRouter);
var server = app.listen(8083, function() {
var port = server.address().port;
console.log("Server started at http://localhost:%s", port);
});
./routes/users.js
var express=require("express");
var router=express.Router();
router.get('/',function(req,res){
res.render("./users");
})
module.exports = router;
Check Express guide and examples here:
https://expressjs.com/en/starter/examples.html
Folder list
Hi, I'm new to node, express and ejs; this is a folder list of my project and for some reason when I include the header and footer on home.ejs, I can see the image on the navbar, but if I do the same in terms-condition.ejs, node load the page correctly with the footer and the navbar, but the logo-image isn't shown in the page.
The only difference between home.ejs and terms-condition.ejs is that the last one is in a subfolder of /views.
index.ejs
const express = require("express");
const bodyParser = require("body-parser");
const app = express();
app.set("view engine", "ejs");
app.use(bodyParser.urlencoded({extended: true}));
app.use(express.static("public"));
app.get("/", function(req, res) {
res.render("home");
});
app.get("/legal/terms-condition", function(req, res) {
res.render("legal/terms-condition");
});
app.listen(3000, function(){
console.log("Server started on port 3000.");
});
home.ejs
<%- include("common/header") -%>
<div class="box">
Terms and Condition
</div>
<%- include("common/footer") -%>
terms-condition.ejs
<%- include("../common/header") -%>
<div class="container">
<div class="row">
<div class="col-6">
<h1>This is a sample</h1>
</div>
<div class="col-6">
<p>Why ejs not load the logo in the navbar?</p>
</div>
</div>
</div>
<%- include("../common/footer") -%>
here the link to my project on GitHub
You need to prefix the images/Stack_Overflow_icon.svg with / i.g. /images/Stack_Overflow_icon.svg. In your code, did you notice that the styles.css loading correctly because you've prefix it with /.
You're facing this issue because the file terms-condition.ejs is within a folder whereas home.ejs not.
P.S. You should always put node_modules in .gitignore file.
Not able to handle post request data using express in Node.js. I want to handle form data from index.html file in test.js file. Getting error:
POST /test" Error (404): "Not found"
Following is the code which I have written:
index.html
<html>
<body>
<form action="/test" method="POST">
Name: <input type="text" name="name"/>
<input type="submit" value="Submit"/>
</form>
</body>
</html>
test.js
var express = require("express");
var bodyParser = require('body-parser');
var app = express();
var urlEncodedParser = app.use(bodyParser.urlencoded({ // to support URL-encoded bodies
extended: false
}));
app.post('/test',urlEncodedParser, function(req,res){
console.log("Kushagra "+req.body);
});
app.listen(8080,function(){
console.log("Started in port 8080");
});
What to be done in order to receive form data from index.html file to test.js file.
// TODO: Place this code before route & put index.html to public directory
const path = require("path");
app.use(express.static(path.join(__dirname, "public")));
I am trying to write a login page . i got the html page with the login box
im enter email and password than submit to server , on server i got route who get the data check on db if doc exists , if its exists should redirect to main page
the problem is the data i send from form to server always undefined i check here on other ppl questions and i didnt find any good result for this
html login page :
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="/css/style.css" />
<title>{{PageTitle}}</title>
</head>
<body>
{{> header}}
<div class="login-box">
<div class="form">
<form action="/get_user" method="post" class="login-form">
<input type="email" name="Email" placeholder="Email"/>
<input type="password" name="Password" placeholder="Password"/>
<button type="submit">login</button>
</form>
</div>
</div>
{{> footer}}
</body>
server code :
const _ = require('lodash');
const express = require('express');
const bodyParser = require('body-parser');
const {mongoose} = require('./db/mongoose');
const hbs = require('hbs');
var {User} = require('./models/user');
var app = express();
app.set('view engine', 'hbs');
const port = process.env.PORT;
hbs.registerPartials(__dirname + '/../views/partials');
app.user(bodyParser.json());
app.use(express.static(__dirname + '/../public'));
app.use(express.static(__dirname + '/../public/images'));
app.use(express.static(__dirname + '/../public/fonts'));
app.listen(port, () => {
console.log(`Started on port ${port}`);
});
app.get('/', (req, res) => {
res.render('login.hbs', {
PageTitle: 'Log In',
ConnectUser: 'Guest'
});
});
app.post('/get_user', (req, res) => {
var body = _.pick(req.body, ['Email , 'Password']);
User.findOne({
Email: body.Email,
Password: body.Password
}).then((user) => {
console.log(body.Email + ' ' + body.Password);
if(!user) {
return res.status(404).send();
}
var fullName = user.First_Name + ' ' + user.Last_Name;
res.redirect('/mainPage', {ConnectUser: fullName});
}).catch((e) => {
res.status(400).send();
});
});
i did few checks and when i call /get_user req.body->var body -> user r empty
the data arnt pass from form to server im also check this route on postman and its work find when i write the body by myself the only problem i can think is the data i send from form arnt send as json and the body parser send only in json format so maybe i need to change the line
app.use(bodyParser.json());
if any 1 can put in the right direction ill appraise that ty.
When using an html form with method post, the data is posted to the server withContent-Type: application/x-www-form-urlencoded instead of JSON.
Json bodyparser will not do anything with that, as its not using JSON format to send the data. See MDN guide under post method.
In your server code, below app.use(bodyParser.json()) add the following:
app.use(bodyParser.urlencoded({extended: true}));
This will add the data onto the request body the way you expect.
Try playing with the form enc-type attribute and see how to configure the bodyparser to get the values you need based on the enc-type.
application/x-www-form-urlencoded
multipart/form-data
https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/enctype