Get the status of toggle button via req.body when multiple buttons are generated dynamically and the text on the button will change - node.js

I'm currently trying to implement a form which has multiple toggle button.
For example, something like this:
The number of the options will be different each time.
For example, if the title is Chef's pizza, the option may be "Add cheese", "Add extra tomato", and "Add black olive". There can be a large number of options (like 100s) depending on the item.
The text of the toggle button will be changed from "Select" to "Selected" or vice versa.
So far, I was able to implement toggle buttons with changing the text on it. However, I'm currently facing challenge how I can get the status of the toggle buttons via req.body.
I'm using node + express + Bootstrap 5 + EJS + mongoDB.
JQuery is also used to toggle the text on the switch.
I included console.log(req.body) to the controllers js file which is called from route js file but the result is as the following:
req.body
{ post: { comment: 'Please remove tomato' } }
As you can see, it only includes the input from text form("Please remove tomato"). How can I get the status of each toggle button (selected/unselected) via this req.body so I can use them in the next process(store those to mongoDB)?
As the number of the options are different (and can be large) for each item, I'm thinking to generate the toggle buttons with something like name="<%= optionIdFromMongoDB %>" for the name field of the form tag of for each options and was wondering how I can collect the result via req.body for each options.
Following is the code.
[selectItem.ejs]
<head>
<script src="https://code.jquery.com/jquery-3.6.1.min.js" integrity="sha256-o88AwQnZB+VDvE9tvIXrMQaPlFFSUTR+nldQm1LuPXQ=" crossorigin="anonymous"></script>
<script type="text/javascript" src="/javascripts/external.js"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bs-custom-file-input/dist/bs-custom-file-input.js"></script>
</head>
<body>
<div class="row">
<h1 class="text-center">Select Option</h1>
<div class="col-md-6 offset-md-3">
<form id="sub-form" action="/posts/<%= order._id %>/review" method="POST">
<div class="mb-3">
<label class="form-label" for="title">Title</label>
<h3>Chef's salad</h3>
</div>
Add cheese
<span id="buttonsend" class="notsosmall pink button">
<input form="sub-form" type="checkbox" class="btn-check" id="btn-check" autocomplete="off" name="post[toggle]">
<span class="btn btn-primary" for="btn-check" name="post[toggleA]" value="unselected">Select</span>
<span class="btn btn-primary" for="btn-check" style="display:none" name="post[toggle]" value="selected">Selected</span>
</span>
<br>
Add bacon
<span id="buttonsend" class="notsosmall pink button">
<input form="sub-form" type="checkbox" class="btn-check" id="btn-check" autocomplete="off" name="post[toggle]">
<span class="btn btn-primary" for="btn-check" name="post[toggleB]" value="unselected">Select</span>
<span class="btn btn-primary" for="btn-check" style="display:none" name="post[toggle]" value="selected">Selected</span>
</span>
<div class="mb-3">
<button class="btn btn-lg btn-primary font-weight-bold border-white text-white">Post</button>
</div>
</form>
</div>
</div>
</body>
[external.js (used to toggle the text on the button)]
$(document).ready(function(){
$('span#buttonsend').click(function(){
$('span',this).toggle();
});
});
[/routes/posts.js]
const express = require('express');
const router = express.Router();
const posts = require('../controllers/posts')
router.route('/posts/:id/review')
.post(isLoggedIn, catchAsync(posts.review))
[/controllers/posts.js]
module.exports.review = async (req, res, next) => {
console.log("req.body")
console.log(req.body)
// some more codes here
res.render('posts/review')
}
Thank you,

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());
});

Autofill checkbox using string query in url but specifying a fieldset

