Updating a EJS file after a different option value is selected - javascript

I have the following files:
my EJS page with <select>
<!doctype html>
<html lang="en">
<%- include('../views/partials/header.ejs') %>
<body>
<h1 style="padding-left: 20px; padding-top: 10px;">AidaLinux</h1>
<%- include('../views/partials/nav.ejs') %>
<div class="table-responsive" style="padding: 20px 20px 0px 20px;" >
<h2><%= name.printername %> jobs List</h2>
<!-- select in question -->
<!-- this prints all my available printers -->
<select class="form-select" onchange="onChange();">
<% for ( var i = 0; i<name.length; i++ ) { %>
<option value="<%= name[i] %>"> <%= name[i] %> </option>
<% } %>
</select>
<table class="table table-hover table-striped table-borderless">
<thead>
<tr class='table-dark'>
<th scope="col">Job Rank</th>
<th scope="col">Job Commissioner</th>
<th scope="col">Job ID</th>
<th scope="col">Job File Name</th>
<th scope="col">Job Size</th>
</tr>
</thead>
<tbody>
<% for(var i=0; i<command.length; i++){ %>
<tr>
<th scope="row"><%= command[i].rank %></th>
<th scope="row"><%= command[i].owner %></th>
<th scope="row"><%= command[i].identifier %></th>
<th scope="row"><%= command[i].files %></th>
<th scope="row"><%= command[i].totalSize %></th>
</tr>
<% } %>
</tbody>
</table>
</div>
<div class="table-responsive" style="padding: 20px 20px 50px 20px;" >
<h2>All Printer Jobs List</h2>
<table class="table table-hover table-striped table-borderless">
<thead>
<tr class='table-dark'>
<th scope="col">Printer name</th>
<th scope="col">Job Commissioner</th>
<th scope="col">Date</th>
</tr>
</thead>
<tbody>
<% for(var i=0; i<job.length; i++){ %>
<tr>
<th scope="row"><%= job[i].printername %></th>
<th scope="row"><%= job[i].owner %></th>
<th scope="row"><%= job[i].date %></th>
</tr>
<% } %>
</tbody>
</table>
</div>
<%- include('../views/partials/footer.ejs') %>
<!-- test function to test the onchange -->
<script>function onChange(){
console.log("ciao");
}</script>
</body>
</html>
my function sent with express, it's only a part of the whole file cupsApis.js, where all my functions are stored, like this i only have to do one request in app.js and i have them all available there, but that's the one i'm interested in
lpq = function (name) {
let self = this;
self = utils.list()[6];
let args = ["-P", self];
let lpq = spawnSync("lpq", args, { encoding: "utf-8" });
let stdoutSpawnSync = utils.parseStdout(lpq.stdout);
stdoutSpawnSync.shift();
stdoutSpawnSync.shift();
let InfoJob = stdoutSpawnSync.map(function (line) {
line = line.split(/ +/);
return {
rank: line[0] === "active" ? line[0] : parseInt(line[0].slice(0, -2)),
owner: line[1],
identifier: parseInt(line[2]),
files: line[3],
totalSize: parseInt(line[4]),
};
});
return InfoJob;
};
my express file
const express = require("express");
const app = express();
const cups = require("./api/cupsApis.js")
app.listen(3000);
app.set("view engine", "ejs");
app.get("/", (req, res) => {
res.redirect("/home");
res.render("home");
});
app.get("/home", (req, res) => {
res.render("home");
});
app.get("/lpq", (req, res) => {
const name = cups.lpstat()
const command = cups.lpq();
const job = cups.lpstatJobs();
res.render("lpqView", {
command,
job,
name,
});
});
app.get("/classes", (req, res) => {
res.render("classes");
});
app.get("/lpstat", (req, res) => {
const command = cups.lpstat();
res.render("lpstatView", {
command,
});
});
app.get("/lp", (req, res) => {
const command = lp("/home/finsoft/ProgettoStampanti/file/file.txt");
console.log("command", command);
res.render("lpView", {
command,
});
});
app.get("/lpadmin", (req, res) => {
const command = cups.lpadmin("PrinterProva2", "HP Printer", "FINSOFT");
res.render("lpadminView", {
command,
});
});
What i'm trying to achieve is a 'refresh' of this EJS page when i click on a different <option> of the <select>, and when it happens i will change the values inside the first table, so i will see the current jobs for the selected printer.
I tried to find something online and a AJAX call and a fetch where the first results, i tried learning something about those topics with some example, but failed.
can someone explain what should i do? are those the only to methods? am i doomed to study them?

