I am using dropzone in my Code Igniter Project.
With every drag of a file, dropzone creates an ajax request and my files is getting stored on the server too. But now, my requirement is that I want to send additional data (DYNAMIC) alongside the file.
With the use of params, Only static datas can be sent, but the data I want to send will be changing everytime.
This is how my code looks:
<script>
Dropzone.autoDiscover = false;
Dropzone.options.attachment = {
init: function(){
this.on('removedfile',function(file){
// console.log('akjsdhaksj');
var fileName = file.name;
$.ajax({
type: 'POST',
url: "<?php echo BASE_URL.'index.php/admin/mail_actions/deleteFile' ?>",
data: "id="+fileName,
dataType: 'html'
});
});
},
// params: {
// customerFolder: $('#toValue').substr(0, toValue.indexOf('#')),
// },
dictDefaultMessage:"Click / Drop here to upload files",
addRemoveLinks: true,
dictRemoveFile:"Remove",
maxFiles:3,
maxFilesize:8,
}
$(function(){
var uploadFilePath = "<?php echo BASE_URL.'index.php/admin/mail_actions/uploadFile' ?>";
var myDropzone = new Dropzone("div#attachment", { url: uploadFilePath});
});
</script>
Anyway I can achieve it?
I got it.
This is what I had to use
myDropzone.on('sending', function(file, xhr, formData){
formData.append('userName', 'bob');
});
Abhinav has the right and working answer I only want to give a second option to use it in the options object (for example if you have multiple Dropzone sections on one page.)
myDropzone.options.dropzoneDivID = {
sending: function(file, xhr, formData){
formData.append('userName', 'Bob');
}
};
In case you have a nested payload object - e.g. to add a name to your file and your api only accepts something like this
{
someParameter: {
image: <my-upload-file>,
name: 'Bob'
}
}
your dropzone setup would look like this
var myDropzone = new Dropzone("div#attachment", {
url: uploadFilePath,
paramName: 'someParameter[image]'
});
myDropzone.on('sending', function(file, xhr, formData){
formData.append('someParameter[image]', file);
formData.append('someParameter[userName]', 'bob');
});
I only added this as there was no example for nested parameters documented since now.
i was using JQuery and this is how worked for me :
$("#dZUpload").dropzone({
url: "ajax/upload_img_ben.php",
success: function (file, response) {
var imgName = response;
file.previewElement.classList.add("dz-success");
console.log("Successfully uploaded :" + imgName);
},
error: function (file, response) {
file.previewElement.classList.add("dz-error");
},
sending: function(file, xhr, formData){
formData.append('id', '5');
}
});
Related
I have a MVC Controller with the following signature:-
[HttpPost]
public async Task<JsonResult> SaveBrochureAsAttachment(Guid listingId, HttpPostedFileWrapper attachmentFile)
{
///some logic
}
How do I make an ajax call and send the file attachment and additional listingId parameter. Currently I am only able to send the attachment like this:-
var uploadFile = function () {
if ($('#attachmentFile').val()) {
}
else {
alert('No File Uploaded');
return;
}
var formData = new FormData($('#uploadForm')[0]);
$.ajax({
url: '/Listing/SaveBrochureAsAttachment',
type: 'POST',
data: formData,
async: false,
success: function (data) {
alert('File Uploaded');
},
error: function (jqXHR, textStatus, errorThrown) {
$("#FileUpload").replaceWith($("#FileUpload").val('').clone(true));
alert('File Uploaded Error');
},
cache: false,
contentType: false,
processData: false
});
return false;
}
Currently as you folks can see I am only able to send the attachment. How do I also send the Guid listingId to match the controller signature.
Try adding another formdata parameter:
formData.append("listingId", guidValue);
Provided you have the guid value accessible. You can use this to generate one from the client. Or create one from the server:
var guidValue = '#Guid.NewGuid()';
one approach would be to your controller accept viewmodel (a class) which contains different property you need. and use formdata.append required stuff to post to the server.
On Server side; you will need to use modelbinder so that you will get required stuff populated.
Refernce for modelbinder : https://www.dotnetcurry.com/aspnet-mvc/1261/custom-model-binder-aspnet-mvc
you can get more on google. :)
I have successfully used Dropzone to display existing files from my server. However, when I submit the form, only new files are submitted to the server, so I don't know if the user has deleted any. Essentiall I want to send the data for all the files currently displayed, including the 'mocked' files and the newly uploaded ones.
I am using autoProcessQueue: false so that I can have a separate submit button to send the data to the server.
My Code:
Dropzone.options.createListingForm = {
autoProcessQueue: false,
uploadMultiple: true,
previewsContainer: '.create-listing-form-uploads',
parallelUploads: 100,
maxFiles: 100,
addRemoveLinks: true,
init: function () {
var thisDropzone = this;
var photos = form.data('photos');
$.each(photos, function (key, photo) {
var mockFile = {
name: photo.name,
size: photo.size,
type: photo.type,
accepted: true
};
thisDropzone.files.push(mockFile); // add to files array
thisDropzone.emit("addedfile", mockFile);
thisDropzone.emit("thumbnail", mockFile, photo.path);
thisDropzone.emit("complete", mockFile);
});
}
};
form.on('click', '.create-listing-form-save-photos', function () {
$('.dropzone').get(0).dropzone.processQueue();
return false;
});
Thanks to this answer for the first part of my code:
https://stackoverflow.com/a/45701181/5482719
Each time a file (including mock Files) is removed/deleted from the dropzone, the removedfile event is fired.
You could use this event to delete the removed file from your server as follows:
myDropzone.on("removedfile", function(file) {
// 'file' parameter contains the file object.
console.log('Removed File', file);
// Delete file from server
$.ajax({
type: 'POST',
url: 'url/that/handles/delete',
data: {
fileName: file.name,
},
dataType: 'json'
}).done(function (response) {
// check repsonse, notify user
}).fail(function(resp) {
console.log('xhr failed', resp);
}).always(function(resp) {
// do nothing for now
});
});
Hope that helps.
I'm trying to add an id attribute to each file uploaded in Dropzone.js, So I can sort it later on.
This is my code:
Dropzone.options.pictureDropzone = {
paramName: "file",
addRemoveLinks: true,
init: function() {
this.on("success", function(file, response) {
file.serverId = response.id;
$(file.previewTemplate).find('.dz-preview').attr('id', "document-" + file.serverId);
});
}
};
The line
$(file.previewTemplate).find('.dz-preview').attr('id', "document-" + file.serverId);
Should add the id, but it does nothing.
Tried it with prop() too.
If I choose a different element, it does work fine. for example, this works for .dz-details
$(file.previewTemplate).find('.dz-details').attr('id', "document-" + file.serverId);
But I cannot seem to find a way to add it to the dz-preview element.
The HTML structure looks like that:
<div class="dz-preview dz-processing dz-image-preview dz-success">
<div class="dz-details"> ... </div>
<div class="dz-progress"> ... </div>
<div class="dz-success-mark"> ... </div>
</div>
Thank you for the help :)
I know this is old but if anyone is still looking for the answer: -
this.on("success", function(file, response) {
file.previewElement.id = response.id;
});
Cast the previewElement into jQuery object and perform any action.
this.on("success", function(file, response) {
$(file.previewElement).attr("id", response.id);
});
this.on("success", function(file, response) {
file.serverId = response.id;
$(".dz-preview:last-child").attr('id', "document-" + file.serverId);
});
I had similar problem but tried it through declaring a variable in javascript ,following is code :
$("#fileUpload${dropdown}").dropzone(
{
url : "uploadAdditionalFile?name="+$("#fileUpload${dropdown} div:first-child").prop('id'),
addRemoveLinks : true,
maxFiles : 1,
init : function() {
var imageId = $("#fileUpload${dropdown} div:first-child").prop('id');
this.on("maxfilesexceeded",
function(file) {
alert("Only one file can be uploaded at a time");
this.removeFile(file);
});
this.on("addedfile",
function(file) {
switch (file.type) {
case 'application/pdf':
this.emit("thumbnail",file,"/sbms/static/img/pdf.png");
break;
case 'application/msword':
this.emit("thumbnail",file,"/sbms/static/img/word.png");
break;
}
}
);
this.on('removedfile', function(file){
$.ajax({
type : "GET",
url : "removeAdditionalMediaPreviewForm?id="+imageId,
dataType : "json",
async : false,
success : function(response) {
if (response.status == 'SUCCESS') {
alert("File removed successfully.")
}else {
alert("File not removed successfully.")
}
}
});
});
},
success : function(file,response) {
var imgName = response;
file.previewElement.classList.add("dz-success");
console.log("Successfully uploaded :"+ imgName);
},
error : function(file,response, xhr) {
alert("Unable to upload file. Please check if it is a valid doc or pdf file.");
this.removeFile(file);
}
});
imageId is a variable which stores the id and is used later on while file remove.
This will fail spectacularly if the user drops multiple files.(Szczepan Hołyszewski Dec 17 '15 at 18:45);
BryanFoong answer won't fail if you set the option uploadMultiple: false. Which is set so by default. In this case Dropzone sends separate request to the server for each file. Therefore "success" event triggers for each individual file.
In case the uploadMultiple: true. Dropzone will send single request to server for all files. And "success" event will trigger once. And following code will handle that.
YourDropzoneInstance.on("success", function(file, response) {
response.files.forEach(function(file) {
file.previewTemplate.id = file.id;
})
})
Again you need to return from server array of files.
In PHP it will look like
function yourFileUploadHandler() {
...
// your server file upload implementation
$response = [
"files" => [
["id" = 1, ...],
["id" = 2, ...],
...
],
];
return json_decode($response);
}
I am trying to use jquery file upload with ember.js. What i am hoping to achieve is there is a file input and when user browse the picture and hit the upload button, the jquery file upload will upload the file and return with the location of the uploaded file then.. i will collect other data from the rest of the form and post the information using ember data, which will include the the image url and rest of the form data.
I cannot make it work, but the same code works with plain html file with php backend.
Here i have included non functional code in jsbin which include my template and app.js code
http://jsbin.com/EtOzeKI/1/edit
Here's a minimal component you can use:
// index.html
<script src="/vendor/jquery/jquery.js"></script>
<script src="/vendor/jquery-ui/ui/jquery-ui.js"></script>
<script src="/vendor/jquery-file-upload/js/jquery.iframe-transport.js"></script>/script>
<script src="/vendor/jquery-file-upload/js/jquery.fileupload.js"></script>
// components/file-upload.js
export default Ember.TextField.extend({
attributeBindings: ['name', 'data-url', 'multiple'],
tagName: "input",
type: 'file',
name: "file[]",
"data-url": function(){
return this.get("path");
}.property("path"),
multiple: true,
didInsertElement: function() {
this.$().fileupload();
}
});
// to use in your hbs template
{{file-upload path="pathToUploadTo"}}
Here's an upload button that I use in my application: It builds up an input button, and auto uploads on change.
{{view App.UploadButton groupBinding="model"}}
App.UploadButton = Ember.View.extend({
tagName: 'input',
attributeBindings: ['type'],
type: 'file',
originalText: 'Upload Finished Product',
uploadingText: 'Busy Uploading...',
newItemHandler: function (data) {
var store = this.get('controller.store');
store.push('item', data);
},
preUpload: function () {
var me = this.$(),
parent = me.closest('.fileupload-addbutton'),
upload = this.get('uploadingText');
parent.addClass('disabled');
me.css('cursor', 'default');
me.attr('disabled', 'disabled');
},
postUpload: function () {
var me = this.$(),
parent = me.closest('.fileupload-addbutton'),
form = parent.closest('#fake_form_for_reset')[0],
orig = this.get('originalText');
parent.removeClass('disabled');
me.css('cursor', 'pointer');
me.removeAttr('disabled');
form.reset();
},
change: function (e) {
var self = this;
var formData = new FormData();
// This is just CSS
this.preUpload();
formData.append('group_id', this.get('group.id'));
formData.append('file', this.$().get(0).files[0]);
$.ajax({
url: '/file_upload_handler/',
type: 'POST',
//Ajax events
success: function (data) { self.postUpload(); self.newItemHandler(data); },
error: function () { self.postUpload(); alert('Failure'); },
// Form data
data: formData,
//Options to tell jQuery not to process data or worry about content-type.
cache: false,
contentType: false,
processData: false
});
}
});
I am using dropzone.js.
When I try to delete files only the thumbnails get deleted but not the files from server.
I tried some ways but it just gives me the name of the image which was on client side and not the name on server side(both names are different, storing names in encrypted form).
Any help would be much appreciated..
Another way,
Get response from your server in JSON format or a plain string (then use only response instead of response.path),
dropzone.on("success", function(file, response) {
$(file.previewTemplate).append('<span class="server_file">'+response.path+'</span>');
});
Here, the server can return a json like this,
{
status: 200,
path: "/home/user/anything.txt"
}
So we are storing this path into a span that we can access when we are going to delete it.
dropzone.on("removedfile", function(file) {
var server_file = $(file.previewTemplate).children('.server_file').text();
alert(server_file);
// Do a post request and pass this path and use server-side language to delete the file
$.post("delete.php", { file_to_be_deleted: server_file } );
});
After the process, the preview template will be deleted by Dropzone along with file path stored in a span.
The way I handle this, is after each file is uploaded and stored on the server, I echo back the name I give the file on my server, and store it in a JS object, something like this:
PHP:
move_uploaded_file($_FILES['file']['tmp_name'], $newFileName);
echo $newFileName;
JS:
dropZone.on("success", function(file, serverFileName) {
fileList[serverFileName] = {"serverFileName" : serverFileName, "fileName" : file.name };
});
With this, you can then write a delete script in PHP that takes in the "serverFileName" and does the actual deletion, such as:
JS:
$.ajax({
url: "upload/delete_temp_files.php",
type: "POST",
data: { "fileList" : JSON.stringify(fileList) }
});
PHP:
$fileList = json_decode($_POST['fileList']);
for($i = 0; $i < sizeof($fileList); $i++)
{
unlink(basename($fileList[$i]));
}
Most simple way
JS file,this script will run when you click delete button
this.on("removedfile", function(file) {
alert(file.name);
$.ajax({
url: "uploads/delete.php",
type: "POST",
data: { 'name': file.name}
});
});
php file "delete.php"
<?php
$t= $_POST['name'];
echo $t;
unlink($t);
?>
The file will be deleteed when you click the "Remove" button :
Put this on your JS file or your HTML file (or your PHP view/action file):
<script type="text/javascript">
Dropzone.options.myAwesomeDropzone = {
// Change following configuration below as you need there bro
autoProcessQueue: true,
uploadMultiple: true,
parallelUploads: 2,
maxFiles: 10,
maxFilesize: 5,
addRemoveLinks: true,
dictRemoveFile: "Remove",
dictDefaultMessage: "<h3 class='sbold'>Drop files here or click to upload document(s)<h3>",
acceptedFiles: ".xls,.xlsx,.doc,.docx",
//another of your configurations..and so on...and so on...
init: function() {
this.on("removedfile", function(file) {
alert("Delete this file?");
$.ajax({
url: '/delete.php?filetodelete='+file.name,
type: "POST",
data: { 'filetodelete': file.name}
});
});
}}
</script>
..and Put this code in your PHP file :
<?php
$toDelete= $_POST['filetodelete'];
unlink("{$_SERVER['DOCUMENT_ROOT']}/*this-is-the-folder-which-you-put-the-file-uploaded*/{$toDelete}");
die;
?>
Hope this helps you bro :)
I've made it easier, just added new property serverFileName to the file object:
success: function(file, response) {
file.serverFileName = response.file_name;
},
removedfile: function (file, data) {
$.ajax({
type:'POST',
url:'/deleteFile',
data : {"file_name" : file.serverFileName},
success : function (data) {
}
});
}
success: function(file, serverFileName)
{
fileList['serverFileName'] = {"serverFileName" : serverFileName, "fileName" : file.name };
alert(file.name);
alert(serverFileName);
},
removedfile: function(file, serverFileName)
{
fileList['serverFileName'] = {"serverFileName" : serverFileName, "fileName" : file.name };
alert(file.name);
alert(serverFileName);
}
When you save the image in upload from there you have to return new file name :
echo json_encode(array("Filename" => "New File Name"));
And in dropzone.js file :
success: function(file,response) {
obj = JSON.parse(response);
file.previewElement.id = obj.Filename;
if (file.previewElement) {
return file.previewElement.classList.add("dz-success");
}
},
And when the dropzone is initialize..
init: function() {
this.on("removedfile", function(file) {
var name = file.previewElement.id;
$.ajax({
url: "post URL",
type: "POST",
data: { 'name': name}
});
});
return noop;
},
Now you will receive new image file and you can delete it from server
You can add id number of uploaded file on the mockFile and use that id to delete from server.
Dropzone.options.frmFilesDropzone = {
init: function() {
var _this = this;
this.on("removedfile", function(file) {
console.log(file.id); // use file.id to delete file on the server
});
$.ajax({
type: "GET",
url: "/server/images",
success: function(response) {
if(response.status=="ok"){
$.each(response.data, function(key,value) {
var mockFile = {id:value.id,name: value.name, size: value.filesize};
_this.options.addedfile.call(_this, mockFile);
_this.options.thumbnail.call(_this, mockFile, "/media/images/"+value.name);
_this.options.complete.call(_this, mockFile);
_this.options.success.call(_this, mockFile);
});
}
}
});
Server Json return for getting all images already uploaded /server/images:
{
"data":[
{"id":52,"name":"image_1.jpg","filesize":1234},
{"id":53,"name":"image_2.jpg","filesize":1234},
]}
In my case server sends back some ajax response with deleteUrl for every specific image.
I just insert this url as 'data-dz-remove' attribute, set in previewTemplate already.
As I use jquery it looks so:
this.on("success", function (file, response) {
$(file.previewTemplate).find('a.dz-remove').attr('data-dz-remove', response.deleteUrl);
});
Later this attr used to send ajax post with this url to delete file on server by removedfile event as mentioned above.
This simple solution will work for single files upload, no need for DOM manipulation.
PHP Upload Script
[...]
echo $filepath; // ie: 'medias/articles/m/y/a/my_article/my-image.png'
JS Dropzones
this.on("success", function(file, response) {
file.path = response; // We create a new 'path' index
});
this.on("removedfile", function(file) {
removeFile(file.path)
});
JS outside of Dropzone
var removeFile = function(path){
//SEND PATH IN AJAX TO PHP DELETE SCRIPT
$.ajax({
url: "uploads/delete.php",
type: "POST",
data: { 'path': path}
});
}