When files[] is opened more than once, previous uploads are erased - javascript

I am creating and using a custom image uploader within my form which is submitted via ajax - everything works perfect.
I am allowing users to upload multiple images e.g:
<input type="file" name="files[]" accept="image/*" class="files-data" id="upload_images" multiple="">
The problem that I am facing, is that when a user clicks the "Image Upload Button" multiple times, each time the input (the array of previously uploaded images) is reset.
So if a user uploads 3 images, great - that works fine. But if they decide to open the file upload again and upload another image or two, the original 3 files are gone.
I am not looking for a plugin to do this, and I know that this can be done from other image uploaders I have seen.
Do you know how I can maintain previously uploaded images when the multiple input field is opened more than once?
Thank-you for any help.

This is the default behavior of HTML. You need to manage those uploaded files via javascript/jQuery in order to maintain the user selection and for which the plugins you are trying to escape from will do that for you :)

I solved this by looping through the uploaded images and storing them into an array each time a new file is uploaded. My problem was that I was doing something completely different, and just overriding the files each time the user uploads more files.
Some common sense, and sitting here to think for a while helped me solve this one :)
MyForm = {}; // empty array
MyForm.userUploads = []; // empty object
$('.add-listing-photos input[type="file"]').on('change', function() {
// Get the files.
var files = $(this)[0].files;
// For each file, append it onto the end of our array.
for( var key in files ) {
if( typeof( files[key] ) === 'object' ) {
MyForm.userUploads.push( files[key] );
}
}
console.log(MyForm.userUploads);
});
And then sent this through my ajax request.

Related

Storing file chooser data in a hidden input

I am using a tool called TamperMonkey to modify a webpage for my personal convenience. TamperMonkey lets you modify the client-side HTML etc. by appending JavaScript to the page after it loads.
The webpage has a file chooser, but it doesn't let you drag-and-drop a file. I use this webpage a lot so having drag-and-drop functionality would really help.
This page has a form with a file input type. I've been reading, and there's no way to modify a file input type for security reasons. But, using TamperMonkey, I could change the input type of the file chooser to "hidden," then set the hidden input value to the file contents that I drop on the webpage, right? It's my understanding that the server couldn't tell the difference (if the name attribute is the same).
I don't know how to set the hidden input type to the same data the file chooser would have:
I've got my file here: const file = e.originalEvent.dataTransfer.files[0];
I've got my hidden input type by doing this: const hiddenField = $("iframe").contents().find(".file-input").attr('type','hidden')
I just don't know how to take file and set it on hiddenField. Should this value be base64 encoded? A blob? Regardless, what code would set the data correctly?
The form it's wrapped in looks like this:
<form ... method="post" enctype="multipart/form-data">
Important context for alternative suggestions: this file chooser input isn't on the page at all until you click a button. Then it shows up in an iframe.
I am using firefox.
It is possible to modify a file input type with Tampermonkey.
If you are not able to add drag and drop support to the input itself straight away, you can implement drag and drop using another dom element and use them as below.
const dT = new ClipboardEvent('').clipboardData || // Firefox < 62 workaround exploiting https://bugzilla.mozilla.org/show_bug.cgi?id=1422655
new DataTransfer(); // specs compliant (as of March 2018 only Chrome)
dT.items.add(new File([dataURItoBlob(image)], '1.jpg', { type: 'image/jpeg' }));
dT.items.add(new File([dataURItoBlob(image2)], '2.jpg', { type: 'image/jpeg' }));
// then ...
// $("iframe").contents().find(".file-input").get(0).files = dT.files;
That snippet of code was tested working, in a similar setting where a file input was being attached to the page dynamically after clicking a button. The images were drag n dropped onto the page using a different div.

How to Open File Dialog box on SPA (browser side) with custom file list (of remote, server directory)