The question almost looks like "implement a feature for me", but if the gist was: is it possible to make a dynamic form without using AJAX, then the answer is yes. You can define a <form> and submit it programmatically with JS in the onChange() function (instead of outputting "ciao").
AJAX would make the user experience much better though, since the page would not reload. It just looks weird if the user is on the form and suddenly page starts loading and then turns to be the same page with just a few fields changes. With AJAX you can display a nice in-progress animation (a spinner) and simply update the current page based on the server response. It slightly more work though.
So answering to your second question: you are doomed to study if you wish to be a good developer. And not only regarding AJAX but you'll have to study through your entire career.

Related

How to retrieve objects from server and save as objects in array in JSP?

I wrote a JSP to get data from server and list as table. The code is below:
<script type="text/javascript">
var thislist;
</script>
<table class="table table-striped">
<thead>
<tr>
<th scope="col">Name</th>
<th scope="col">Address</th>
</tr>
</thead>
<tbody>
<%
int index = 1;
getCustomers ActionGet = new getCustomers();
List list = ActionGet.getCustomer();
Iterator it = list.iterator();
while (it.hasNext()) {
Customer customer = (Customer) it.next();
%>
<tr>
<th scope="row"><%=index++%></th>
<td><%=customer.getName()%></td>
<td><% if (customer.getAddress().length()>10) { %><%=customer.getAddress().substring(0,10) %><% } else { %>
<%=customer.getAddress() %><% } %></td>
</tr>
<%
}
%>
</tbody></table>
It only list the first 10 characters of address, Now I want to create a modal to view the whole address. To do that I want to create object array to store the whole address value ? Any hint? Thx.

"Is not defined" error trying to read database with nodejs and ejs

I can read the database and render it in the file mascotas.ejs but can't do it in the file index.ejs, it throw an error "arrayMascotas is not defined".
For the database I'm using mongoDB, also I'm using ejs templates and express.
Sorry if I didn't explain something correctly, it's my first web using mongoDB and probably is a small thing but I've trying resolve it during hours.
The idea is to read and render the data from mongodb into a table, in mascotas.ejs is working but not in index.ejs
mascotas.ejs
<table class="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">a</th>
</tr>
</thead>
<tbody>
<% if(arrayMascotas.length > 0) { %>
<% arrayMascotas.forEach(mascota => { %>
<tr>
<th scope="row"><%= mascota.id %></th>
<td><%= mascota.a %></td>
</tr>
<% }) %>
<% } %>
</tbody>
</table>
index.ejs
<table class="table">
<thead>
<tr>
<th scope="col">name</th>
</tr>
</thead>
<tbody>
<% if(arrayMascotas.length > 0) { %>
<% arrayMascotas.forEach(mascota => { %>
<tr>
<td><%= mascota.state %></td>
</tr>
<% }) %>
<% } %>
</tbody>
</table>
app.js
app.use("/", require("./router/Rutasweb"));
app.use("/mascotas", require("./router/Mascotas"));
Mascotas.js
const express = require("express");
const router = express.Router();
const Mascota = require("../models/mascota")
router.get("/", async (req, res) => {
try {
const arrayMascotasDB = await Mascota.find()
console.log(arrayMascotasDB)
res.render("mascotas", {
arrayMascotas: arrayMascotasDB
})
} catch (error) {
console.log(error)
}
})
module.exports = router;

Cannot read property 'forEach' of undefined Nodejs/ejs/javascript

Iam facing the error Cannot read property 'forEach of undefined' for two days long and I just coudn't solve the problem. Your help would be very helpful. The code below
bruidstaart.js page where I want to show some data
<div class="table-wrapper">
<table class="table table-hovered">
<thead class="thead-dark">
<tr>
<th scope="col">Image</th>
<th scope="col">Bruidstaartnaam</th>
<th scope="col">Aantalpersonen</th>
</tr>
</thead>
<tbody>
<% bruidstaarten.forEach((bruidstaart, user) => { %>
<tr>
<td><img src="/assets/bruidstaartenmap/<%= bruidstaart.image %>" class="rounded-circle player-img" alt="" width="200" height="200"></td>
<td><%= bruidstaart.bruidstaartnaam %></td>
<td><%= bruidstaart.aantalpersonen %></td>
</tr>
<% }) %>
</tbody>
</table>
</div>
index.js
exports.bruidstaartenPage = function(req, res, next){
var sql1 = "SELECT * FROM `bruidstaarten` ORDER BY id ASC"; // query database to get all the players
db.query(sql1, function(err, result){
res.render('bruidstaartenPage', {bruidstaarten:result});
});
};
I figure it out by checking the query and the tabel in the database. id was wrong by creating the tabel

