Why does jQuery File Upload need reinitializing when using it with KnockoutJS? - javascript

I have a file upload component which is bound through a template to a view model (UploadViewModel). The file upload dialog is initialized through a custom Knockout binding (uploadFileDialog). The UploadViewModel is created when the user clicks the 'Choose file...' button and when the user has selected a file to upload the fileuploadadd event should trigger which should invoke fileSelected method and then the Start button should be visible as a result. This doesn't seem to happen. The only way to make it work is to re-initialize the file upload dialog every time (the commented code in the uploadSelectFile method).
Why does it need to be re-initialized?
Code: http://jsfiddle.net/FKYwB/

Your event is never fired.
Actually, you are not binding to the right element.
Your uploadFileDialog should be on the form tag in the template like this:
<form id="fileupload" action="" method="POST" enctype="multipart/form-data"
data-bind="uploadFileDialog: { maxFileSize: 500000000, autoUpload: false },
event: { fileuploadadd: fileSelected}">
<!-- -->
</form>
Updated fiddle

Related

Inserting a button inside a form and triggering different actions in an Angular app

I'm making a web app. I'm in the middle of implementing the Braintree and everything works fine. Now I have an issue with the view code for Braintree. Below is an essential view code I need for braintree integration:
<form name="form" ng-submit="submitPayment()">
<div id="payment-form"></div>
<input type="submit" class="button button-form-success button--primary vertical-offset--small" value="Pay">
</form>
Now, I am trying to add another button next to pay button, but whenever I put the button in the form, it triggers submitPayment() instead of button's action. How do I successfully add a button inside the form and trigger different function when clicked?
Just use a tag for that like below
Second Button

Sending multiple file input fields programmatically in one form

I'm trying to use the blueimp/jQuery-File-Upload plugin to programmatically send more than one file input field though the same form.
When user select form files, it just append them in a JS variable to further send them with $('#form').fileupload('send') method on form submission. My goal is to use the exactly same synchronous form I was using before in an asynchronous way. So when user click on form submit button, it prevents default action and them let the plugin to do the task, sending all form data and displaying overall upload progress.
I'm mainly following these guides:
https://github.com/blueimp/jQuery-File-Upload/wiki/API
https://github.com/blueimp/jQuery-File-Upload/wiki/Multiple-File-Input-Fields-in-One-Form
Actually it's almost working, but it does not send more than one input file to the server end. In fileuploadadd event I'm pushing data.files[0] (my file inputs are single file only, but each of them use different accept attributes) to a "global" uploadable array and then on form submission I use something like $('#form').fileupload('send', {files: uploadable}).
I guess I'm not doing it the right way, since only one file is being sent along with form data. What is the correct way to programmatically send more than one file input file using a single form?
I'm also not too confident about overall upload progress... If I use fileuploadprogressall event to read the upload progress will it be reporting the progress of all uploaded files?
JS (simplified)
$(function () {
var uploadable = [];
$('#form').fileupload({
autoUpload: false,
singleFileUploads: false,
add: function (event, data) {
uploadable.push(data.files[0]);
return false;
},
// other event callbacks
})
.prop('disabled', !$.support.fileInput)
.parent().addClass($.support.fileInput ? undefined : 'disabled');
$('#form').submit(function (event) {
event.preventDefault();
$('#form').fileupload('send', {files: uploadable});
});
});
HTML
<form id="form" action="upload" method="post" enctype="multipart/form-data">
<!-- other text/hidden inputs that will also be sent -->
<input type="file" name="image" id="image" accept="image/*" />
<input type="file" name="video" id="video" accept="video/*" />
</form>
uploadable.push(data.files[0])
You vividly told the compiler to only push the first file.
Have you tried using foreach and push all files?
Thank you,

Triggering click on type=file with another button causes unexpected behaviour

