I have read many online articles on this topic. However, they either just show how to do ajax form submission, or how to submit just files. In my case, well I bet in most real life situations, we need to submit both ordinary text/selection/radio values and files.
Here is how to do it.
HTML forms. Yea, whatever. Just set something up.
Submit
Notice I didn’t use the form tag. My philosophy here is that: since we will decide the data set during the ajax submission, there is really no need to declare a form here.
Then here comes the ajax part.
$('document').ready(function(){
// bind actions to the submit button
$('#submit_btn').click(function(){
submit_xhr();
});
});
// submission
function submit_xhr(){
// our file obj
file_obj = document.getElementById('file1').files[0];
// using FormData, makes your life much easier
var formData = new FormData();
// append key-value pairs
formData.append('text1', $('#text1').val());
formData.append('text2', $('#text2').val());
var xhr = new XMLHttpRequest();
url = "http://somewhere.com/some_dir/upload.php";
type = "POST";
xhr.open(type, url, true);
xhr.onload = function(e) {
if (xhr.status == 200) {
if (xhr.statusText != "OK"){
// something wrong at the server side, not fatal
alert(xhr.statusText);
return;
}
// success
alert('could do a window.location.replace(url) here');
} else {
// error, something bad happened...
alert("ErrornStatus: "+xhr.status+"nStatus text: "+xhr.statusText);
}
};
xhr.send(formData);
}
I found FormData very easy and intuitive to use. I recommend using that rather than creating a json array when file sending is involved.
So now, we need to receive the content at the server side.
$text1 = $_POST["text1"];
$text2 = $_POST["text2"];
$file_obj = $_FILES["file1"];
$file_name = $file_obj["name"];
$file_type = $file_obj["type"];
$file_size = $file_obj["size"];
$file_tmp_name = $file_obj["tmp_name"];
$file_error = $file_obj["error"];
// do whatever
The $file_error value should be 0 upon a successful transfer. The $file_tmp_name is a local temp file name containing your file content. Everything feels natural now from this point on. You can also double check the $file_size.
If you are a javascript purist, you may want to try out FileReader. Below is some snippet to get you started.
function read_file_content_and_submit(){
var file_type;
var file_name;
var reader = new FileReader();
reader.onerror = errorHandler;
reader.onload = function(e){
data = {
type: file_type,
name: file_name,
content: reader.result
}
//alert(data);
combine_with_others_then_submit(data);
}
file_obj = document.getElementById('file1').files[0];
file_type = file_obj.type;
file_name = file_obj.name;
reader.readAsBinaryString( file_obj );
}
Hope this helps!