How to get a MySQL Value as a colour in EJS?

I have a table in my nodeJS project that has data with a status. I would like to show this status in red and green. To render the HTML page I use EJS.
I've already tried using an if/else statement, but there I always get the first value of the statement.
MySQL:
SELECT g_id, g_name, g_status FROM games
EJS:
<table class="table table-hover">
<thead>
<tr class="table-info">
<th>Name</th>
<th>Status</th>
</tr>
</thead>
<% if (data) {
data.forEach(function(game){
var status = game.g_status;
if (status = '1') {
status = 'color-green';
} else {
status = 'color-red';
}
%>
<tbody id="myTable">
<tr>
<td><%= game.g_name %></td>
<td><%= status %></td>
</tr>
</tbody>
<% }) %>
<% } %>
</table>
What's the problem, and how do I get the SQL output to a specific colour?
use ternary condition like this way :
<table class="table table-hover">
<thead>
<tr class="table-info">
<th>Name</th>
<th>Status</th>
</tr>
</thead>
<% if (data) {
data.forEach(function(game){ %>
<tbody id="myTable">
<tr>
<td><%= game.g_name %></td>
<td><%= game.g_status=='1'?'color-green':'color-red' %></td>
</tr>
</tbody>
<% }) %>
<% } %>
well.
there is many places to look for.
read on equals operator in JavasScript
status is not part of the list, just app variable
create function returning color for given status

error with document.getElementById()