I'm trying to create my own "upload" button instead of the default one. By clicking on my custom button I'm triggering a click on the original upload button:
HTML:
<form id="myForm" enctype="multipart/form-data" action="api/upload.php" method="POST">
<input type="hidden" name="MAX_FILE_SIZE" value="5120000" />
<input name="userfile" type="file" class="choose-file"/>
<button class="choose-picture"></button>
<input type="submit" class="send-button" value='' />
</form>
JS:
$('.choose-picture').click(function() {
$('.choose-file').trigger('click');
});
I have another script that displays the picture that got uploaded when I click the submit button. If I use the original upload file button, nothing happens and that's ok (the picture is only suppose to show up after I choose and submit one), but when I click my custom (.choose-picture) button it acts as if I already chose a file for uploading, putting some mess in the img source and displaying a non-img (the icon you see when the source is wrong).
This is what the console says:
GET http://localhost/OrlenOla/%3Cbr%20/%3E%3Cb%3ENotice%3C/b%3E:%20%20Undefined…api/upload.php%3C/b%3E%20on%20line%20%3Cb%3E10%3C/b%3E%3Cbr%20/%3Euploads/ 403 (Forbidden)
So it's acting as if I already called my upload script (which I have no intention to call at this stage as it's supposed to happen on submit).
Why is this happening? How can I fix it?
If you don't explicitly specify a type attribute on a <button> element, it's treated as though you explicitly declared it as type="submit" (i.e. a button that's intended to submit the form):
submit: The button submits the form data to the server. This is the default if the attribute is not specified, or if the attribute is dynamically changed to an empty or invalid value.
Source
That's why it's triggering your form submit event handler code, because it does submit the form.
Easiest way to fix this is to just specify type="button" on the element:
<button type="button" class="choose-picture"></button>
The other way (as you discovered) is to prevent the default behaviour of the button:
$('.choose-picture').click(function(e) {
e.preventDefault();
$('.choose-file').trigger('click');
});
I managed to resolve the issue:
$(document).ready(function() {
$('.choose-picture').click(function(e) {
e.preventDefault();
$('.choose-file').trigger('click');
});
});

Uploading multiple single files using separate Dropzones in one form

I have a form where you can continually add more rows.
One row contains name and avatar, etc.
I want to use Dropzone.js to make each avatar a different droppable field.
Whenever I create a new row, I'm creating a new Dropzone area. This is fine, and works.
However, when I submit the form, the files are nowhere to be found. I can understand why, because the file fields aren't in the form, they are appended to the body.
<form>
<div class="person" id="person_1">
<div class="avatar"></div>
<input type="text" name="name_1" />
</div>
<!-- then these are added via js -->
<div class="person" id="person_2">
<div class="avatar"></div>
<input type="text" name="name_2" />
</div>
<div class="person" id="person_3">...</div>
<div class="person" id="person_4">...</div>
<!-- etc -->
</form>
I'm initializing the dropzone on the avatar div.
Is it possible to add them to file fields inside the form?
Here's what's going on in the JS. It's dumbed down a little for brevity.
(function(){
var count = 1;
var $form = $('form');
initDropzone( $('#person_1') );
function addPerson() {
count++;
var $personDiv = $('<div class="person" id="person_'+count+'">...</div>').appendTo($form);
initDropzone( $personDiv, count );
}
function initDropzone( $el, count ) {
$el.find('.avatar').dropzone({
autoProcessQueue: false,
uploadMultiple: false,
parallelUploads: 100,
maxFiles: 1,
url: '/' // dropzone requires a url param
});
}
$('#add_person').on('click', addPerson);
})();
The problem is not that the fields are appended to the body, but that the whole Dropzone uploading process is different from a normal form submission.
You can not use Dropzone to drop files in the browser, and then use the normal form submit to submit it.
There are two ways to accomplish what you are doing:
Don't let the user submit the form until all your files in the Dropzones have uploaded (or better yet: create event listeners on all your Dropzones that will fire the submit function on the form as soon as all Dropzones have uploaded). You need to store the files on your server and wait for the actual form submission to assemble the data.
This is by far the most elegant solution, because this way the files are already uploading while the user may still be editing form data.
Create one Dropzone on the actual form, that will handle the whole uploading of the form via AJAX. (See the docs for that). If you want different dropzone targets inside that dropzone, you'll have to create them separately, and "delegate" the file drops to the main dropzone (basically, just take the file object, and add it to the main Dropzone).

Jquery custom file input plugin

This jquery plugin allows you to turn any element into a file input element. http://plugins.jquery.com/project/custom-file
But to actually upload the file, the only documentation i could found is this:
To upload the chosen file to a server you should then attach the input element to a form element
how can i do that?
I think you need to create an html form and append the input to the form, and if you need to submit, you can do it via a submit button or via $.submit
# from http://www.daimi.au.dk/~u061768/file-input.html
<script type="text/javascript">
$(function() {
$('button').button().add('#foo, a').file().choose(function(e, input) {
$(input).appendTo('#TheForm').
attr('name', 'a-name').
attr('id', 'an-id');
});
});
</script>
...
<form method="post" enctype="multipart/form-data" id="TheForm" action="/path/in/your/server/">
<input type="submit" value="send">
</form>
Anyway this is not the best plugin for submiting the files via ajax.
The uploading itself is not of the scope of this plugin. You should see this with your server side technology.

Categories

Resources