req.body option selected express ejs - node.js

Hi would like to send the selected option in dropdown menu, to show only the products from my mongodb.
If i use a submit button, works, but i would like to do without button. some help?
app.post('/windproducts', async (req, res) =>{
let tipoProducto = req.body.tipo_producto;
console.log(tipoProducto)
const windproducts = await WindProduct.find({"tipo_producto": {$eq:tipoProducto}})
res.redirect('windproducts/tablas', {windproducts})
}
)
in EJS:
<form action="/windproducts" method="POST">
<select id="productosTipo" class="validated-form" name="tipo_producto">
<option name="" value="">Todo</option>
<option name="tabla" value="tabla">Tabla</option>
<option name="vela" value="vela">Vela</option>
</select>
<!-- <button class="btn btn-success">mostrar</button> -->
</form>
Thanks

<% %>
use this syntax in your view file to use foreach loop on object
<%
Object.keys(obj).forEach(function(key) {
%>
// HTML Code
<%
});
%>

Related

Standardize Dropdown's Selected Handlebars Helper

I'm facing the following challenge building some dropdowns with Handlebars.
Instead of modeling the dropdown's select this way:
<div class="form-floating col-3">
<select name="sport" class="form-select" id="floatingSelect">
<option {{selectedSport sport 'all'}} value="all">All</option>
<option {{selectedSport sport 'Hiking'}} value="Hiking">Hiking</option>
<option {{selectedSport sport 'Mountaineering'}} value="Mountaineering">Mountaineering</option>
<option {{selectedSport sport 'Climbing'}} value="Climbing">Climbing</option>
<option {{selectedSport sport 'Mountain biking'}} value="Mountain biking">Mountain biking</option>
</select>
<label for="floatingSelect">Sport</label>
</div>
<div class="form-floating col-2">
<select name="difficulty" class="form-select" id="floatingSelect">
<option {{selectedDifficulty difficulty 'all'}} value="all">All</option>
<option {{selectedDifficulty difficulty 'Easy'}} value="Easy">Easy</option>
<option {{selectedDifficulty difficulty 'Medium'}} value="Medium">Medium</option>
<option {{selectedDifficulty difficulty 'Hard'}} value="Hard">Hard</option>
<option {{selectedDifficulty difficulty 'Expert'}} value="Expert">Expert</option>
</select>
<label for="floatingSelect">Difficulty</label>
</div>
I would like to use the same helper for both of them, but I still don't know how to do it. (btw, ignore the fact that I should be using an {{#each}} for displaying the options :P)
The controller:
module.exports.list = (req, res, next) => {
const filters = req.query;
const { location, sport, difficulty } = req.query;
const criterial = Object.keys(filters)
.filter((key => filters[key] !== 'all'))
.reduce((criterial, filter) => {
if (filters[filter]) criterial[filter] = filters[filter];
return criterial;
}, {});
Route.find(criterial)
.then(routes => {
res.render('routes/list', { routes, location, sport, difficulty })
})
.catch(next)
}
The helpers:
hbs.registerHelper('selectedSport', (option, sportValue) => {
return option === sportValue ? ' selected' : '';
})
hbs.registerHelper('selectedDifficulty', (option, difficultyValue) => {
return option === difficultyValue ? ' selected' : '';
})
Many thanks for your help! :)
Finally I solved it this way:
Instead of typing all the options directly on the HBS, I create these with a helper that renders each option.
<div class="form-floating col-3">
<select name="sport" class="form-select" id="floatingSelect">
{{#each sportOptions as |sportOption|}}
{{option ../sport sportOption}}
{{/each}}
</select>
<label for="floatingSelect">Sport</label>
</div>
<div class="form-floating col-2">
<select name="difficulty" class="form-select" id="floatingSelect">
{{#each difficultyOptions as |difficultyOption|}}
{{option ../difficulty difficultyOption}}
{{/each}}
</select>
<label for="floatingSelect">Difficulty</label>
</div>
The helper receives 2 parameters: sport and sportOption and according to their value, returns a string cointaining the option with the selected attribute or not.
hbs.registerHelper('option', function (selectedValue, value) {
const selectedProperty = value == selectedValue ? 'selected' : '';
return new hbs.SafeString(`<option value=${value} ${selectedProperty}>${value}</option>`);
});
sportOption and difficultyOption are arrays with all the possibilities inside them.
I hope that, if someone else has the same problem, this can be of any help :)

Cannot POST error using Express, Mongoose, EJS

(For the solution check the last answer)
I'm creating object with rating system with default value of 0. What I'm trying to do is to update the rating value by choosing one of the options in the <select> dropdown menu. The problem is when I'm submiting the selected value it sends the 'Cannot POST / ...' error.
Here's the app.js code with post and get requests:
// Updating Single Object
app.post('project/:projectId', (req, res) => {
const project = {};
project.rating = req.body.rating;
Project.update({_id: request.params.projectId}, project, (err) =>{
if(err){
console.log(err);
return;
} else {
res.redirect('/project/:projectId');
}
});
});
// Route To Single Project
app.get('/project/:projectId', (req, res) => {
const requestedProjectId = req.params.projectId;
Project.findOne({_id: requestedProjectId}).populate('image_file').exec((err, project) => {
res.render('project', {
project: project
});
});
});
And the form:
<form action="/project/<%= project.id %>" method="post">
<select class="" name="rating">
<option value="0">Rate us</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
<option value="7">7</option>
<option value="8">8</option>
<option value="9">9</option>
<option value="10">10</option>
</select>
<input type="submit" value="Vote">
</form>
I think I'm missing something but can't figure it out.
Thank you in advance.
Just change your url in routes, use /project/:projectId instead of project/:projectId in app.post() method
Solved it after 3 hours, realizing I was missing the / before project in the url route.
app.post('project/:projectId', (req, res) => {
Maybe instead of:
<form action="/project/<%= project.id %>" method="post">
you should use:
<form action="/project/<%= project._id %>" method="post">

conditional statement is not working in ejs

Hello I wants to apply conditional statement in ejs but it is not working in my code "i wants that when i select the a specific value(not using transportation) then buton shows otherwise not show but its showing only - (else condition) on every selection from dropdown" in developer tools it is showing the conditional statement code like this https://ibb.co/60ZWcXh that it is not taking
conditional statement
<%if (locals.students == "noTransportation") { %>
<button type="button" class="btn btn-primary pull-right" onclick="" id="">
Migrate to Applicants
</button>
<%} else { %>
-
<% } %>
complete students_list.ejs
<select class="form-control changeDropDown" id="transportation">
<option value="applications">Applications</option>
<option value="transportation">Using Transportation</option>
<option value="noTransportation">Not Using Transportation</option>
<option value="All">All</option>
</select>
<%if (locals.students == "noTransportation") { %>
<button type="button" class="btn btn-primary pull-right" onclick="" id="">
Migrate to Applicants
</button>
<%} else { %>
-
<% } %>
controller:
in controller the code in comments ////data migration code//// is for this conditional statement but its not working
paste.ofcode.org/RGu9t7Fm3uNPNKiczNP2p9
how can I resolve this issue
If you put a console.log(locals.students) right above the if condition, you'll see (in your node's terminal) that locals.students has a value that's different than noTransportation. Add it like this:
<select class="form-control changeDropDown" id="transportation">
<option value="applications">Applications</option>
<option value="transportation">Using Transportation</option>
<option value="noTransportation">Not Using Transportation</option>
<option value="All">All</option>
</select>
<% console.log("====================", locals.students) %>
<%if (locals.students == "noTransportation") { %>
<button type="button" class="btn btn-primary pull-right" onclick="" id="">
Migrate to Applicants
</button>
<%} else { %>
-
<% } %>
If you want to see that the if actually works properly, you can put, temporarily, instead of the console.log(....):
<% locals.students = "noTransportation" %>
Update:
There's no quick & easy solution that could fit in an answer on stackoverflow for what you currently have.
Some ideas for you to follow:
the code inside <% .. %> is executed on the server.
the selection change of the select box is executed in the browser
in order to have the button show whenever a change is made, you can:
add a client side js function to hide/show the button whenever $("#transportation") changes - but this alone will save nothing in your DB
make a server request and redraw the whole page when $("#transportation") changes, so that your ejs can be executed.

Ejs passed variable not showing

I am using express framework in node js.
for page rendering i use ejs.
given below route i passed 3 variable doctors title or loggined user id
router.get('/doctors/:id',passportConf.isAuthenticated, function(req,res,next){
Doctor.find({category:req.params.id})
.populate("category")
.exec(function(err, doctors){
if (err) return next (err);
res.render('main/doctor', {doctors: doctors, title:'doctors', id: req.user._id})
})
});
now problem is when i access these variable like this then i get my variable data
<%= doctors[i]._id%> or <%= title %> or <%= id%>
but when i acces these variable data in if statment then id data give nothing
i tried this in if statment
user id is 5cfaa0e32e21cb3c88885260
if (doctor[i]._id != '5cfaa0e32e21cb3c88885260')
then my code worked fine
if (id != '5cfaa0e32e21cb3c88885260')
thene my code not work
my ejs code
<% for(i=0; i<doctors.length; i++) {%>
<small><%= doctors[i].category.name%></small>
<ul>
<% if (id != '5cfaa0e32e21cb3c88885260') {%>
<form method="post">
<input class="form-control" type="hidden" name="doctor_id" value="<%= doctors[i]._id%>">
<button class="btn_1 medium" type="submit">Book now</button>
</form>
<%}%>
</ul>
</div>
</div>
<%}%>

Node.js pass a value to a partial view

I have a route that looks like this:
app.get('/Search', function (req, res) {
var searchString = req.query.SearchString;
var request = require('./cstapi')(searchString, onBody);
function onBody(body) {
res.render('index', { output: body });
}
});
and an index.ejs that looks like this:
<div id="searchDiv">
<% include ../partials/search %>
<br>
<% include ../partials/results %>
</div>
search looks like this:
<form action="./search" method="GET">
<input type="text" name="SearchString" class="form-control" >
<input type="submit" value="Search" class="form-control">
</form>
and results looks like this:
<p>Search returned the following: <%= output %></p>
I'm trying to get the search results to display in a partial view after the user submits the form. With the above I get output is not defined when attempting to render index and the subsequent partial views.
I found a work around although I'm not 100% sure this is the best way of doing it:
By adding 'null check' to output in index I can avoid the output not defined error when accessing the results partial without search results.
So index now becomes:
<div id="searchDiv">
<% include ../partials/search %>
<br>
<%if (typeof output !== 'undefined') { %>
%> <% include ../partials/results %>
<% } %>
</div>
Hopefully someone can provide a better way?

Resources