OK, here's a report. There's probably some valid criticism deserved, but this is working for me now.
My requirements: add items to a cart without reloading the page. The catch: the user is creating the items and may include photos, etc. We want them previewable. The crux of our issue: AJAX wasn't posting the photos.
- Note that for my own reasons, I'm not ever calling the form's submit() method.
- JS reads all the form fields/values and does an AJAX call to a PHP script to do the DB work.
- To handle the photos/files, JS needs the Form API; I'm adding the files to the FormData object. If I don't, it appears the form gets sent without them (PHP doesn't see anything in $_FILES).
var fd = new FormData();
The following JS is instrumental in doing two things; a] grab the file object being passed from the input for use later (in D.photos ---"D" is a global object we use as a namespace), and b] provide for previewing the files in the "preview_photo" DIV. D.photopager_create() is called when the [input=file] element's onchange event is fired.
D.photopager_create = function(obj) {
var i;
D.photopager_files = [];
D.photos = {};
for (i = 0; i < obj.files.length; i++) {
D.photos[i] = obj.files[i];
D.photopager_files[i] = window.URL.createObjectURL(obj.files[i]); // for previewing
}
//preview the first file
document.getElementById('preview_photo').src=window.URL.createObjectURL(obj.files[0]);
D.photopager_index = 0; // var for paging
};
When the "submit" button is pushed, everything gets appended to fd (the formData object).
if (typeof(D.photos) ==='object' && Object.keys(D.photos).length) {
//to get a JS object's size, you must count keys() in the Object Prototype
for (var i=0; i < Object.keys(D.photos).length; i++) {
var nn = "file"+i;
fd.append(nn, D.photos[i]);
}
} else {
// warn user
}
Something I learned and didn't expect: in order to get the files passed, I had to instruct jQuery to use a falsy contentType (also "processData"):
settings = {"method":"POST", 'contentType':false, processData:false, "data":fd};
$.ajax(url, settings).complete(myFunc);
I THINK that's all I had to do. Thank you folks for your help!!