I have a MVC project with a view. Have a directory on server with files, and have to show good looking Open File dialog box with this directory and files in it (not a user's local directory). I got a list of files, and path, and send as variables (string and array of strings) into my view, so now I can show directory listing on my page. But I'd like to use some standard looking dialog box for choosing file instead of writing my own window with radio buttons and text boxes.
Is there any way to fill Open file dialog box with my list of files With Javascript?
Regarding the buttons, you can take a look at bootstrap: https://getbootstrap.com/docs/4.0/components/list-group/
There you can use predefined buttons, lists etc. But specifically for downloading files there is no SPECIAL button of any kind.
Regarding the JS part, you can use something like:
<a id="download_link" download=filename.txt" href=”” onclick="getFile('someinputtxt')"><font size="5">Download Txt File</font></a>
<script>
function getFile(input)
{
var text = input;
var data = new Blob([text], {type: 'text/plain'});
var url = window.URL.createObjectURL(data);
document.getElementById('download_link').href = url;
}
</script>
There I create a text file with some input. But basically you can use a button/list that is already in bootstrap for example and just add the file using 'download':
Hope it helps.

Js/Jquery Drop event takes .lnk file instead of real file

I am trying to add a div link where users can drag and drop files. It works well on every files, but when I drop a Linked (.lnk) file, it takes the lnk file instead of the real one behind the link.
my code
$("html").on("drop", "#mydiv", function(event) {
...
data.append("file-0", event.originalEvent.dataTransfer.files[0]);
//then sending data object via ajax
...
});
is there a way to get the real file on drop ?
Thanks by advance

how can I send input straight to textarea

I am using
https://github.com/Rovak/InlineAttachment
I currently have it all setup so I can drag and drop images to my textarea and they upload straight to imgur, from following this tutorial:
http://wilfreddenton.com/posts/drag-and-drop-photo-uploads-to-imgur
what I'm trying to do is add an input so if the user doesnt want to drag and drop, they can simply browse their pc and upload files, and have them go straight into the textarea upon selection. (just how github comments work)
I just cant seem to get the input to insert into the textarea.
Here's a live example: http://codepen.io/DrCustUmz/pen/KzZOeP
or if your logged into github you can see the end goal what im trying to do: https://github.com/wilfreddenton/dynamic-scss/issues/new
dont actually submit but click "selecting them" below the textarea, pic a few images, and watch the textarea after you click open.
the input selection is not working in this example. How can I get it so I open the choose files, select a few images, then when I select "open" on the browse my pc popup, they are directly inserted into the textarea, just like i drag and dropped them.
Most of the writting work is done in background so I had to rewrite the writting to textarea. Sorry I mostly use pure javascript so I didn't use any fancy jquery features.
This is where the magic happens. The upload can handle only one file at a time so I had to use loop for all of them. I recommend you take a look at the whole code.
document.getElementById("inputFile").addEventListener("change", function() {
var object = this;
var editor = document.getElementById("editor");
for(var i=0;i<this.files.length;i++) {
editor.value += "uploading...";
uploadHandler.customUploadHandler(this.files[i], function(result) {
editor.value = editor.value.replace("uploading...",result.filename);
});
}
});
Whole code on CodePen
You can simply attach the eventListener upon file is selected via choose files option. You just have to trigger the upload in callback. Assume that you've given id of the input type file as "fileUpload"
document.getElementById('fileUpload').addEventListener('change', function () {
console.log(this.files);
/*trigger the upload here, like you're doing in drag and drop*/
});

How do I manipulate a form according to the contents of a file field?

I need to manipulate parts of a form in Drupal 6 based on the contents of a file field.
For example:
if the form shows and there is a file, do x
if the form opens without a file, do y
if a file is uploaded, do z (as soon as the upload is finished)
if a file upload fails, or the uploaded file is deleted, do xyz (whether ahah is used or not)
Any ideas on how I get this done?
thanks
Found a solution of sorts.
Using Drupal behaviors I am able to check whether the "upload" or "remove" buttons are in place and act according to them. Drupal behaviors also give the added value of updating when when ahah is used, as well.
For example, I needed a check-box to be disabled if no file was uploaded. I used this code:
drupal_add_js("
Drupal.behaviors.FilefieldCheckbox = function(context) {
if ($('#[filefield_id]-remove', context).size() > 0) {
$('#[checkbox_id]').removeAttr('disabled');
} else {
$('#[checkbox_id]').attr('disabled', true);
}
}
", 'inline', 'footer');
you need to replace [filefield_id] and [checkbox_id], of course.

Categories

Resources