Updata table html EJS + Nodejs + Expressjs - node.js

I have an application nodejs + expressjs + ejs.
I am building a history search screen, my question is how to update my ejs html table with the values ​​returned in the response.
Uploading the screen with the values ​​is working, but when I enter the filters and search, I would like to update my table.
In the example below is how to use to load the html the first time with the data of the query, I would like to fill in an initial and final date and click on searching and updating the html.
EJS HTML
<div class="row">
<div class="col-md-2">
<div class="form-group">
<label for="dataPrimayID">Date Primary</label>
<input type="text" class="form-control datepickerDefault" id="dataPrimayID" name="dataPrimary" maxlength="250">
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<label for="dataFinalID">Date Final</label>
<input type="text" class="form-control datepickerDefault" id="dataFinalID" name="dataFinal" maxlength="250">
</div>
</div>
<div class="col-md-2">
<a id="btnSearch" class="btn btn-primary">Search</a>
</div>
</div>
<div class="row">
<div class="table-responsive col-md-12">
<table id="dataTableHistoricoID" class="table table-striped" cellspacing="0" cellpadding="0">
<thead>
<tr>
<th>Name</th>
<th>LastName</th>
</tr>
</thead>
<tbody>
<% if(data.length > 0){ %>
<% for ( var i = 0 ; i < data.length ; i++){ %>
<tr>
<td>
<%= data[i].name%>
</td>
<td>
<%= data[i].lastname%>
</td>
</tr>
<% } %>
<% } %>
</tbody>
</table>
</div>
</div>
ROUTER
var express = require('express');
var router = express.Router();
var historyController = require('../controllers/history-controller');
router.get('/find', historyController.findHistory);
module.exports = router;
Controller
db.query(sql, function (err, rows) {
if (err) {
var message = err.message;
console.log(message);
return res.status(500).send(message);
}else {
var data = rows;
res.render('history/search-history', {data: data});
}
});

