Express cannot process textarea value [duplicate] - node.js

This question already has answers here:
Textarea value not getting posted with form
(12 answers)
Closed 3 years ago.
I want to get value using post method in node.js using body-parser. But I always get undefined.
Below is my node.js code.
var bodyParser = require('body-parser');
var urlencodedParser = bodyParser.urlencoded({ extended: false });
app.get('/form', function (req, res) {
html += "<form action='/thank' method='post' name='form1'>";
html += "<div id='divParent'>";
html += "<div id='div1' name='formset' class='formset'>";
html += "<p>Name: <input type= 'text' name='name'></p>";
html += "<p>Sex: Male <input type='radio' class='gender' name='gender' value='male'>"
html += " Female <input type='radio' class='gender' name='gender' value='female'></p>"
html += "<p>Email: <input type='text' name='email'></p>";
html += "<p>Address:<input type='text' name='address'></p>";
html += "<p>Mobile number:<input type='text' name='mobilno'></p>";
html += "<p>Note:</p>"
html += '<textarea rows="4" cols="50" name="note" id="note" form="form1"></textarea>';
html += "</div>";
html += "</div>";
html += "<input id='input1' type='submit' value='submit'>";
html += "<INPUT type='reset' value='reset'>";
html += "</form>";
...
}
app.post('/thank', urlencodedParser, function (req, res){
var reply='';
reply += "<br>Array length is : " + req.body.name.length;
reply += "<br>Your name is : " + req.body.name;
reply += "<br>Sex is : " + req.body.gender;
reply += "<br>Your E-mail id is : " + req.body.email;
reply += "<br>Your address is : " + req.body.address;
reply += "<br>Your mobile number is : " + req.body.mobilno;
reply += "<br>Your note is : "+ req.body.note;
console.log(req.body)
res.send(reply);
});
I can get the input value, but not textarea value.
Here's what I get when I console.log(req.body)
{ name: 'Roy',
gender: 'male',
email: 'roy#topscore.com',
address: 'Bali',
mobilno: '0821' }
Why body-parser can't get req.body.note? What's the problem?

I think the textarea is not really part of the form since you do not have a form with id "form1". Either remove the form attribute from the textarea or add the attribute id to the form.

Related

NetSuite Suitelet Custom HTML | Pressing submit on the form causes the value to be null

I am creating a suitelet using custom HTML. The page displays fine, but on submit, I am not able to get the parameter values.
html = html + "<div class='row row_1'>";
html = html + "<select onchange='onItemSelect(event)' class='item_select' name='item_1'>";
html = html + "</select>";
html = html + "<input name='quantity' placeholder='Quantity' type='number' />";
html = html + "<input name='svuuom' disabled placeholder='SVU UOM' type='text' />";
html = html + "<input name='qtysvuuom' disabled placeholder='Qty in SVU UOM' type='text' />";
html = html + "<input name='lot_num' placeholder='Lot Number' type='text' />";
html = html + "<input name='exp_date' placeholder='Expiration Date' type='date' />";
html = html + "<input onChange='calcQtyRemain(event)' name='ac_weight' placeholder='Actual Weight' type='text' />";
html = html + "<input name='averageweight' disabled placeholder='Average Weight' type='number' />";
html = html + "<input name='totalqty' disabled placeholder='Total Quantity' type='text' />";
html = html + "<input name='qtyremaining' disabled placeholder='Quantity Remaining' type='text' />";
html = html + "<button class='row_1 remove nav_button' onClick='removeRow(this)'>Remove</button>";
html = html + "<input type='hidden' name='submit_data' id='submit_data' ></input>";
html = html + "</div>";
html = html + "<button class='nav_button' type='submit' >Submit</button>";
html = html + "<button id='finalize' class='nav_button' onClick='finalizeForm(event)'> Finalize</button>";
html = html + "<button class='nav_button' onClick='addRow()' class='add_row'>Add Row</button>";
html = html + "<script src='https://6511345.app.netsuite.com/core/media/media.nl?id=3240&c=6511345&h=g_fi0R_eVH-pDCr9pidg6_RMLQc"+
"A-ySTQOWrhs3FYIL3NVkc&_xt=.js' /></script>";
html = html + "</form>";
The value is being set to the hidden field 'submit_data' when the user clicks finalize. I want to grab this as a parameter on post. If I set the value='Test' on the submit_data field, I get the parameter just fine on post. The above code is on the get request.
I am also linking JS files and doing some client side functions within that. These functions set the value on submit_data field.
The issue was within the JS resource. Something was conflicting with the post action and caused the field to be null. I have resolved the issue and I am now grabbing the value perfectly.

nodeJS how to use router to add icon tag into pug file?

Hello I think it's easier to show partial lines of my code.
What I'm trying to do is when I input a zipcode, the right icon will show.
I'm using https://erikflowers.github.io/weather-icons/ this git.
for example: if NY weather condition says clear
weather condition in weather.pug should be like i.wi.wi-night-sleet
is it possible to add class name in icon tag from topic.js? or
can I use equal statement in pug flie like - if text=='clear' i.wi.wi-night-sleet
topic.js
router.post('/weather', function(req,res){
let url = `http://api.openweathermap.org/data/2.5/weather?zip=${req.body.zipcode}&units=imperial&appid=${apiKey}`
request(url, function (err, response, body) {
if(err){
res.status(500).send('Internal Server Error');
console.log('error: ' ,err);
} else {
if(req.body.zipcode.length != 5) {
res.render('topic/weather', {text: "Zipcode does not exist"})
} else {
let weather = JSON.parse(body)
let temp = weather.main.temp
let location = weather.name;
let day_weather = weather.weather[0].main;
let message = `It's ${weather.main.temp} degrees in ${weather.name}!`;
//below this I want to call icon tag that has a class name
res.render('topic/weather', {text: location + " : " + day_weather, weatherCondition: `i.wi.wi-night-sleet`});
}
}
});
})
weather.pug
extends ./homepage
block navigate
div.container-fluid
div.row.row-centered
p= text
//- space 넣을떄
= " "
if text
= date
div.col-lg-6.col-centered
form.form-group(action='/weather', method='post')
p
input(type='text', class="form-control", id="zipcode",name='zipcode', placeholder='zipcode')
p
button(type='submit', class="btn btn-primary btn-lg" style='margin-right: 10px;') Login
In your route just pass the identifying part of the icon you need:
res.render('topic/weather', {text: location + " : " + day_weather, weatherCondition: "night-sleet"});
Then here's what your pug template needs to look like:
i.wi(class= 'wi-' + weatherCondition)
or
i(class= 'wi wi-' + weatherCondition)
Either of those lines of pug will produce the same html:
<i class="wi wi-night-sleet"></i>

Change the default content of a site if the site is redirected

So I have a eventhandler for a website called "login" :
function _GetLoginEventHandler(req, res) {
var answer = _getHTMLSkeleton();
var dynamicAnswer;
if (isLogedIn == false) {
dynamicAnswer = "<h1>Login</h1>" + //creates a form for not logged users
"<form action='/login' method='post'>" +
"User name: <br>" +
'<input type="text" name="username" value="MickeyMouse">' +
"<br>" +
"Password: <br>" +
'<input type="password" name="password" value="geheim">' +
"<br><br>" +
'<input type="submit" value="Submit">' +
"</form> ";
answer = answer.replace('{title}', "Login");
answer = answer.replace("{body}", dynamicAnswer);
res.write(answer);
res.end();
}
else {
res.writeHead(302, { //if the user is loged it, it redirects to his "profile"
'Location': '/user'
});
res.end();
}
};
If the user is already logged in, it redirect him to a page called "user" which is in my case his profile:
function _GetUserEventHandler(req, res) {
var answer = _getHTMLSkeleton();
var dynamicAnswer;
if (isLogedIn == true) {
dynamicAnswer = "<h1>Logg Off</h1>" +
"<p>Your user id is: " + uID + "</p>" +
"<form action='/user' method='post'>" +
'<input type="submit" value="Submit">' + "</form>";
}
else
dynamicAnswer = "<h4>You are not allowed to see this content, you are not loged in </h4>";
answer = answer.replace('{title}', "User");
answer = answer.replace("{body}", dynamicAnswer);
res.write(answer);
res.end();
}
I want to check if the home site is redirected from (in this case) the login page so I can add to "answer" for example "You are succesfully logged in".
PS: The _getHTMLSkeleton returns the structur of a HTML page with placeholders
You can check if referrer header in your application is your login form:
req.headers.referer
if your app is setting referrer values (check origin .
or try setting header:
res.setHeader('fromLoginPage', 'true');
before redirecting user, and checking it later:
req.headers.fromLoginPage == true

Can a lodash template be used in Node.js to send HTML version of an email?

I am using Node.js to send a confirmation email when a user submits an order. I would like the email to include include all items that the user submits. The number of items will vary with each submission. I'd like the email body to include a table. Can a lodash template be used for this? Or should this be handled differently?
When I used the following code, the resulting email includes what I assume to be uncompiled code.
var tpl = _.template('<% _.forEach(items, function(item) { %><td><%- item %></td><% }); %>');
tpl({ 'items': ['Guitar', 'Harmonica'] });
var data = {
from: 'support#example.com',
to: email,
subject: 'Your Order Confirmation',
html: '<p>Thank you for submitting your order.</p>
<table>
<tr>
<thead>
<tr>
<th><strong>Items</strong></th>'
+ tpl +
// The template should insert each item here
// <td>Guitar</td>
// <td>Harmonica</td>
'</tr>
</thead>
</tr>
</table>'
};
Output in actual email sent:
function (obj) { obj || (obj = {}); var __t, __p = '', __e = _.escape,
__j = Array.prototype.join; function print() { __p +=
__j.call(arguments, '') } with (obj) { _.forEach(items,
function(item) { ; __p += ' ' + __e( item ) + ' '; }); ; } return
__p }
change:
tpl({ 'items': ['Guitar', 'Harmonica'] });
to
var html = tpl({ 'items': ['Guitar', 'Harmonica'] });
and
ng>Items</strong></th>'
+ tpl +
to
ng>Items</strong></th>'
+ html +
if you look at the docs at: https://lodash.com/docs#template
you will see the compiled function returns an output which you need to use.
You instead of using the output, you used the actual function itself.

Node.js (sails.js) wysiwyg editor - images

Is there a way to use any WYSIWYG/html editor in the sails app? I
can't find any manuals to do that. Seems like Mercury is
well-supported in Node but I can't find a way to adapt sails for it
either. :( Please guide me
OK now, it turned up to be easy to connect TinyMCE (just as easy as described on http://www.tinymce.com/wiki.php/Installation ). So now another major question comes out: is there any Node.js connector to any editor for uploading images and stuff?
Or just how can I allow user to upload an image and insert it to a post body?
Thanks
Yay! Finally did it!
At last I used the CKEditor and it worked! Check it out:
download the editor at http://ckeditor.com/download
put it into the assets folder of your project
add config.filebrowserUploadUrl = '/uploader'; to your ckeditor/config.js file
add an action for uploads in your controller :
upload_file : function(req, res) {
var fs = require('fs');
console.log(req.files);
fs.readFile(req.files.upload.path, function (err, data) {
var newPath = 'assets/files/' + req.files.upload.name;
fs.writeFile(newPath, data, function (err) {
if (err) res.view({err: err});
html = "";
html += "<script type='text/javascript'>";
html += " var funcNum = " + req.query.CKEditorFuncNum + ";";
html += " var url = \"/files/" + req.files.upload.name + "\";";
html += " var message = \"Uploaded file successfully\";";
html += "";
html += " window.parent.CKEDITOR.tools.callFunction(funcNum, url, message);";
html += "</script>";
res.send(html);
});
});
}
add a route for this action:
'/uploader' : {
controller : 'post',
action : 'upload_file'
}
make a folder (assets/files for me) for uploads
finally, change the form putting ckeditor in:
block body
script(type="text/javascript", src="/ckeditor/ckeditor.js")
form(action='/posts/create', method="post", enctype="multipart/form-data")
p Title
input(type='text', name='title')
p Body
textarea(name='body', id='ck')
script.
CKEDITOR.replace( 'ck' );
hr
input(type='submit', value='Сохранить')
(in jade here)
That's all! Enjoy WYSIWYG :)
The above answer will work (I gave it the up vote), but if you have the csrf token enabled on the site you need to do a few extra things (I would leave a comment but my rep is not high enough yet):
Add the standard csrf hidden input on the form that ckeditor is being used in:
<input type="hidden" name="_csrf" value="<%= _csrf %>" id="csrf" />
Next, add the following lines to ckeditor/ckeditor.js around line 498.
var csrf = document.getElementsByName("_csrf");
var token = csrfitems[0].defaultValue;
You then need to add the hidden input on the form that the uploader uses on line 499 of ckeditor.js
<input type="hidden" name="_csrf" value="' + token + '" id="csrf" />
Here is the full line 499 just to see it in context:
var csrf = document.getElementsByName("_csrf");var token = csrfitems[0].defaultValue;
d.$.write(['<html dir="'+g+'" lang="'+i+'"><head><title></title></head><body style="margin: 0; overflow: hidden; background: transparent;">','<form enctype="multipart/form-data" method="POST" dir="'+g+'" lang="'+i+'" action="',CKEDITOR.tools.htmlEncode(f.action),
'"><label id="',a.labelId,'" for="',h,'" style="display:none">',
CKEDITOR.tools.htmlEncode(f.label),
'</label>
<input type="hidden" name="_csrf" value="' + token + '" id="csrf" /><input style="width:100%" id="',h,'" aria-labelledby="',a.labelId,'" type="file" name="',CKEDITOR.tools.htmlEncode(f.id||"cke_upload"),
Hopefully this saves some people the headaches I had to go through. This might not be the most elegant solution but it will allow the uploader to work across your sails site now.

Resources