Error : need help to upload picture with Dropzone.js & Node.js - node.js

I would like to create a web app with Express and Node.js. I'm currently trying to let user uploads a profile picture and I use Dropzone.js. Here, what I did for now :
<script type="text/javascript">
Dropzone.options.ppDrop = {
paramName: username,
maxFilesize: 10, // MB
maxFiles : 1,
uploadMultiple = false,
acceptedFiles : "image/*",
dictDefaultMessage : "Drop files here or click to upload"
};
</script>
<form action="/PPupload" method="post" class="dropzone" id="ppDrop" enctype="multipart/form-data">
<div class="fallback">
<input name="pic" type="file" />
</div>
</form>
But it doesn't work. What I did wrong ?
I also need help to define a route that could store the image in an internal folder and display it after the user confirms his choice. How I could do that ? Many thanks in advance !

You're trying to set an object property with an = instead of a :. The fixed code would look like this:
Dropzone.options.ppDrop = {
paramName: username,
maxFilesize: 10, // MB
maxFiles : 1,
uploadMultiple : false,
acceptedFiles : "image/*",
dictDefaultMessage : "Drop files here or click to upload"
};

Related

Multer multiple Images Update Form

I've been trying without success to make an update a form that contains multiple inputs for multiple images with Multer.
I managed to make the Create form, I used an upload.files({name: "image1", name: "image2}), etc. The thing is when I created the Update form and when I want to Edit a text field only I get an undefined error since no images files are found.
So I came up with an approach to save the previous (or current image) in and oldImage and assign this in case there is no imagen update.
Here is my code from the controller:
update: (req,res)=>{
let data_games3 = JSON.parse(fs.readFileSync(path.join(__dirname, '../baseDeDatos/data_games3.json')))
req.body.id = req.params.id
req.body.img_1 = req.files ? req.files.img_1[0].filename : req.body.oldImage1
req.body.img_2 = req.files ? req.files.img_2[0].filename : req.body.oldImage2
req.body.img_3 = req.files ? req.files.img_3[0].filename : req.body.oldImage3
req.body.img_4 = req.files ? req.files.img_4[0].filename : req.body.oldImage4
req.body.img_5 = req.files ? req.files.img_5[0].filename : req.body.oldImage5
let gamesUpdate = data_games3.map( games => {
if(games.id == req.body.id){
return games = req.body
}
return games
})
let gameActualizar = JSON.stringify(gamesUpdate, null, 2)
fs.writeFileSync(path.join(__dirname,'../baseDeDatos/data_games3.json'), gameActualizar);
res.redirect('/admin')
}
I can update an image only if the input receives an image. Here is my Edit View trying to store in the input name "oldImage1" a value with current img.
<form action="/admin/edit/<%= gameToEdit.id%>?_method=PUT" method="POST" enctype="multipart/form-data">
<input type="hidden" name="oldImage1" value="<%= gameToEdit.img_1%>" >
<input type="hidden" name="oldImage2" value="<%= gameToEdit.img_2%>" >
<input type="hidden" name="oldImage3" value="<%= gameToEdit.img_3%>" >
<input type="hidden" name="oldImage4" value="<%= gameToEdit.img_4%>" >
<input type="hidden" name="oldImage5" value="<%= gameToEdit.img_5%>" >
Im working with a JSON file as a DB.
The update works great but only if I update all the fields for images too.

How to reference data from vue,js pug template?

Basically I am trying to make a permalink from an event name. When I get the value from the event name using v-model it works but how do I put the converted permalink back in another input box in pug?
This works:
"P {{message}}",textarea(rows="2") {{message}}
but when i try the following:
input(value="{{message}}"),input(value={{message}}),input(value=#{{message}}),input(value=#{{message}}),input(value=#{message})
Pug does not render it & shows an indent error.
My question is how do I bind or reference data from Vue in input values ?
Pug template:
.col-md-12(style="padding:0px;")
.col-md-2.labelcont
label.labeltext Event Name :
.col-md-10
input(
type="text"
class="form-control"
placeholder="Event Name"
v-model="eventname"
)
.col-md-12(style="padding:0px;")
.col-md-2.labelcont
label.labeltext Permalink :
.col-md-10
textarea(
type="text"
class="form-control"
placeholder="Event Permalink"
) {{eventpermalink}}
Vue.js code:
var basicinfo = new Vue({
el: '#basic',
data: {
eventname: '',
eventpermalink: '',
}
})
basicinfo.$watch('eventname', function (newValue, oldValue) {
basicinfo.eventpermalink = basicinfo.eventname.replace(/[^a-zA-Z0-9 ]/g,'').replace(/ +/g,'-').toLowerCase();
})
You can use the v-bind directive. This way, you can bind any HTML element's attribute to a value whether it's calculated or a reference to your props or data.
In your case, it would be something like this:
input(type="text" class="form-control" placeholder="Event Name"
v-model="eventname" v-bind:value="YOUR-DATA-OR-WHATEVER")
Look the official documentation for further reading:
https://v2.vuejs.org/v2/guide/syntax.html

In Node-RED, how do I upload to a node with the given configuration and retrieve the configuration later?

I am using Node-RED on Bluemix, I want to let the user upload a document, here is the relevant code fragment in a function/template of a flow
<form action="/upload" method="POST">
<h1>Upload PDF</h1>
<input type="file" name="myFile" />
<input type="submit" />
</form>
When I run it, I chose a file and press 'submit', but then comes the message
Cannot POST /upload
Then I went to http://flows.nodered.org/node/node-red-contrib-http-multipart
, in the example there it says
You can upload to a node with the following configuration:
[{ "name": "myFile" }]
and access the files using the following function on the out port of the node
var fields = msg.req.fields;
msg.fields = Object.keys(fields);
var myFile = fields["myFile"][0];
msg.localFilename = myFile.path
...
1) How can I upload a node with the configuration?
2)Once I get the file name, how do I retrieve it to be sent to the next services? -the next service is 'Conversion' - it takes in the file name.
To make it work, you need :
1- a classic http node connected to a html node where you put your form :
<form enctype="multipart/form-data" action="/fileUploaded" method="POST">
<input type="file" name="myFile" />
<input type="submit" />
</form>
2- Then you put your HTTP multipart node with Fields :
[{ "name": "myFile"}]
You link that node to a function node with the following code :
var fields = msg.req.files;
msg.fields = Object.keys(fields);
var myFile = fields["myFile"][0];
var fs = global.get('fs');
var inStr = fs.createReadStream(myFile.path);
var outStr = fs.createWriteStream('/app/public/upload/testUpload');
inStr.pipe(outStr);
msg.localFilename ='/upload/testUpload'
return msg;
You will need to have a folder named "upload" under /app/public/
You will also need 'fs' :
In bluemix-settings.js in functionGlobalContext add fs:require('fs')
In package.json, add "fs":"x.x"
The file will be copied there : /app/public/upload/testUpload
Then we will be able to access it via msg.localFilename in the next node, for example in a HTML page like this :
<html>
<body>
<h1>Job Done</h1>
File uploaded here
</body>
</html>
install multer for node-red and then restart node-red.
npm install node-red-contrib-http-multipart
After you are done with the installation correctly, you will see httpInMultipart Node.
basic html file upload code:
<form action="/upload" enctype="multipart/form-data" method="POST">
<input type="file" name="myFile" />
<input type="submit" />
</form>
httpInMultipart->Function->Http Response Node
Configure the httpInMultipart Node:
method: POST
url: /upload
Fields: [ { "name": "myFile"} ]
In function node Write the following code:
var file = msg.req.files;
var filesize
msg.test=file;
var localFilenamePath = file.myFile[0].path;
var fileSize = file.myFile[0].size;
var response={};
if(msg.test)
{
response.statusCode=0;
response.localFilenamePath=localFilenamePath;
response.fileSize = fileSize;
response.sendMessage="Successful";
}
else
{
response.statusCode=1;
response.sendMessage="Failed";
}
msg.payload=response;
return msg;
And Voila! We are done!

Upload a file with ServiceStack ss-utils.js

I have a job application form as part of a site built on ServiceStack. I am attempting to use the included ss-utils.js to leverage built-in Fluent Validation, but my form doesn't post the user's file upload. Here's the relevant snippet of the form:
<form id="form-careerapplication" action="#(new CreateCareerApplication().ToPostUrl())" method="post">
<div class="error-summary"></div>
<div class="form-group">
<label>
Upload Resume
</label>
<input type="file" id="Resume" name="Resume" />
<span class="help-block"></span>
</div>
<input type="hidden" name="Id" value="#Model.Id" />
<input type="submit" value="Submit Application" />
</form>
<div id="success" class="hidden">
Thank you for your application.
</div>
$("#form-careerapplication").bindForm({
success: function (careerApplicationResponse) {
$("#form-careerapplication").addClass("hidden");
$("#success").removeClass("hidden");
},
...
Is there something I'm missing in ss-utils.js? Or is there a way of overriding / supplementing the submit behavior to use FormData?
Uploading files via a HTML FORM requires a enctype="multipart/form-data", e.g:
<form id="form-careerapplication" action="#(new CreateCareerApplication().ToPostUrl())"
method="post" enctype="multipart/form-data">
...
</form>
If you want to change support multiple file uploads or change the appearance of the UI Form I recommend the Fine Uploader, there's an example showing how to use Fine Uploader on the HTTP Benchmarks Example.
Whilst Imgur has a simple client HTML and Server example.
Turned out I can use the beforeSend option as part of the configuration passed into bindForm to override the data being sent. Its a bit of a hack, but it worked and I keep the original ss-utils.js fluent validation!
$("#form-careerapplication").bindForm({
success: function (careerApplicationResponse) {
....
},
error: function (error) {
....
},
contentType: false,
processData: false,
beforeSend: function (x, settings) {
var fd = new FormData();
// Tweaked library from https://github.com/kflorence/jquery-deserialize/blob/master/src/jquery.deserialize.js
// Used to translate the serialized form data back into
// key-value pairs acceptable by `FormData`
var data = $.fn.deserialize(settings.data);
$.each(data, function (i, item) {
fd.append(item.name, item.value);
});
var files = $('#form-careerapplication').find("input:file");
$.each(files, function (i, file) {
fd.append('file', file.files[0], file.files[0].name);
});
settings.data = fd;
}
});

Uploadifive does not apply on dynamically created INPUT elements

This is my uploadifive setup:
Inside body:
<div id="file_rows_wrapper">
<div class="file_row">
<input class="file_upload" name="file_upload" type="file" multiple="false">
</div>
</div>
Add Another File
While this is the javascript part:
$(function() {
uploadify();
});
function uploadify() {
<?php $timestamp = time();?>
$('.file_upload').uploadifive({
'auto' : true,
'checkScript' : '/files/check_exists',
'formData' : {
'timestamp' : '<?php echo $timestamp;?>',
'token' : '<?php echo md5('hiall' . $timestamp);?>'
},
'queueID' : 'queue',
'uploadScript' : '/files/upload_file',
'multi' : false,
'buttonText' : 'Upload File',
});
};
function add_file()
{
var file = $('.file_row:first').clone();
file.css('margin-top', '20px');
file.fadeIn().appendTo($('#file_rows_wrapper'));
uploadify();
}
All works as expected. The "file_row" div is being cloned but when clicking on the "Add Another File" and choosing the local file, nothing happens. There is no upload. If I maually copy the "file_row" div more times then the upload works fine, even more uploads at once. What am I doing wrong?
I think you need a unique id in your file input to have multiple instances on one page.

Resources