I am a bit stuck here and I need help..
I am trying to make drag and drop file upload in my website, I have started from scratch since I could not find any plugin that will fit my needs.
this is what I have so far:
File Drop detection:
var dropzone = document.getElementById('holder');
dropzone.ondragover = function(){
this.className = 'well pull-left display-ex-pic drag_hover';
return false;
}
dropzone.ondragleave = function(){this.className = 'well pull-left display-ex-pic'; return false;}
dropzone.ondrop = function(e){
e.preventDefault();
this.className = 'well pull-left display-ex-pic';
readURLs(e.dataTransfer.files);//display the pictures
images = e.dataTransfer.files;
images_obj = e.dataTransfer;
}
submitting the form through AJAX:
formImages = new FormData();
var status = $('#status');
$('#image_upload').hide();
$('form').ajaxForm({
beforeSend: function() {
$('#image_upload').show();
$('#math li .mathquill-editable').each(function() {
a = $('#math-text').val();
$('#math-text').val(a + $(this).mathquill('latex') + '[{line}]');
});
for (var x = 0; x < images.length; x = x + 1) {
formImages.append(images[x].fileName, images[x]);
}
},
data: {'files[]': formImages},
uploadProgress: function(event, position, total, percentComplete) {
var percentVal = percentComplete + '%';
$('#image_upload').attr('aria-valuenow', percentComplete).css('width', percentComplete + '%').html(percentComplete + '%');
},
complete: function(xhr) {
status.html(xhr.responseText);
}
});
Now my problem is that after the user drops the files the files get into a files array using e.dataTransfer.files and then I want to submit those files with a progress bar along with all of the form data using the "jQuery Form Plugin" from here http://malsup.com/jquery/form/.
Does anyone know how is it possible to send files using the "jQuery Form Plugin" manually?
I just happen to found this plugin and it works perfectly in very short time of implementation.
http://www.dropzonejs.com/#installation
Basically:
Include the plugin
Include the HTML
Code your File
Receiver at server side ( example included in the URL )
Adjust
CSS.
Related
I'm trying the print button and others when rendering a file using pdf.js. I tried using CSS and it works for Chrome but not Internet Explorer. For Internet Explorer I used javascript. JS works when I load one file but subsequent files are still showing the buttons.
viewer.html
<script type="text/javascript">
$(function () {
$('#print').hide();
$('#viewBookmark').hide();
$('#openFile').hide();
});
</script>
viewer.css
button#openFile, button#print, a#viewBookmark {
display: none;
}
default.cshtml
$('.file').on('click touchend', function (e) {
e.preventDefault();
if ($(this).hasClass('disabled'))
return;
var path = $(this).data('path').replace("\\\\", "http://").replace("#pdfFolder", "Uploads");
var name = $(this).data('name');
var lastname = $(this).data('lastname');
name = name.length > 8 ?
name.substring(0, 5) + '...' :
name.substring(0, 8);
lastname = lastname.length > 8 ?
lastname.substring(0, 5) + '...' :
lastname.substring(0, 8);
var tabCount = $('#tabs li').size();
var uuid = guid();
$(this).attr('data-position', uuid);
$('#content').css('display', 'block');
if (tabCount === 5) {
$('#maximumTabsModal').modal('show');
} else {
$(this).addClass('disabled')
$('<li role="presentation" data-position="' + uuid + '">' + name + '<span class="close"></span><br/>' + lastname + '</li>').appendTo('#tabs');
$('<div class="tab-pane" id="panel' + uuid + '"><div id="pdf' + uuid + '" class="pdf"></div></div>').appendTo('.tab-content');
$('#tabs a:last').tab('show');
var options = {
//pdfOpenParams: {
// view: "FitV"
//},
forcePDFJS: true,
PDFJS_URL: "pdfjs/web/viewer.html"
};
var pdf = PDFObject.embed(path, '#pdf' + uuid, options);
$('#print').hide();
$('#viewBookmark').hide();
$('#openFile').hide();
$('#exd-logo').hide();
}
});
Unfortunately, PDFObject is not capable of hiding the print button, it only provides a mechanism for specifying PDF Open Parameters, which do not include the ability to hide the print button.
I'm no expert on PDF.js, but since it's all JS-based, and hosted on your domain (i.e. you have full script access), you should be able to find a way to hack it to remove the print button. Good luck!
I was able to get the buttons to hide by handling the pagerendered event that PDF.js provides.
viewer.html
<script type="text/javascript">
$(function () {
document.addEventListener("pagerendered", function (e) {
$('#print').hide();
$('#viewBookmark').hide();
$('#openFile').hide();
});
});
</script>
I am shooting in the dark here because I do not know if the PDF viewer loads in an <iframe> or not, but the following code will scan over the page indefinitely and suppress the print button from showing if it finds it.
var $printSearch = setInterval(function() {
if ($('#print').length > 0 || $('#print').is(':visible')) {
hidePrint();
} else {
//doNothing
console.log('Searching...');
}
}, 150);
function hidePrint() {
$('div#print').css('display', 'none');
}
If it does load in an iframe we could use the .contents() and .filter() jQuery methods to target those elusive buttons.
Have you tried using print media queries ?
How can I rename my picture before upload ?
I tried this : $('#sortpicture').prop('files')[0] = $('#namePicture').val(); but it doesn't work.
I would like rename my picture with the value from #namePicture
//elements
var progressbox = $('#progressbox');
var progressbar = $('#progressbar');
var statustxt = $('#statustxt');
var submitbutton = $("#SubmitButton");
var myform = $("#UploadForm");
var output = $("#output");
var completed = '0%';
console.log($('#namePicture').val());
$('#sortpicture').prop('files')[0] = $('#namePicture').val();
$(myform).ajaxForm({
beforeSend: function() {
submitbutton.attr('disabled', '');
statustxt.empty();
progressbox.slideDown();
progressbar.width(completed);
statustxt.html(completed);
statustxt.css('color','#000');
},
uploadProgress: function(event, position, total, percentComplete) {
progressbar.width(percentComplete + '%');
statustxt.html(percentComplete + '%');
if(percentComplete>50)
{
statustxt.css('color','#fff');
}
},
complete: function(response) { // on complete
console.log(response.responseText);
myform.resetForm(); // reset form
submitbutton.removeAttr('disabled'); //enable submit button
progressbox.slideUp(); // hide progressbar
}
});
Input[type=file] is readonly, you can only set the value by browsing, not via JavaScript.(security!)
However if you want to send a different name to the server, you can make a input[type=hidden] and set it's value to he filename you want. Then on the server, you give it that name.
==== UPDATED QUESTION ====
I have control over onComplete state. That's not the case. The problem is that I don't know how to remove currently uploaded item's Progress Bar. Pls, check the screenshot.
I am using a jQuery plugin for multiupload with the support of HTML5 File API located on this website named damnUploader.
File upload works fine, but I'm stuck at the point where I need to hide the uploading progress bar once the upload is finished, but do not know how to do it without any special key to tell to remove progress bar from that element.
==== UPDATED QUESTION ====
To clarify my question, here is a screenshot. 5th and 6th images are at the uploading state. 6th image is about to be finished, so once it's successfully uploaded, I want to hide that progress bar which is below that image, but without touching the other progress bars on the other items.
Here is the javascript code (just search the function where is console.log(this._id); line:
var announcements = function () {
/*** ******************** ***/
/*** 1.1 MAIN INIT METHOD ***/
function _init() {
// Main inits on document ready state
}
/*** ********************* ***/
/*** 1.2 PRIVATE FUNCTIONS ***/
function _form_upload(){
// Main form for fallbacks
var $form_form = $('#form');
// Standard input file
var $form_file_input = $('#file_uploader');
// File POST field name (for ex., it will be used as key in $_FILES array, if you using PHP)
var $form_file_fieldName = 'image-file';
// Upload url
var $form_file_url = '/announcements/form_file_upload/' + $form_file_fieldName;
// List of available thumbnail previews based on selected files
var $form_file_list = $('#form_file_list');
// File upload progress
var $form_file_progress = $('#form_file_progress');
// Settings
var $form_file_autostartOn = true;
var $form_file_previewsOn = true;
// Misc
var isImgFile = function(file) {
return file.type.match(/image.*/);
};
var imagesCount = $form_file_list.length + 1;
var templateProgress = $form_file_list.find('div.progress').remove().wrap('<div/>').parent().html()
var template = $form_file_list.html()
// File uploader init
$form_file_input.damnUploader({
// URL of server-side upload handler
url: $form_file_url,
// File POST field name
fieldName: $form_file_fieldName,
// Container for handling drag&drops (not required)
dropBox: $('html'),
// Expected response type ('text' or 'json')
dataType: 'JSON',
// Multiple selection
multiple: false
});
// Creates queue table row with file information and upload status
var createRowFromUploadItem = function(ui) {
var $row = $('<div class="col-xs-4"/>').appendTo($form_file_list);
var $progressBar = $('<div/>').addClass('progress-bar progress-bar-success').css('width', '0%').attr('aria-valuemin', 0).attr('aria-valuemax', 100);
var $pbWrapper = $('<div/>').addClass('progress').append($progressBar);
// Defining cancel button & its handler
/*
var $cancelBtn = $('<a/>').attr('href', 'javascript:').append(
$('<span/>').addClass('glyphicon glyphicon-remove')
).on('click', function() {
var $statusCell = $pbWrapper.parent();
$statusCell.empty().html('<i>cancelled</i>');
ui.cancel();
console.log((ui.file.name || "[custom-data]") + " canceled");
});
*/
// Generating preview
var $preview;
if ($form_file_previewsOn) {
if (isImgFile(ui.file)) {
// image preview (note: might work slow with large images)
$preview = $('<img/>').attr('width', 120);
ui.readAs('DataURL', function(e) {
$preview.attr('src', e.target.result);
});
} else {
// plain text preview
$preview = $('<i/>');
ui.readAs('Text', function(e) {
$preview.text(e.target.result.substr(0, 15) + '...');
});
}
} else {
$preview = $('<i class="fa fa-image"></i>');
}
// Constructing thumbnails markup
$('<div class="thumbnail"/>').append($preview).appendTo($row);
$row.find('.thumbnail').append('<button type="button" name="formImageRemove" value="imageRemove" class="btn btn-danger btn-xs" role="button" />');
$row.find('.thumbnail').prepend(loading);
$row.find('.uploading').append($pbWrapper);
$row.find('button').append('<i class="fa fa-fw fa-trash-o" />');
return $progressBar;
};
// File adding handler
var fileAddHandler = function(e) {
// e.uploadItem represents uploader task as special object,
// that allows us to define complete & progress callbacks as well as some another parameters
// for every single upload
var ui = e.uploadItem;
var filename = ui.file.name || ""; // Filename property may be absent when adding custom data
// We can replace original filename if needed
if (!filename.length) {
ui.replaceName = "custom-data";
} else if (filename.length > 14) {
ui.replaceName = filename.substr(0, 10) + "_" + filename.substr(filename.lastIndexOf('.'));
}
// Show info and response when upload completed
var $progressBar = createRowFromUploadItem(ui);
ui.completeCallback = function(success, data, errorCode) {
// Original filename
// console.log((this.file.name || "[custom-data]"));
if (success) {
// Add animation class for fadeout
$(this).find('.loading').addClass('animated fadeOutDown');
console.log(this._id);
console.log(ui);
// Add some data to POST in upload request once upload finished and new filename retrieved
ui.addPostData($form_form.serializeArray()); // from array
ui.addPostData('images[]', JSON.parse(data).file_name); // .. or as field/value pair
} else {
console.log('uploading failed. Response code is:', errorCode);
}
};
// Updating progress bar value in progress callback
ui.progressCallback = function(percent) {
$progressBar.css('width', Math.round(percent) + '%');
};
// To start uploading immediately as soon as added
$form_file_autostartOn && ui.upload();
};
var loading = function(){
return '<div class="loading">\n\t<div class="uploading animated fadeInUp">\n\t\t<img src="/assets/img/loaders/ajax-loader.gif" />\n\t</div>\n</div>';
}
// File Uploader events
$form_file_input.on({
'du.add' : fileAddHandler,
'du.limit' : function() {
console.error("File upload limit exceeded!");
},
'du.completed' : function() {
console.info('******');
console.info("All uploads completed!");
}
});
}
/*** ************************************************** ***/
/*** 1.3 MAKE PRIVATE FUNCTIONS ACCESSIBLE FROM OUTSIDE ***/
return {
init: function () {
_init();
},
form_upload:function(){
_form_upload();
}
};
}();
$(document).ready(function () {
announcements.init();
});
Make a custom event and trigger it with Jquery:
$( "#hide_loading" ).on( "done", function() {
( "#hide_loading" ).animate({
opacity: 0
}, 5000);
});
if ( success ) {
$( ".hide_loading").trigger( "loadingfade" );
}
and if you completely want to remove it from the DOM structure after the animation:
$( "#hide_loading" ).on( "loadingfade", function() {
$( ".hide_loading" ).animate({
//put animations here (don't forget cross browser compatibility)
opacity: 0,
}, 5000, function() { //this function is called when the animation is completed
$( "#hide_loading" ).remove();
});
});
(now just add the class hide_loading to your loading elements)
I'm using ajax file uploader on my pages.
https://github.com/blueimp/jQuery-File-Upload
I'm using one control for image uploading and another for file uploading and both are on the same page.
I've added the validation to check the file type in both of the file uploaders but when I drag and drop resume on my file uploader then it will catch the image uploader event.
I want to disable the functionality of drag and drop for image uploader so it will not trigger when i drag my resume.
Here's my code,
$(function () {
var userId = $("#CandidateProfile_user_id").val();
var url = 'index.php?r=fileUpload/uploadResume';
$('#resumeUpload').fileupload({
add: function(e, data) {
var uploadErrors = [];
var acceptFileTypes = /^document\/(doc|docx)$/i;
var fileName = data.originalFiles[0].name;
var fileExtension = fileName.split('.')[1];
if(fileExtension.toLowerCase() != "doc" && fileExtension.toLowerCase() != "docx") {
uploadErrors.push('Not an accepted file type');
}
// if(data.originalFiles[0]['type'].length && !acceptFileTypes.test(data.originalFiles[0]['type'])) {
// uploadErrors.push('Not an accepted file type');
// }
if(data.originalFiles[0]['size'].length && data.originalFiles[0]['size'] > 5000000) {
uploadErrors.push('Filesize is too big');
}
if(uploadErrors.length > 0) {
alert(uploadErrors.join("\n"));
} else {
data.submit();
}
},
url: url,
dataType: 'json',
formData: {userId : userId},
done: function (e,data) {
onFileUploaded(data.result.fileName,data.result.filePath);
//Update the pic
// $("#userPic").attr('src',data.result.imagePath);
//set the image name
// $("#CandidateProfile_image_name").val(data.result.imageName);
//console.log(data);
},
}).prop('disabled', !$.support.fileInput)
.parent().addClass($.support.fileInput ? undefined : 'disabled');
});
Thanks,
Faisal Nasir
You can disable drag & drop by setting the dropZone option to null.
$('#resumeUpload').fileupload({
dropZone: null,
add: function(e, data) {
I have this strange issue and I've tried several solutions (even implementing the same as the Basic Plus demo on their website). I can upload files just fine, single or multiple. They upload on a click of the individual item, or a "Upload All" button. The problem is trying to add additional files before or after uploading. The file upload plugin will not even detect that these files are changing in the file input, so it never fires the "fileuploadadd" event, and requires me to refresh the page in order to upload more files. I'm wondering whether the fileupload change event is being lost somewhere, but I cannot for the life of me figure out where.
Also, does the blueimp file upload plugin require a specific return format of JSON? At the minute, I'm just returning "{\"status\":\"success\"} if the uploads are a success, and a similar error message. EDIT: Changing the response format to examples shown by blueimp had no effect.
Here's some code for the uploader I'm using. Note that I'm currently using ASP.NET and jQuery 2.0.3, and jQuery UI 1.9.2.
function initFileUploader() {
//initProgressBars();
$(upload_progressbar_title).css('display', 'none');
$(upload_progressbar).css('display', 'none');
$(upload_upload).on('click', function () {
$(upload_progressbar).css('display', 'block');
$(upload_progressbar_title).css('display', 'block');
$('.uploadbtn').click();
});
$(upload_browse).on('click', function () {
$(upload_file).click();
return false;
});
$.guid = 0;
console.log('initialising file upload');
var uploadButton = $('<input type="button" id="button" />')
.addClass('button tiny').addClass('uploadbtn')
.prop('disabled', true)
.val('Processing...');
var uploadCon = $('<div class="small-4 medium-6 large-6 columns progresscontainer" />')
.append('<div class="progressbar" />')
.append('<label class="progressbarlabel">Not uploading</label>');
uploadCon.append($(uploadButton).on('click', function () {
var $this = $(this),
data = $this.parent().data();
$this
.off('click')
.val('Abort')
.on('click', function () {
$this.remove();
data.abort();
});
data.submit().always(function () {
$this.remove();
}).success(function (result, textStatus, jqXHR) { console.log("Result: " + result + " - TextStatus " + textStatus); })
.error(function (jqXHR, textStatus, errorThrown) { console.log("Error: " + errorThrown + " - TextStatus " + textStatus); })
.complete(function (result, textStatus, jqXHR) { console.log("Result: " + result + " - TextStatus " + textStatus); });
}));
$(upload_file).fileupload({
dataType: 'json',
autoUpload: false,
acceptFileTypes: /(\.|\/)(pdf|jpe?g|png|doc|docx)$/i,
maxFileSize: 5000000, // 5 MB
}).on('fileuploadadd', function (e, data) {
var uniqueId = $.guid++;
data.context = $('<div id="div_upload_dcon_' + uniqueId +'" class="row"/>').appendTo(upload_filescon);
$.each(data.files, function (index, file) {
file.uniqueId = uniqueId;
var node = $('<div id="div_fname" class="small-6 medium-4 large-4 columns"/>')
.append($('<span/>').text(file.name));
if (!index) {
data.url = baseUrl + 'PostUploadFile?fileName=' + data.files[index].name + '&refId=' + ClientRefId + '&upbyid=' + ClientUserId + '&ticketId=' + globalTicketId;
var contentNode = (uploadCon.clone(true).data(data));
}
node.appendTo(data.context);
$(contentNode).appendTo(data.context);
$(upload_file).on('change', function () {
alert('changing fileinput');
});
});
}).on('fileuploadstart', function (e, data) {
initProgressBars();
}).on('fileuploadchange', function (e, data) {
alert('changing');
}).on('fileuploadprocessalways', function (e, data) {
var index = data.index,
file = data.files[index],
node = $(data.context.children()[index]);
if (file.error) {
console.log(file.error));
}
if (index + 1 === data.files.length) {
$('.uploadbtn').val('Upload').prop('disabled', !!data.files.error);
}
}).on('fileuploadprogress', function (e, data) {
var progress = parseInt(data.loaded / data.total * 100, 10);
$('#div_upload_dcon_' + data.files[0].uniqueId).progressbar('value', progress);
}).on('fileuploadprogressall', function (e, data) {
var progress = parseInt(data.loaded / data.total * 100, 10);
$(upload_progressbar).progressbar('value', progress);
}).on('fileuploaddone', function (e, data) {
getTicketContent(globalTicketId);
}).on('fileuploadstop', function (e, data) {
$(upload_file).val('');
}).on('fileuploadfail', function (e, data) {
$.each(data.files, function (index, file) {
var error = $('<span class="text-danger"/>').text('File upload failed.');
$(data.context.children()[index])
.append('<br>')
.append(error);
});
});
}
Well, after a night's sleep and more thinking about it, I specified this option
replaceFileInput: false,
during the file upload initialisation. And guess what, it works as intended now. I'm guessing that the file input was being lost because the fileupload clones the control by default after an upload or change.
Thanks for any consideration anyone may have given this, I hope it comes in handy for someone else in the future.
It's been two years since the original answer, but I just figured this out for my own case (:
If you use replaceFileInput: false, the code will not work in IE9, which does not support the newer file upload APIs. According to the documentation the fallback support for this browser depends on an "iframe transport" that requires the file input element be replaced each time. Reading that was the big clue for me.
What's really killing you is this:
$(upload_browse).on('click', function () {
$(upload_file).click();
return false;
});
You are assuming that upload_file is still the same element, but it's been replaced with a clone. You're firing a click event on the old file input element. It exists, so you get the system browse dialog, but it's not hooked up to any plumbing.
So the correct solution with full IE9 support is to use "find" to locate upload_file anew each time this click handler is fired. You didn't include your code for setting upload_file, so I don't know what the correct selector would be in your case, but it would look something like this:
$(upload_browse).on('click', function () {
// You should use a more specific selector, better yet use
// find() to locate it inside some div you know is "in scope" so
// you don't fire every file input on the page. Just an example
$('input[type=file]').click();
return false;
});