I am trying to write a jdo query in which I have to get a set of values based on the category that the user selects on the jsp...my query looks like this
Query query2 = pm.newQuery("select from " + ProductDB.class.getName()+ "where pCategory = " document.getElementById("cname").text);
Now on my jsp page, I have a dynamic drop-down box and in the tag I have given the id tag as "cname". So when I execute the above query I am hoping it will get the category that the user selects.
However I am getting this error:
Syntax error on token "document", delete this token
My select tag looks like this :
<select name = "cname" id="cname">
.
.
.
</select>
What am i missing here?
UPDATE :
I am putting my entire code for the jsp file below :
<%# page contentType="text/html;charset=UTF-8" language="java"%>
<%# page import="java.util.*"%>
<%# page import="javax.jdo.Query"%>
<%# page import="javax.jdo.PersistenceManager"%>
<%# page import="com.google.appengine.api.users.User"%>
<%# page import="com.google.appengine.api.datastore.Key"%>
<%# page import="com.google.appengine.api.users.UserService"%>
<%# page import="com.google.appengine.api.users.UserServiceFactory"%>
<%# page import="java.net.*"%>
<%# page import="javax.servlet.http.HttpServletRequest"%>
<%# page import="com.nerdy.needs.*"%>
<html>
<head>
<title>Product Inventory</title>
<META HTTP-EQUIV="Refresh" CONTENT="450">
<link rel="stylesheet" href="login.css" type="text/css" />
</head>
<h1 align="center">Product Inventory</h1>
<body>
<form>
<table>
<tr>
<td>View</td>
<td><select name="cname" id="cname">
<option value="all">All</option>
<%
PersistenceManager pm = PMF.get().getPersistenceManager();
Query query = pm.newQuery("select cname from "
+ CategoryDB.class.getName());
List<String> categories = new ArrayList<String>();
categories = (List<String>) query.execute();
String[] c = categories.toArray(new String[categories.size()]);
for (int i = 0; i < c.length; i++) {
String s = c[i];
%>
<option value="<%=s%>"><%=s%></option>
<%
}
%>
</select></td>
<td>Products</td>
</tr>
</table>
</form>
<%
if (document.getElementById("cname").value == "all") {
PersistenceManager pm1 = PMF.get().getPersistenceManager();
Query query1 = pm1.newQuery("select * from "
+ ProductDB.class.getName());
List<ProductDB> prods1 = (List<ProductDB>) query1.execute();
if (prods1.isEmpty()) {
%>
<table class="items">
<tr>
<th class="main">Image</th>
<th class="main">Category</th>
<th class="main">Name</th>
<th class="main">Price</th>
<th class="main">Description</th>
</tr>
<tr class="lightBlue">
<td class="actions" colspan=100%>
<p>No items were found.</p>
</td>
</tr>
</table>
<%
} else {
%>
<table class="topics">
<tr>
<th class="main">Image</th>
<th class="main">Category</th>
<th class="main">Name</th>
<th class="main">Price</th>
<th class="main">Description</th>
</tr>
<%
for (ProductDB p : prods1) {
%>
<tr>
<td>
<p><b> <img width="100" height="100"
src="http://localhost:8888/serve?id= <%=p.getProductImage()%>">
</b></p>
</td>
<td>
<p><b><%=p.getProductCategory()%></b></p>
</td>
<td>
<p><b><%=p.getProductName()%></b></p>
</td>
<td>
<p><b><%=p.getProductPrice()%></b></p>
</td>
<td>
<p><b><%=p.getProductDescription()%></b></p>
</td>
</tr>
<%
}
%>
</table>
<%
pm1.close();
}
} else {
PersistenceManager pm2 = PMF.get().getPersistenceManager();
Query query2 = pm.newQuery("select * from "
+ ProductDB.class.getName() + "where pCategory = "
+ document.getElementById("cname").value);
List<ProductDB> prods2 = (List<ProductDB>) query2.execute();
if (prods2.isEmpty()) {
%>
<table class="items">
<tr>
<th class="main">Image</th>
<th class="main">Category</th>
<th class="main">Name</th>
<th class="main">Price</th>
<th class="main">Description</th>
</tr>
<tr class="lightBlue">
<td class="actions" colspan=100%>
<p>No items were found.</p>
</td>
</tr>
</table>
<%
} else {
%>
<table class="topics">
<tr>
<th class="main">Image</th>
<th class="main">Category</th>
<th class="main">Name</th>
<th class="main">Price</th>
<th class="main">Description</th>
</tr>
<%
for (ProductDB p : prods2) {
%>
<tr>
<td>
<p><b> <img width="100" height="100"
src="http://localhost:8888/serve?id= %=p.getProductImage()%>">
</b></p>
</td>
<td>
<p><b><%=p.getProductCategory()%></b></p>
</td>
<td>
<p><b><%=p.getProductName()%></b></p>
</td>
<td>
<p><b><%=p.getProductPrice()%></b></p>
</td>
<td>
<p><b><%=p.getProductDescription()%></b></p>
</td>
</tr>
<%
}
%>
</table>
<%
pm2.close();
}
}
%>
</body>
</html>
I am getting "document cannot be resolved" errors in two places - one at the if statement
if(document.getElementById("cname").value=="all")
and the other at the query statement
Query query2 = pm.newQuery("select * from " + ProductDB.class.getName()+ "where pCategory = " + document.getElementById("cname").value);
Can anyone help me to figure out what is wrong?
Your concrete problem is that you're mixing Java/JSP with JavaScript. You seem to expect that they run in sync and you seem to expect that JavaScript's document object variable is also present in JSP scriptlet code.
This is wrong. Java/JSP is a HTML code generator. It runs in webserver upon a HTTP request and generates HTML/JS code and sends it back to webbrowser as HTTP response. All the webbrowser retrieves is plain HTML/JS code. Rightclick the page in webbrowser and do View Source to see it yourself.
Your concrete functional requirement seems to be that you need to grab the the submitted value of
<select name="cname">
in the Java/JSP side.
You need to get it as a request parameter by HttpServletRequest#getParameter(). So, replace
<%
if (document.getElementById("cname").value == "all") {
// ...
}
%>
by
<%
if ("all".equals(request.getParameter("cname"))) {
// ...
}
%>
That said, writing Java code in JSP files is a poor practice. Work on that as well. Note that this problem is unrelated to JDO.
You forgot the plus mark before the document.getElementById.
The correct code would be
Query query2 = pm.newQuery("select from " + ProductDB.class.getName() + "where pCategory = " + document.getElementById("cname").text);
Also, although that will fix the syntax error, the code still won't work. According to W3C DOM specification, the <select/> element doesn't have the text attribute; you should use the value, or selectedIndex in conjunction with options instead.
Try this way:-
var i = document.getElementById("cname").selectedIndex;
document.getElementById("cname").options[i].text;
OR
document.getElementById("cname").value
UPDATE:
Column names are missing too. It should be either * or specific column names.
Query query2 = pm.newQuery("select * from " + ProductDB.class.getName()+ "where pCategory = " + document.getElementById("cname").value);
As per your error update
your code should be as follows:-
if(document.getElementById("cname").value=="all")
{
<%
PersistenceManager pm1 = PMF.get().getPersistenceManager();
Query query1 = pm1.newQuery("select * from " + ProductDB.class.getName());
List<ProductDB> prods1 = (List<ProductDB>) query1.execute();
%>
}
JSP tags should be declared between tags <% and %> and other html tags should be outside.
As per your Code:
The problem is document.getElementById("cname").value calling inside the JSP tags. That is wrong.
Here either you can pass cname value as query string and get value through the parameter
OR
Assign document.getElementById("cname").value value to JSP variable and process it.

Categories

Resources