EJS is static after compiling, you can't change it on backend-side. There are two ways of it.
Refreshing the page every time you want to render new content.
Implement client-side JS code that will handle api requests and render new elements.
For example, using Jquery:
$.post(url, (result) => {
let data = JSON.parse(result);
let innerHTML = '';
for (let item of data) {
innerHTML += `<tr>
<td>
${item.name}
</td>
<td>
${item.lastname}
</td>
</tr>`;
}
$('#dataTableHistoricoID tbody').html(innerHTML)
};

Related

How to send embed generated qr-code in ejs using mailgun in node js?

This the code of sending an email using mailgun:
const qrcodeEmail = async (email, subject,text,qrcode,user,data) => {
try {
const requiredPath = path.join(__dirname, "../views/emailTemplates/qrcodeEmail.ejs");
const emailData = await ejs.renderFile(requiredPath,{user:user,data:data,qrcode:qrcode});
var mailData = {
from: 'moilasurprise7#gmail.com',
to: 'moilasurprise7#gmail.com',
subject:subject,
html:emailData,
};
mailgun.messages().send(mailData, function (error, body) {
if(error){
console.log(error);
}
console.log("email sent successfully");
});
} catch (error) {
console.log(error.message);
}
};
The email is sent,the user and order details are showing but the qr-code is not displaying down here is the ejs email template.
Note: the qr-code is generated in this manner.
await QRCode.toDataURL(text);
This is the ejs template where the qrcode is rendered:
<table style="width:100%;max-width:620px;margin:0 auto;background-color:#ffffff;">
<tbody>
<tr>
<td style="padding: 30px 30px 20px">
<p style="margin-bottom: 10px;">Hi <%= user.name %> <%=user.lastName%> ,</p>
<p style="margin-bottom: 10px;">Here is your ticket order</p>
<p style="margin-bottom: 10px;">eventName : <%= data.eventName %> </p>
<p style="margin-bottom: 10px;">EventVenue : <%= data.eventVenue %> </p>
<p style="margin-bottom: 10px;">eventDuration : <%= data.eventDuration %> </p>
<p style="margin-bottom: 10px;">eventRegion : <%= data.eventRegion %> </p>
<p style="margin-bottom: 10px;">Ticket Type : <%= data.category %> </p>
<p style="margin-bottom: 10px;">Ticket price : $<%= data.price %> </p>
<p style="margin-bottom: 10px;">eventDate: <%= data.eventDate.getDate()%>/<%= data.eventDate.getMonth() + 1%>/<%= data.eventDate.getFullYear()%> </p>
<img src="<%=qrcode%>" alt="qr-code">
</td>
</tr>
</tbody>
</table>

How to make my update button work correctly

I am making a todolist app using express, mongoose, mongodb, bootstrap. When I hit my update button to update a task it just makes a duplicate of the task that i'm trying to update. How would I go about making my update button update the original task?
Here are some screenshots on what happens when I try to update :
https://i.stack.imgur.com/t11OG.jpg - here I created a task "make breakfast".
https://i.stack.imgur.com/ijt98.jpg - here I hit the yellow update button and I am updating the task from "make breakfast" to "make lunch".
https://i.stack.imgur.com/V4RCe.jpg - here when I hit the green update button it creates a separate task instead of updating the original "make breakfast" task.
My routes and my ejs for the home page are below:
I can also show the ejs for updating a task as well.
Thanks
const express = require("express");
const { route } = require("express/lib/application");
const router = express.Router();
const mongoose = require("mongoose");
const Todoinfo = require("../models/infoSchema");
router.get("/", async (req, res) => {
// get all todos
const allTodos = await Todoinfo.find({}).sort("-date");
res.render("home", { allTodos });
});
router.post("/", async (req, res) => {
// add a todo
const newTodo = new Todoinfo(req.body); // create a new todo
await newTodo.save((err) => {
// save the new todo
if (err) {
res.send("Not updated");
}
});
//res.redirect("/");
});
router.get("/:id/delete", async (req, res) => {
// delete a todo
const todoDelete = await Todoinfo.findByIdAndDelete(req.params.id); // find the todo by id and delete it?
res.redirect("/"); // redirect to home page
});
router.get("/:id/finish", async (req, res) => {
// finish a todo (change status to completed)
const todoDelete = await Todoinfo.findByIdAndUpdate(req.params.id, {
progress: "Completed",
});
res.redirect("/");
});
router.get("/:id/update", async (req, res) => {
// update a todo (change status to in progress)
const updateTodo = await Todoinfo.findById(req.params.id); // find the todo by id and update it?
res.render("update", { updateTodo }); // render the update page with the todo
});
router.get("/:id/update/final", async (req, res) => {
// update a todo (change status to finished)
const updateTodo = await Todoinfo.findByIdAndUpdate(req.params.id, {
// find the todo by id and update it?
description: req.body.description, // update the description of the todo with the new description
});
res.redirect("/");
});
module.exports = router;
<!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">
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<title>Todo App</title>
</head>
<body>
<section class="vh-100" style="background-color: #eee ">
<div class="container py-5 h-100">
<div class="row d-flex justify-content-center align-items-center h-100">
<div class="col col-lg-12 col-xl-g">
<div class="card rounded-3">
<div class="card-body p-4">
<h4 class="text-center my-3 pb-3 text-primary ">My Todo App</h4>
<form class="row row-cols-lg-auto g-3 justify-content-center
align-items-center mb-4 pb-2" action="/" method="POST">
<div class="col-12">
<div class="form-outline">
<input type="text" id="form1" class="form-control" name="description" />
<label class="form-label" for="form1">Create a new task </label>
</div>
</div>
<div class="col-12">
<button type="submit" class="btn btn-primary mb-4">Add</button>
</div>
</form>
<table class="table mb-4">
<thead>
<tr>
<th scope="col">Item No.</th>
<th scope="col">Todo Item</th>
<th scope="col">Action</th>
<th scope="col">Status</th>
</tr>
</thead>
<tbody>
<% for(let i= 0; i <allTodos.length; i++) { %>
<tr>
<% let z= i + 1 %>
<th scope="row"><%= z %></th>
<% if (! allTodos[i].progress.localeCompare(" Completed" )) { %>
<td class="text-decoration-line-through"> <%=
allTodos[i].description %> </td>
<%} else {%>
<td> <%= allTodos[i].description %> </td>
<%}%>
<td> <%= allTodos[i].progress %> </td>
<td>
<button type="submit" class="btn btn-danger ms-1 mb-1">Delete</button>
<% if (! allTodos[i].progress.localeCompare(" Completed"))
{ %>
<%} else {%>
<a href="/<%= allTodos[i]._id %>/finish" class="text-decoration-none">
<button type="submit" class="btn btn-success ms-1 mb-1">Finished</button></a>
<button type="submit" class="btn btn-warning ms-1 mb-1">Update</button>
<% } %>
</td>
</tr>
<% } %>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</section>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
</body>
</html>

ExpressJS : SQLITE_RANGE: column index out of range WHERE condition

I am working on a project using express , EJS and SQLite , So i made a function that select data from the database, and render it to the interface, this is the function:
function findHomeforSell(req , res , next){
const sell = "Sell";
db.all('SELECT * FROM home WHERE for = ? ', [
sell
] ,function(err , rows){
if (err) { return next(err);}
var homes = rows.map(function(row) {
return {
id: row.id,
location: row.Location,
four: row.for,
space: row.space,
bathrooms: row.bathrooms,
bedrooms: row.bedrooms,
price: row.price,
url: '/' + row.id
}
});
res.locals.homes = homes;
});
};
the ejs file:
<div class="house-list" id="buy">
<h1>Buy</h1>
<ul class="todo-list">
<% homes.forEach(function(home) { %>
<li>
<form action="<%= home.url %>" method="post">
<div class="view">
<table>
<thead>
<th>Location</th>
<th>For</th>
<th>Space</th>
<th>Bathroom</th>
<th>Bedroom</th>
<th>Price</th>
</thead>
<tbody>
<td><label ondblclick=""><%= home.location %> </label></td>
<td><label ondblclick=""> <%= home.four %></label></td>
<td><label ondblclick=""><%= home.space %> SQRM </label></td>
<td><label ondblclick=""> <%= home.bathrooms %></label></td>
<td><label ondblclick=""><%= home.bedrooms %> </label></td>
<td><label ondblclick="">$ <%= home.price %> SDG</label></td>
</tbody>
</table>
</div>
</li>
<% }); %>
</ul>
</div>
and the error:
SQLITE_RANGE: column index out of range
I couldn't understand the error so what to do

How do I handle form data from a form with multiple fields in node?

I'm trying to build a page for people to RSVP for a wedding website. The guest types in their email address, and the page finds all guests that appear on that invitation and then generates a table:
<%- include("./partials/header") %>
<h2>
RSVP
</h2>
<div class="container">
<div class=" row justify-content-center">
<h5>Enter the email address that appears on your invitation.</h5>
</div>
<div class=" row justify-content-center">
<div id="form-findGuest">
<form action="/rsvp" method="GET">
<input type="text" name="searchEmail" placeholder="email">
<button type="submit">Submit</button>
</form>
</div>
</div>
<div class="row justify-content-center">
<form action="/rsvp" method="POST">
<table class="table">
<% for(i=0;i<guests.length;i++){ %>
<tr>
<td><%= guests[i].name %></td>
<% if(guests[i].isComing){ %>
<td>Attending</td>
<% } else { %>
<td>Not Attending</td>
<% } %>
<td>
<td>
<input type="checkbox">
</td>
</tr>
<% }%>
</table>
</form>
</div>
<div class="row justify-content-center">
Back
</div>
</div>
<%- include("./partials/footer") %>
The problem is that I don't know what to do with the post route. Basically I want to do something like this:
app.post("/rsvp", (req, res)=>{
// parse the req.body and for each rsvp that got sent here, add it to some array
// now use a for loop to iterate through that array and change the isComing value for each guest
res.redirect("index")
})
But I can't figure out how to parse the req.body when I don't know how many fields are going to be in the request- some email addresses may correspond to only one guest, but others may correspond to, say, five.
Add Body parser if not added already, and make use of
Object.keys
const express = require('express'),
app = express(),
bodyParser = require('body-parser');
// support parsing of application/json type post data
app.use(bodyParser.json());
//support parsing of application/x-www-form-urlencoded post data
app.use(bodyParser.urlencoded({ extended: true }));
app.post("/rsvp", (req, res)=>{
var keys = Object.keys(req.body);
for(var i=0;i<keys.length;i++)
{
var guest=req.body[keys[i]];
// now use this to change the isComing value for each guest
}
res.redirect("index")
})

KrakenJs with Dust Template looping through object Error

I should Have got the else part but I am getting the error: Expected end tag for cart.items but it was not found. At line : 21, column : 35. I don't know where is the problem everything is fine may be indentation error please look out the code and suggest me. thanks there is also attached screen shot of the error.
this is my dust file:
{>"layouts/master" /}
{<body}
<div class="row">
<div class="container">
<h2>Your Cart</h2>
{?cart.items}
<table>
<thead>
<tr>
<th>Item</th>
<th>Quantity</th>
<th>Total</th>
<th>Action</th>
</tr>
</thead>
<tbody>
{#cart.items}
<tr>
<td>{title}</td>
<td>{.qty}</td>
<td> ${#math key="{.price}" method="multiply" operand ="{.qty}"}</td>
<td>Remove</td>
</tr>
{/cart.items}
</tbody>
</table>
<div class="row">
<div class="col-sm-6">
<h4> Total <strong>${cart.total}</strong></h4>
</div>
<div class="col-sm-6">
</div>
</div>
{:else}
<p>There is no Items in your cart</p>
{/cart.items}
</div>
</div>
{/body}
this is my controller
'use strict';
var Book = require('../models/bookModel');
var Category = require('../models/categoryModel');
module.exports = function (router) {
router.get('/', function (req, res) {
var cart = req.session.cart;
var displayCart = {
items: [], total: 0
};
var total = 0;
//get total
for(var item in cart){
displayCart.items.push(cart[item]);
total += (cart[item].qty * cart[item].price);
}
displayCart.total = total;
res.render('cart/index', {cart: displayCart});
});
});
I am Getting this error:
The math helper should be closed. E.g:
{#math key="{.price}" method="multiply" operand ="{.qty}" /}

Resources