Retrieving value from input in EJS with NodeJS - node.js

Here is my EJS code:
<form action="/" method="POST">
<% items.forEach((item)=>{ %>
<div class="item">
<input type="checkbox" name="checkbox" value="<%=item._id%>" onchange="this.form.submit()">
<p><%= item.name %></p>
</div>
<% }) %>
</form>
And here is the app.js:
app.post('/',(req,res)=>{
console.log(req.body.checkbox);
})
My questions are:
1) Why does it only log the value of the selected checkbox (assumed that there are 3 items) instead of 3 values, is it because of the post method only post the checkbox's value that has the property checked == true?
2) If I add another checkbox like below, why does it return undefined if I try to console.log(req.body.item_id)?
<form action="/" method="POST">
<% items.forEach((item)=>{ %>
<div class="item">
<input type="checkbox" name="checkbox" value="<%=item._id%>" onchange="this.form.submit()">
<p><%= item.name %></p>
<input type="checkbox" name="item_id" value="<%=item._id%>">
</div>
<% }) %>
</form>
3) I've tried to do the same thing above but this time it is using input type of text. Why does the console.log(req.body.item_id) show 3 values instead of 1 (which corresponds with the selected checkbox like in question 1)?
<form action="/" method="POST">
<% items.forEach((item)=>{ %>
<div class="item">
<input type="checkbox" name="checkbox" value="<%=item._id%>" onchange="this.form.submit()">
<p><%= item.name %></p>
<input name="item_id" value="<%=item._id%>">
</div>
<% }) %>
</form>
All response are appreciated. Thank you!

That is the default behaviour of the checkbox, it only gets
passed as data if its checked, if it doesn't get passed, we can
assume it wasn't checked
However if you still want the checkbox in data even if it was not checked, one hack would be
Create a hidden element with same name as your checkbox & set value as 'off'
Before submit, if the checkbox is checked, disable the hidden input element
this will give your checkbox value 'on' when checked & 'off' when its not
As mentioned above, it will only added to formdata if its
checked, when its not checked, the element is not added to formdata
at all, so you will get undefined if its not checked
Again this is default behaviour of input types, the reason it
does not do same for checkbox is because, maybe you are only
selecting 1 checkbox with same name before submit, if you do select
multiple checkbox with same name in checkboxes, you'll get same
result for checkboxes too, but due to the reason mentioned in first
answer, it only get's us the element selected which is 1 in your
case

Related

SyntaxError: Unexpected identifier in E:\i\todolist-nithishtry\views\list.ejs while compiling ejs

code:
<% newitems.forEach(function(item){%>
<div class="item">
<input type="checkbox" />
<p>
<%= item.name %>
</p>
</div>
<% });%>
by using for loop i got the required output
when i tried to use for each loop i got error
code used for for loop
<%for(var i=0; i<newitems.length; i++){%>
<div class="item">
<input type="checkbox" >
<p><%= newitems[i].name %></p></div>
<%}%>
I was having the same issue on my end. Check out the submit button and change the value to value="<%=listTitle%>". hope this helps

How to get value of checkbox plus another value together from ejs with express

in the code below, I want to get checkbox value 'on/undefined' based on user selection and the value which I am passing (item._id) together in req.body. how do I do that?
<form action="/update" method="POST">
<div class="items">
<input type="checkbox" name="checkbox" value="<%= item._id%>" onChange=" this.form.submit()">
<p><%= item.title %></p>
</div>
</form>
Got the answer : Pass the additional attribute as hidden property.

NodeJS send to POST also unchecked input

I have a form in which I iterate an input checkbox field n times, as follows:
<form class="" action="" method="post">
<% availableDirezione.forEach((direzione, index) => { %>
<p>
<input class="checkbox" type="checkbox" name="checkArray" id="check0" value="1">
<span><%= direzione.usr_udf_direzione %> (<%= direzione.usr_udf_dirid %>) </span>
</p>
<% }) %>
<button type="submit" class="btn btn-primary float-right mb-5">Add Mapping</button><br>
</form>
I would like that in the post method, even the unchecked values are passed in the checkArray object.
Let's suppose the forEach iterates 5 times, and only the first and last checkbox are checked, I would like that the checkArray object is as following:
...
body : {
checkArray : [1,0,0,0,1]
}
...
I tried adding the hidden checkbox with a 0 value. It fills the checkArray object 5 times but in wrong error. Any tips?
Sorry but is not possible. This is not due to a Node.js limitation but rather a HTML standard. See second 'note' block in
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/checkbox (under value section)
Hence you may try to fight against it with some front-end js code, but I wont suggest it. What you need to do is have a mean to reconstruct the array at the end like this:
<form class="" action="" method="post">
<% availableDirezione.forEach((direzione, index) => { %>
<p>
<input class="checkbox" type="checkbox" name="checkArray" id="check0" value="<%= index %>">
<span><%= direzione.usr_udf_direzione %> (<%= direzione.usr_udf_dirid %>) </span>
</p>
<% }) %>
<button type="submit" class="btn btn-primary float-right mb-5">Add Mapping</button><br>
</form>
Then when you receive your POST:
availableDirezione.map((direzione, index) => checkArray.indexOf(index) !== -1 0 : 1)
This will produce a [0, 1, 1, 0, 0 ... ] array
availableDirezione.map((direzione, index) => checkArray.indexOf(index) !== -1 direzione : none)
Were this will produce a [none, {direzione}, {direzione}, ... ] array
The trick is to use value as your value media and set there something adequate. In this case i used the index of the value inside availableDirezione array, but you may even put set it to something even more meaningful like a unique id present in your direzione objects.

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.