I'm trying to get filtered data from a webform more quickly. Basically I want to use URL input to specify a date and to precheck a checkbox. I'm getting stuck with how to specify the check box as I'm not sure what the value should be.
<form action="/xxx/yyy" class="form-inline d-flex justify-content-end" method="get"> <div class="input-group input-group-lg mb-2">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-calendar"></i></span>
</div>
<input type="text" name="from" value="" class="form-control datetimepicker-input" id="datetimepicker7" data-toggle="datetimepicker" data-target="#datetimepicker7" autocomplete="false">
<div class="input-group-append">
<button type="submit" class="btn btn-dark"><i class="fas fa-arrow-right"></i></button>
</div>
</div>
</form>
####snip and skip to the part of the form I wish to pre-check####
<fieldset id="departureGatewayFilters">
<div class="form-check">
<input class="form-check-input" type="checkbox" value="AMS" id="departureGatewayCheck_AMS">
<label class="form-check-label" for="departureGatewayCheck_AMS">
AMS
</label>
</div>
So far I'm using URL string: /xxx/yyy?from=2020-03-05 - what would I need next to pre-check the checkbox as well?
Thanks in advance!
Clare
Getting your checkbox checked and also getting value of the checkbox just through URL string is little bit troublesome. But you can try this :
You can assign unique name to the checkbox.
<input class="form-check-input" type="checkbox" name="checkbox_1" id="departureGatewayCheck_AMS">
And then what you can do is pass the value of checkbox through URL string. For example :
/xxx/yyy?from=2020-03-05&checkbox_1=test.
Now, using javascript you can parse URL strings and get your search params, compare it and get your checkbox checked.
<script lang="javascript">
var url_string = window.location.href ; //gets current URL
var url = new URL(url_string); // instantiate string as URL object
var c = url.searchParams.get("checkbox_1"); //get the params
if(c == "test") {
document.getElementById("departureGatewayCheck_AMS").checked = true; //checks your checkbox
}
</script>
Hope it helps ! Have a good day!
I think all you need to do is add a (checked="true") argument to your input tag your code should look like this then:
<div class="form-check">
<input class="form-check-input" checked="true" type="checkbox" value="AMS" id="departureGatewayCheck_AMS">
<label class="form-check-label" for="departureGatewayCheck_AMS">
AMS
</label>
</div>
Hope this helps
If you want to make the checkbox departureGatewayCheck_AMS checked by default, it is sufficient to edit its code like this:
<input class="form-check-input" type="checkbox" value="AMS" name="departureGatewayCheck_AMS" id="departureGatewayCheck_AMS" checked> AMS
If the checkbox is selected, since its "value" attribute is "AMS",your url (if you submit the form via GET) would be something like:
/xxx/yyy?from=2020-03-05&departureGatewayCheck_AMS=AMS
Complete solution for your requirement:-
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css">
<link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datetimepicker/4.17.47/css/bootstrap-datetimepicker.min.css" integrity="sha256-yMjaV542P+q1RnH6XByCPDfUFhmOafWbeLPmqKh11zo=" crossorigin="anonymous" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js">
<div class="container">
<form class="form-inline d-flex justify-content-end" method="get"> <div class="input-group input-group-lg mb-2">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-calendar"></i></span>
</div>
<input type="text" name="from" value="" class="form-control datetimepicker-input" id="datetimepicker7" autocomplete="false">
<div class="input-group-append">
<button type="submit" class="btn btn-dark"><i class="fas fa-arrow-right"></i>
</button>
</div>
</div>
<fieldset id="departureGatewayFilters">
<div class="form-check">
<input class="form-check-input" name="checkname" type="checkbox" value="AMS" id="departureGatewayCheck_AMS">
<label class="form-check-label" for="departureGatewayCheck_AMS">
AMS
</label>
</div>
</fieldset>
</form>
</div>
</body>
<script type="text/javascript">
$(function () {
var url_string = "https://www.example.com/page?from=2020-12-12&checkname=1";//window.location.href ; //gets current URL
var url = new URL(url_string); // instantiate string as URL object
var date=url.searchParams.get("from");
var check = url.searchParams.get("checkname"); //get the params
alert(date);
alert(check);
if(check) {
$( "#departureGatewayCheck_AMS" ).prop( "checked", true );
}
$('.datetimepicker-input').datetimepicker({
format: 'YYYY-MM-DD',
defaultDate: date,
});
});
</script>

Pass Data from MongoDB to Bootstrap Modal Using EJS

