NodeJS send to POST also unchecked input - node.js

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.

Related

Semantic UI: get current dropdown search input text

I'm trying to filter some results I will get from an api using Semantic UI's dropdown search component.
The issue is that I don't know how to get the text I'm typing in the input field
The dropdown search I have:
<div class="ui fluid search selection dropdown" id="user-dropdown">
<input id="user-dropdown-input" name="country" type="hidden">
<i class="dropdown icon"></i>
<div class="default text">Search...</div>
<div class="menu" id="user-dropdown-menu">
<div class="item" data-value="af">
<span class="description">123</span>
<span class="text">User123</span>
</div>
<div class="item" data-value="af">
<span class="description">123</span>
<span class="text">User123</span>
</div>
<div class="item" data-value="af">
<span class="description">123</span>
<span class="text">User123</span>
</div>
</div>
</div>
How dropdown is initialized:
$(document).ready(function () {
$('.ui.dropdown').dropdown({
clearable: true,
fullTextSearch: true
});
});
What I tried:
$('#user-dropdown').on('keyup', function () {
let input = $('#user-dropdown');
console.log('Val: ' + input.dropdown().val());
// also tried: $('#user-dropdown-input').val()
// $('#user-dropdown-input').html()
// $('#user-dropdown-input').text()
});
Basically what I want is if I type "abc" to print the value "abc" into the console, but I don't know how to get that value.
what worked for me was searching the input used for search that looks like:
<input class="search" autocomplete="off" tabindex="0">
and I added a type to this input
document.getElementsByClassName('search').type = 'text';
and then got the value by class on keyup
$('.search').keyup(function() {
console.log($(this).val());
});

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.

Retrieving value from input in EJS with NodeJS

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

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>
<%}%>

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