Pass Dynamic Table Row Data to Modal Dialog via Delete Button

Context
I have a GET route that loads a .ejs file which adds rows of data to a table based on the length of the passed variable accounts. Here accounts is an array of dictionaries with the keys _id, type, nickname, rewards, balance, customer_id.
<% if (accounts.length > 0) { %>
<% accounts.forEach(account => { %>
<tr class="blue-grey lighten-3 account-row">
<th scope="row" class="account-id"><%= account._id %></th>
<td><%= account.type %></td>
<td><%= account.nickname %></td>
<td><%= account.rewards %></td>
<td>$<%= account.balance %></td>
<td><%= account.customer_id %></td>
<td>
<span class="table-remove">
<button type="button" class="btn btn-danger btn-rounded btn-sm my-0 remove" data-toggle="modal" data-target="#removeAccountModal">
Remove
</button>
</span>
</td>
<div class="modal fade" id="removeAccountModal" tabindex="-1" role="dialog" aria-labelledby="removeAccountModalLabel"
aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="removeAccountModalLabel">You are about to remove this account</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
CAUTION!!!
<br>
<br>
Removing this account will delete all the data associated with it. You must visit a local branch to retrieve any monies left residing in the account.
</div>
<div class="modal-footer">
<button type="button" class="btn grey darken-1" data-dismiss="modal">Cancel</button>
<form id="remove-form" action="/" method="POST">
<button id="removeAccount" class="btn btn-primary" type="submit">Remove Account</button>
</form>
</div>
</div>
</div>
</div>
</tr>
<% }) %>
Issue
There is a delete button on each row of data that opens a Bootstrap modal confirming that the user wants to indeed delete that row's data. Upon a submit in the modal, this will initiate a DELETE request in the form of a form element.
I want to pass the selected row's associated account._id variable so that I can modify the form's action attribute to /<%= account._id %>/?_METHOD=DELETE.
I am having trouble accessing the modal's parent window DOM elements.
My jQuery code is as follows:
<script>
$(document).ready(function () {
console.log("loaded and ready to go!"); // works as expected
var $remove = $(".remove"); // works as expected
console.log($remove.length); // works as expected
$(".remove").click(() => {
console.log("I'm in the modal!") // works as expected
var $parent = $(this).parent().closest("tr"); // find row
console.log($parent); // w.fn.init [prevObject: w.fn.init(0)]
var $account_id = $parent.find("th"); // find account id
console.log($account_id); // w.fn.init [prevObject: w.fn.init(0)]
console.log($account_id.text()); // returns blank type string
$("#remove-form").prop("action", "/" + $account_id + "?
_method=DELETE"); // change action attribute to account id value
})
});
</script>
Methods tried:
console.log(window.parent.$(this).closest("tr"));
// returns w.fn.init [prevObject: w.fn.init(1)]
you have placed the modal inside the forEach loop. So you dont have only one modal, instead you have one for each row. The problem here is that you assigned the same id removeAccountModal for all of them. Try to assign a unique id for each modal, for example:
<div class="modal fade" id="<%= account._id %>" tabindex="-1" role="dialog" aria-labelledby="removeAccountModalLabel" aria-hidden="true">
and on each delete button replace data-target with
data-target="#<%= account._id %>"
So you have unique modals and now you can place <%= account._id %> directly in action attribute
Thank you #dimitris tseggenes for pointing me in the right direction.
The unique ids for each modal div was imperative here. It turns out the id attribute value must not solely consist of numbers.
I refactored the id and target-data attributes to look like the following, respectively:
id="account<%= account._id %>id"
data-target=#account"<%= account._id %>id"
I have learned the following from the responses in this post:
Don't forget to make modal divs unique if you will have multiple modals, i.e. in a table and to alter the action element respectively using the data-target attribute
id attributes must not solely contain numbers

Resources