Reputation: 171
whats up?
There are a lot of examples in the Internet about make a ajax-jquery form to upload an image. like this:
<form id="imageform" method="post" enctype="multipart/form-data" action='ajaximage.php'>
<input type="file" name="photoimg" id="photoimg" />
</form>
Make this form upload a file is not so difficult, but I need something else.
I have a form a little bigger than that.
Example:
<form id="imageform" method="post" enctype="multipart/form-data" action='ajaximage.php'>
<input type="file" name="photoimg" id="photoimg" />
<input type="text" name="foo"/>
<input type="text" name="bar"/>
<input type="submit" value="FINALLY DO THE SUBMIT"/>
</form>
Whats the big deal?
Well, I want the file input field do the upload of the file onchange event. But I dont want that the hole form do the submit. There are others fields to be done and after all the user will do the final submit.
I have no problem to do that in back end, my PHP engine is waiting and working, but I have no ideia of how to do that in front end.
Any sugestions?
Upvotes: 2
Views: 638
Reputation: 2146
You can use the target
attribute of the <form>
element to submit the form without reloading the page. The extra fields will still be sent, but by dynamically swapping the <form>
attributes, such as action
and enctype
, you can ensure the file input will be sent to an point in your back-end.
I have written a simple JavaScript+jQuery component that allows you to quickly setup AJAX uploaders. It will handle the attribute changes automatically and lets your back-end trigger a callback in your front-end:
var uploader = {
functionBegin: function () {},
functionCallback: function () {},
formID: '',
formAction: '',
buttonID: '',
originalAction: '',
originalTarget: '',
originalEnctype: '',
originalOnSubmit: '',
isSetup: false,
// Initializes the AJAX uploader
init: function(formID, buttonID, formAction, beginFunction, callbackFunction) {
// Sets up the optional callback functions
this.functionBegin = beginFunction;
this.functionCallback = callbackFunction;
// Sets up the selectors and upload form atributes
this.formID = formID;
this.buttonID = buttonID;
this.formAction = formAction;
// If we haven't already, create the invisible IFRAME that our form will target
if(!this.isSetup) {
$(formID).append('<iframe id="AU_IFrame" name="AU_IFrame" src="about:blank" style="width:0;height:0;border:0px solid #fff;"></iframe>');
this.isSetup = true;
}
// If a button selector was defined, we hook it's click event
if(buttonID) {
$(buttonID).click(function () {
uploader.triggerBegin();
return false;
});
}
},
// Begins the file upload
triggerBegin: function() {
// Backs up the original form attributes
this.originalAction = $(this.formID).attr('action');
this.originalTarget = $(this.formID).attr('target');
this.originalEnctype = $(this.formID).attr('enctype');
this.originalOnSubmit = $(this.formID).attr('onSubmit');
// Sets up the form with our upload attributes
$(this.formID).attr('action', this.formAction);
$(this.formID).attr('target', 'AU_IFrame');
$(this.formID).attr('enctype', 'multipart/form-data');
// Call our 'on upload begin' callback, if defined
if(this.functionBegin) {
this.functionBegin();
}
// Submit the upload form
$(this.formID).submit();
// Now that it's already uploaded, revert back to the original attributes
$(this.formID).attr('action', this.originalAction);
$(this.formID).attr('target', this.originalTarget);
$(this.formID).attr('enctype', this.originalEnctype);
$(this.formID).attr('onSubmit', this.originalOnSubmit);
},
// This can be called from the back-end, will trigger the user-defined callback
triggerCallback: function(params) {
if(this.functionCallback) {
this.functionCallback(params);
}
}
};
Here's an example on how you would apply this in an HTML form:
<form name="test" method="POST" action="regularForm.php">
<input id="fileInput" name="fileInput" type="file" />
<input type="text" name="foo" />
<input type="text" name="bar" />
<input type="submit" value="Send" />
</form>
<script type="text/javascript">
$(function () {
uploader.init(
'#fileInput', // File field selector
null, // Upload button selector (Optional, since we'll upload on change, this won't be needed here)
'fileUpload.php', // Upload action
function () { // Callback on upload begin (optional)
alert("Starting upload!");
},
function (params) { // Callback on upload end/error (called by the back-end, optional)
alert("Upload successful");
}
);
$('#fileInput').change( upload.triggerBegin ); // automatically upload on file input change
});
</script>
To trigger the callback properly, just make sure your back-end will run the following (assuming you're using PHP):
$someParameter = "whatever you want to return in the callback";
echo '<script type="text/javascript">';
echo 'if(top.uploader && top.uploader.triggerCallback) { top.uploader.triggerCallback("'.$someParameter.'"); }';
echo '</script>';
You can naturally tweak the parameters to make it return, for example, the file URL, upload status, size, etc.
As for other solutions, without HTML5 the only alternative is to use a Flash/Silverlight/Java applet or the Google Gears plugin, that will handle the file picking and uploading. There are a bunch of jQuery plugins that implement all of the alternatives as gradual fallbacks:
Upvotes: 1
Reputation: 20173
In order to submit a file via javascript you must first read its content. Unfortunately it's impossible to do that with HTML4, the HTML4 doesn't have any API that reads local files.
But there is a workaround for that, basically you need to redirect a form's action into a hidden IFrame. So, when the form with the file field is submitted, the result will appear in a IFrame. But since it is hidden, the user will not see it. This effect is achieved using the 'target' attribute of the Form tag.
HTML:
<iframe id="blah"></iframe>
<form id="imageform" target="blah" method="post" enctype="multipart/form-data" action='ajaximage.php'>
<input type="file" name="photoimg"/>
<input type="text" name="foo"/>
<input type="text" name="bar"/>
<input type="submit" value="FINALLY DO THE SUBMIT"/>
</form>
Javascript:
$('#imageform input').change(function () {
// This is called when any input changes
$(this)
.siblings()
.attr('disabled', '') // Disable the other inputs
.end()
.parent()
.submit() // Submit the form
.end()
.siblings()
.removeAttr('disabled'); // Re-enable the inputs
});
Of course, if you don't want to write all that stuff, you could just use a jQuery plugin
Upvotes: 1
Reputation: 2576
This tutorial can help you http://rafaelcouto.com.br/upload-dinamico-com-php-jquery/
Upvotes: 1