I'm building an express app which comprises ejs and bootstrap for rendering views, node and express for server side and mongodb for storage.
I have a form (contained in a modal) in which I can post data. After submitting the form, the values are saved to mongodb.
Here's the snippet for edit:
<td><%= cats.image %></td>
<td><a type="button" data-toggle="modal" data-target="#editCategory" href="#">Edit</a>
// without using the modal above, I'll have to create a new page to edit only one item
// I think it's a waste of page space and bad UX, so I am going with the modal
<!--<a href="/admin/categories/edit-category/<%= cats._id %>">--> // I want to get the values from this id and show in the modal
<!--<button type="button" class="btn btn-primary btn-sm">Edit</button>-->
<!--</a>-->
</td>
When I click on the edit button, I want to get the id of the item and retrieve it's values to display in the modal.
Here's the full modal view:
<!-- Edit Category Modal -->
<div class="modal fade" id="editCategory" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<form action="/admin/categories/edit-cateory/<%= %>" method="post" enctype="multipart/form-data">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">×</span> </button>
<h4 class="modal-title" id="myEditCategoryLabel">Edit Category</h4>
</div>
<div class="modal-body">
<div class="form-group">
<label>Title</label>
// this value should come from the category id but don't know how to pass it
<input value="<%= %>" name="title" class="form-control" type="text" placeholder="Category Title"> <br>
<label>Upload Image</label>
<input class="form-control selImg" type="file" accept="image/*" onchange="showImage.call(this)">
<img src="#" class="imgPreview" style="display: none; height: 100px; width: 100px">
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
<button type="submit" class="btn btn-primary">Save Edits</button>
</div>
</form>
</div>
</div>
</div>
How can I pass the data from mongodb to the modal using ejs?
Any help will be much appreciated.
Store your ID somewhere: hidden inputs or data-attributes.
<tr data-id="<%= cats.id %>">
<td><%= cats.image %></td>
<td>
<a type="button" class="edit" href="#">Edit</a>
</td>
</tr>
Then, create an onclick event handler such that, upon clicking on the button,
it will fetch the extra data via AJAX and open the modal dynamically after you get a response.
$('a.edit').click(function (e) {
e.preventDefault();
var tr = $(this).closest('tr'),
modal = $('#editCategory');
// make AJAX call passing the ID
$.getJSON('/admin/categories/get-cateory/' + tr.data('id'), function (data) {
// set values in modal
modal.find('form').attr('action', '/admin/categories/get-cateory/' + tr.data('id') );
modal.find('[name=title]').val( data.title );
// open modal
modal.modal('show');
});
});
You will need to create a route for fetching a single object (I'll leave that to you)
app.get('/admin/categories/get-cateory/:id', function (req, res) {
// TODO: fetch data using passed ID
// once you have the data, simply send the JSON back
res.json(data);
});

How to send data using socket in nodejs

I want to send a data from html page to nodejs server.I want by pressing a button "desactivate my account" a prompt window apperas and when a user enter yes the username of connected user was sent to server to destroy the model from the database.
profile.ejs:
<div class="form-group">
<label class="col-md-3 control-label">Username:</label>
<div class="col-md-8">
<input class="form-control" id="username" name="username" value=<%= user.username %> type="text">
<div class="form-group">
<label class="col-md-3 control-label"></label>
<div class="emaillogin">
<a class="btn btn-default email-signin-button" role="button" onclick="desactive()"><i class="fa fa-trash-o fa-fw"></i> <span class="network-name" >Desactivate my account</span></a>
</div>
</div>
<script src="socket.io/socket.io.js"></script>
<script>
function desactive(){
var desactiv=prompt("Are you sure to desactive your account?");
var maj=desactiv.toUpperCase();
if(maj =="YES"){
var socket=io.connect();
var user1=$("#username").value;
socket.emit("desactiv",user1);
}
else{
alert("no");
}
}
</script>
The problem with the function mentioned below I can't send the username of the user I got null in the server side.However the user.username was displayed on the html page.what's my mistake?
jQuery object doesn't have value property - it's $("#username").val(); method
var socket=io.connect();
var user1=$("#username").val();
// not
var user1=$("#username").value;

model undefined on page reload

I'm trying example from this site. It works fine. But if i separate views,models,routers into separate file it gives me a problem. There is 3 views. WineList view, WineListItemView and winedetails view. WineList view takes collection of wine models as model and winelistItem and winedetails view takes wine as a model.
Router's code is like this
var app = app || {};
app.AppRouter = Backbone.Router.extend({
routes:{
"":"list",
"wines/:id":"wineDetails"
},
initialize:function () {
$('#header').html(new app.HeaderView().render().el);
},
list:function () {
this.wineList = new app.WineCollection();
this.wineListView = new app.WineListView({model:this.wineList});
this.wineList.fetch();
$('#sidebar').html(this.wineListView.render().el);
},
wineDetails:function (id) {
if(this.wineList == undefined)
{
this.wineList = new app.WineCollection();
this.wineListView = new app.WineListView({model:this.wineList});
this.wineList.fetch();
$('#sidebar').html(this.wineListView.render().el);
}
this.wine = this.wineList.get(id);
if (app.router.wineView) app.router.wineView.close();
this.wineView = new app.WineView({model:this.wine});
$('#content').html(this.wineView.render().el);
}
});
On page load it fetches models from server and displays list of wines in sidebar div of page. When i click on particular wine item its details will be displayed in content div of page. That all works fine. But when i reload that page which now contains details of particular,wine model of Winedetails view gives undefined .
I'm intializing the router on main page like this
app.js
var app = app || {};
$(function() {
})
app.router = new app.AppRouter();
Backbone.history.start();
index.html
<!DOCTYPE HTML>
<html>
<head>
<title>Backbone Cellar</title>
<link rel="stylesheet" href="../css/styles.css" />
</head>
<body>
<div id="header"><span class="title">Backbone Cellar</span></div>
<div id="sidebar"></div>
<div id="content">
<h2>Welcome to Backbone Cellar</h2>
<p>
This is a sample application part of of three-part tutorial showing how to build a CRUD application with Backbone.js.
</p>
</div>
<div>
Next page
</div>
<!-- Templates -->
<script type="text/template" id="tpl-header">
<span class="title">Backbone Cellar</span>
<button class="new">New Wine</button>
</script>
<script type="text/template" id="tpl-wine-list-item">
<a href='#wines/<%= id %>'><%= name %></a>
</script>
<script type="text/template" id="tpl-wine-details">
<div class="form-left-col">
<label>Id:</label>
<input type="text" id="wineId" name="id" value="<%= id %>" disabled />
<label>Name:</label>
<input type="text" id="name" name="name" value="<%= name %>" required/>
<label>Grapes:</label>
<input type="text" id="grapes" name="grapes" value="<%= grapes %>"/>
<label>Country:</label>
<input type="text" id="country" name="country" value="<%= country %>"/>
<label>Region:</label>
<input type="text" id="region" name="region" value="<%= region %>"/>
<label>Year:</label>
<input type="text" id="year" name="year" value="<%= year %>"/>
<button class="save">Save</button>
<button class="delete">Delete</button>
</div>
<div class="form-right-col">
<img height="300" src="../pics/<%= picture %>"/>
<label>Notes:</label>
<textarea id="description" name="description"><%= description %></textarea>
</div>
</script>
<!-- JavaScript -->
<script src="js/lib/jquery.min.js"></script>
<script src="js/lib/underscore.js"></script>
<script src="js/lib/backbone.js"></script>
<script src="js/models/WineModel.js"></script>
<script src="js/collections/WineListCollection.js"></script>
<script src="js/Views/WineListView.js"></script>
<script src="js/Views/WineListItemView.js"></script>
<script src="js/Views/WineDetailsView.js"></script>
<script src="js/Views/HeaderView.js"></script>
<script src="js/routers/routers.js"></script>
<script src="js/app.js"></script>
</body>
</html>
I'm new to this backbone technology. please tell me what am i missing
this.wineList.fetch();
fires an asynchronous request to your server, which means that the content will arrive (or not) at some point after executing this line, but your application execution continues whether the response arrived or not. On page reload (assume you have wines/:id in the URL) first you have to fetch the complete list of wines before accessing any particular wine from the collection.
You have to wait until is download the collection, and access the wine with id, after this request is finished.
So after initiating the request continue your application logic in the success callback:
this.wineList.fetch({
success: function(model) {
...
this.wine = model.get(id);
...
}
});

Resources