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.
Related
I have server side code which serves up a pug file, the pug file has variables parsed to it when rendered by my server side code.
I would like to be able to update that variable in pug when a check box is checked / unchecked.
my server side code:
// load the express module
const express = require('express');
const simpleVarDisplaySite = 'simpleVarDisplay.pug';
const app = express();
app.use(express.urlencoded({extended: false}))
app.use(express.static(__dirname+'/static'));
// simpleVarDisplaySite page
app.get('/', function (req, res) {
console.log(req.url);
let myHeading = 'Simple Pug Page';
let simpleObject = {
'date': {
'day': 'time'
}
}
res.render(simpleVarDisplaySite, {
heading: myHeading,
pugObject: simpleObject,
});
})
app.listen(8082)
my pug file:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Simple Pug</title>
<link rel="stylesheet" href="/styles/MainStyling.css">
<script src="/scripts/pugVarUpdater.js"></script>
</head>
<body>
<form method="POST">
<div>
<header>
<h1 class="HeaderEl" id="heading">#{ heading }</h1>
</header>
<div>
<input type="checkbox" id="simpleCheckBox" onchange="JavaScript:updatePugVarFunc()">
</div>
<br>
each valueDict, date in pugObject
<div>
<div>
<span>#{date}</span>
</div>
<br>
each time, day in valueDict
<div>
<span>#{day}</span>
</div>
<div>
<span>#{time}</span>
</div>
</div>
</div>
</form>
</body>
</html>
my client-side js when checkbox is checked / unchecked:
function updatePugVarFunc() {
const simpleVarDisplaySite = 'simpleVarDisplay.pug';
let newSimpleObject = {
'new_date': {
'new_day': 'new_time'
}
}
alert(newSimpleObject)
let myNewHeading = 'My New Simple Heading'
alert(myNewHeading)
document.body.innerHTML = simpleVarDisplaySite({
heading: myNewHeading,
pugObject: newSimpleObject,
});
}
I would like to have pug variable: pugObject updated when the checkbox is checked / unchecked onChange event, and see the updates in my browser, which I have tried with:
document.body.innerHTML = simpleVarDisplaySite({
heading: myNewHeading,
pugObject: newSimpleObject,
});
But that does not work.
I know that client-side is handled rather differently from server-side, but I am soo hoping that there is a solution to my specific problem.
Please note that I am a nood with javascript and pug, and I am very open to any and all suggestions to better achieve my goal.
My File structure:
server.js
views
simpleVarDisplay.pug
static
scripts
pugVarUpdater.js
PS:
I have had a look at: use client-side js variable in pug
And that did not help me.
Your assistance and guidance is much appreciated.
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
I am having trouble trying to redirect POST requests using Node.js, Express and angular. I am aware there is a standard way of using forms as follows:
index.ejs
<!DOCTYPE html>
<html>
<head>
<title>Redirect Example</title>
</head>
<body>
<p>INDEX PAGE</p>
<form action="/redirect" method="post">
<button type="submit">CLICK</button>
</form>
</body>
</html>
test.ejs
<!DOCTYPE html>
<html>
<head>
<title>Redirect Example</title>
</head>
<body>
<p>YAY REDIRECTED</p>
</body>
</html>
app.js
var fs = require('fs');
var https = require('https');
var express = require('express');
var bodyParser = require('body-parser');
var cookieParser = require('cookie-parser');
var app = express();
app.set('view engine', 'ejs');
app.get('/', function(req, res) {
res.render('index');
});
app.post('/redirect', function(req, res){
res.redirect('/test');
});
app.get('/test', function(req, res) {
res.render('test');
});
var port = process.env.PORT || 1337;
app.listen(port, function(){
console.log('http://localhost:' + port + '/');
});
This method automatically redirects the page to the "test" route since it uses a form to handle the post request.
However using when I use an angular approach, the page does not automatically redirect. How would I do this?
index.ejs
<!DOCTYPE html>
<html ng-app="project">
<head>
<title>Redirect Example</title>
<script src="/javascripts/jquery/jquery.js"></script>
<script src="/javascripts/angular/angular.js"></script>
<script src="/javascripts/angular/angular-route.js"></script>
<script src="/javascripts/main.js"></script>
</head>
<body ng-controller="MainController">
<button type="submit" ng-click="submit()">CLICK</button>
</body>
</html>
main.js
var app = angular.module('project', []);
app.controller('MainController', ['$scope', '$http', function ($scope, $http) {
$scope.submit = function() {
$http.post('/redirect');
}
}]);
Try keeping the redirection from within Angular, as Angular is meant to stay client-side in its own module. Like I said in a comment, you can send a status code from the server indicating the client to do a redirect.
For example, change your express endpoint to something like
app.post('/redirect', function(req, res){
res.status(300).send({ redirect:"/test"});
});
And your Angular Controller to something like
var app = angular.module('project', []);
app.controller('MainController', ['$scope', '$http', '$window', function ($scope, $http, $window) {
$scope.submit = function() {
$http.post('/redirect').then(function(data, status){
$window.location.href = data.redirect;
});
}
}]);
This way you can specify the redirect address from within server-side code.
Edit: In addition, I think you would need a hashtag for your redirect in angular, unless you have HTML5 mode enabled.
Routes created by node.js server are actual routes while AngularJS routing is based on hash (#) tags like -
Routes in node.js -
app.get('/myroute') will be like - http://localhost:8000/myroute
Routes in AngularJS -
'/myangroute' will be like - http://localhost:8000/#/myangroute
So coming back to your question, $http.post('/redirect'); is not redirecting you but posting the data to '/redirect' route(defined at server end). For redirection use angularjs $location service.
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.
I'm making a basic program where the user is shown a current room temperature along with a text field and "Set" button so that they can set their desired room temperature. What I want to happen is when the user enters a number into the text field and hits the Set button it changes the "roomTemp" variable to their desired temperature also known as "desiredTemp" and displays it as the current temperature. I don't think it's reaching the save() function as nothing is printed in my console when the button is clicked when it should output "Temperature is changing!" to my console.
Javascript File:
var http = require('http');
var ejs = require('ejs');
var fs = require('fs');
var roomTemp = 20;
var desiredTemp = 0;
http.createServer(function(req,res) {
res.writeHead(200, {'Content-Type': 'text/html'});
//since we are in a request handler function
//we're using readFile instead of readFileSync
fs.readFile('index.html', 'utf-8', function(err, content) {
if (err) {
res.end('error occurred');
return;
}
var renderedHtml = ejs.render(content, {roomTemp: roomTemp}); //get redered HTML code
res.end(renderedHtml);
});
}).listen(3000, "127.0.0.1");
console.log('Server Running at http://127.0.0.1:3000 CNTL-C to quit');
HTML File:
<!DOCTYPE html>
<html>
<head>
<script src="Thermostat.js"></script>
</head>
<body>
Current Temp: <%= roomTemp %> <br></br>
<form>
Desired Room Temperature: <input type="number" id="desTemp" name="roomTempDes"><br></br>
<button onclick="save(document.getElementById("roomTempDes").value)">Set</button>
</form>
<script>
function save(desiredTemp) {
roomTemp = desiredTemp;
console.log("Temperature is changing!");
}
</script>
</body>
</html>
You have too many quotation marks in your script.
"save(document.getElementById("roomTempDes").value)"
should be
"save(document.getElementById('roomTempDes').value)"
Your code is quoted incorrectly AND you have the WRONG ID.
<button onclick="save(document.getElementById('desTemp').value)">Set</button>