How to replace image formdata with Javascript after compressing the data? - javascript

There are various image compression libraries, that can simply read the file attached to a form's <input>, but I'm lacking the skill to 'return' the new compressed image back to that <input>, so it's attached to the form/application and can be processed.
Whatever library I try, and often in the console can see the old/new size values, and press 'submit' on the form to send the image to the server, always the original image is sent over, not the new compressed one.
How would I replace the image that the user selects for the <input type="file"> with the new DataURL that is created with Javascript? I think I just need a line of code or two to replace the value/data, but which?
Providing code is a little difficult, because I haven't set on a specific compression library. Let's just assume we've got a form with an <input>, an OnChange Event handler and a function that reads the data and returns a new DataUrl.

As far I remember due to security reasons browsers won't allow you to modify the FileList.
Anyway, you can solve your task by appending a hidden field to your form and setting the data URI as Base64 value for the hidden field. On form submit clear the original file field (if you do not need it) while on the server side you have to decode Base64 value of the hidden field.
If ajax requests are ok for you, another option is to use FormData and XMLHttpRequest (for some good examples check Using FormData Objects).

Related

How do I append binary file data to a <form> and submit it synchronously?

I've got a template that works nicely with synchronous submission. I've got a couple of images that I'm trying to upload with the form, having resized them in the browser to the desired size in a <canvas>. I could append these to a FormData object, but I'm trying to avoid asynchronous submission because I'd really like to reprocess the template through the django template context processor (for various reasons).
Is it possible to get my binary image data in the form, submit synchronously, and still be "recognisable" as a request.FILES object server side? If so, how do I do this?

Getting all files that have been submitted with a form using OneUp's UploaderBundle and blueimp's jQuery-file-upload

In out website, we wish to present the users with a form that would allow them to upload picture galleries. The form consists of a <textarea> for a description, a <select> with sharing options and the multiple file upload field.
We're using jQuery-file-upload's jquery-ui version, as seen in here: link and our javascript code is pretty much identical. The only significant difference is that we also added a simple submit button, that sends out a POST request to the form's action.
The problem is that we need to reference ALL the files in a GalleryPost object, and the POST request that we get from the form only contains the values of <textarea> and <select>. Which makes sense, since the uploading is done asynchronously via separate requests.
Since we're using OneUpUploaderBundle to handle the actual uploads, we've tried enabling the orphanage feature described here, which kinda helps doing what we want, but as stated in the "known limitations" section, if the user does not submit the form, but starts over with a new one, the previously uploaded files will be submitted, together with the new ones, unless the session id is changed.
Simply put, we need a way to attach a list of files (names would suffice), that have been successfully uploaded, to the form's POST request, so that we could reference them in our GalleryPost object. Or maybe there is some other way to achieve the functionality we need?

Is it possible to set the value of a file input to files from another file input?

I suspect I am going to disappointed on this one, but I would like to know if there is any way to set the value of a file input with files obtained from a different file input.
My example would be a file input which allows multiple selection:
the user selects some files
another file input is added (using javascript - this is irrelevant - it could already exist in the original form)
the value of the second input is set to that of one of the files from the first input
when the form is submitted (normally, not using ajax), the server receives the files from both inputs.
I realise that people will probably comment on the security aspect, but I am talking only about files that have already been specifically selected by the user (in the first input).
I don't need to read the files (I know I can do that using the FileReader API), and I don't want to submit the form using AJAX - I simply want to split multiple selected files from one multiple file input into single file inputs.
On getting, it must return the string "C:\fakepath\" followed by the
name of the first file in the list of selected files, if any, or the
empty string if the list is empty. On setting, if the new value is the
empty string, it must empty the list of selected files; otherwise, it
must throw an InvalidStateError exception.
See the value attribute specification. So you cannot get the real value, nor can set a new value other then an empty string.

How to manipulate form file input before POST

I have a form which includes an input type="file" to upload an image, and I want to be able to manipulate that image before submission.
(I may want to crop or resize it using an existing jQuery library, for example. I'm posting to WordPress and am tied to gravity forms, which means I can't use a plug-in such as jQuery-file-upload which includes server-side handling too, so my question is more generic.)
I'm trying to understand what happens on submit and how the browser constructs the post to be handled by the server.
If a user has selected a file, can I take that file and do something with it in javascript, and then on the form submit have the browser take my amended version from memory rather than the original version linked to in the input field?
[EDIT]
So, I've discovered some useful insights. Anyone looking at this, here is a useful thread here on SO.
When a user selects an image on a file input field, I can use html5 canvas to manipulate it. I need to then convert it back to a binary file to upload (via canvas.toBlob() in the most modern browsers, or using the technique mentioned in the above link for older browsers).
Then what do I do with it? I can POST it via Ajax as per this Mozilla developers article and for most people this will be fine.
My problem is that I am tied to using Gravity Forms and I need to let it handle the form submission.
Which means I need to manipulate my existing form and let the user hit the submit button as normal.
Where my form has
<input type="file" name="input_3" id="input_3_3">
I have tried in JavaScript:
document.getElementbyId('input_3_3').value = myBlob;
but it appears that I can't assign the blob to the input field.
Reading around, the solutions which involve Ajax make use of FormData objects, and I thought I might be able to append the field but that doesn't seem to work (the form on the page in the DOM and the FormData object are not the same thing?).
So, that's where I'm stuck.
In theory you can use blob , but practically it is not good solution because it is not supported in all browsers , and there is no current javascripts library to process images , so the best bet is to send it so server and let the server process it .

How to do nice and simple file uploading in javascript?

All I want is:
select a file
small progress bar (unless it is not simple)
fail/success confirmation on client side
trigger action on server side.
all that without page reloading
Except that, the simpler the better.
Snippet would be most welcome.
There are plenty of scripts and tutorials around. Check for example http://www.ajaxf1.com/tutorial/ajax-file-upload-tutorial.html
Apparently that's not as trivial as one might think, since you can't just take the body of a form, containing an <input type='file'/> tag, and submit that.
But you can submit the form with a target of another <iframe/> and then poll the server with a XMLHttpRequest object for status updates, that however, requires that your sever-side script, that handles the upload, does so in a asynchronous manner, otherwise you will only get a status update once the file has been fully uploaded, not the kind of progress status updates you want. I think this is a challenge for most web frameworks to date, but I have never actually had any reason to dig into it. Sounds fun though...
If you just want to submit the file, independently of the actual form, you'll do the same, but you don't have to worry about the progress status updates.
What you can do, is to replaces the <input type='file'/> once the upload completes, with a <input type='hidden'/> containing the server-side ID of the recently uploaded file. That way you'll know when the user hits save, what files you'll want to actually save.
That hidden thing can also be a checkbox, which would let you undo a file upload, by simply unchecking that checkbox before hitting save.
File uploads using the XMLHttpRequest object is not possible in all browsers (only Firefox and Safari/Chrome support it), so for a cross-browser implementation use the <iframe> trick.
If you want a real XHR file upload, I have written an extended article on how to do it in Firefox 3. It's so low level that you actually have to build the actual HTTP request from JavaScript strings.
Maybe GearsUploader will fit.

Categories

Resources