- The objective is to save form data with file inputs and AJAX.
- Step 1: process files before the rest of data, save them to disk and database.
- Step 2: process the rest of field inputs, validate and the save them all.
HTML
<div id="wrapper">
<form id="example-form" method="post" action="">
<div class="form-group">
<label for="Model[name]">Text input</label>
<input type="text" class="form-control" name="Model[name]">
</div>
<div class="form-group">
<label for="Model[file]">File input</label>
<input type="file" class="form-control" name="Model[file]">
</div>
<div class="form-group">
<label for="Model[file2]">File input 2</label>
<input type="file" class="form-control" name="Model[file2]">
</div>
<input type="submit" class="btn btn-primary" value="Send">
<div id="ajax-form-results"></div>
</form>
</div>
Javascript
// Variable to store your files
var files;
// on submit, preprocess files
$('#wrapper').on('submit', 'form', uploadFiles);
/**
* Catch the form submit and upload the files
* @param {object} event
* @returns {Boolean}
*/
function uploadFiles(event) {
// create a formdata object and add the files #}
var filesData = new FormData();
// find files
var files = [];
$(this).find('input[type="file"]').each(function() {
if ($(this).val() !== "") {
files.push($(this)[0].files[0]);
}
});
// if form has files...
if (files.length > 0) {
$.each(files, function (key, value) {
filesData.append(key, value);
});
$.ajax({
url: 'ajaxFileUpload.php',
type: 'POST',
data: filesData,
cache: false,
dataType: 'json',
processData: false, // Don't process the files
contentType: false, // Set content type to false as jQuery will tell the server its a query string request
success: function (filesData) {
if (data.success === true) {
// success so call function to process the form
submitForm(event, filesData);
} else {
// handle errors here
$('#ajax-form-results').html(filesData.error);
}
},
error: function (filesData) {
// handle errors here
console.log('Errors ajaxFileUpload: ' + filesData.error);
}
});
} else {
// process the form without files
submitForm(event, filesData);
}
return false;
} // end uploadFiles()
/**
* Proccess the form submit
* @param {object} event
* @param {object} filesData
* @returns {void}
*/
function submitForm(event, filesData {
// create a jQuery object from the form
var form = $(event.target);
// serialize the form data
var formData = form.serialize();
// if the form has files, add to formData
if (filesData.length > 0) {
$.each(filesData.files, function (key, value) {
formData = formData + '&filenames[]=' + value;
});
}
$.ajax({
url: 'ajaxSubmitForm.php',
type: 'POST',
data: formData,
cache: false,
dataType: 'json',
success: function (data) {
if (data.success === true) {
// do whatever, send a OK message for example
$('#ajax-form-results').html(data.message);
// we can refresh some page content here...
} else {
// Handle errors here
$('#ajax-form-results').html(data.error);
}
// in case we made a submit form by Bootstrap modal, hide it by force
$('body').removeClass('modal-open');
$('.modal').modal('hide');
$('.modal-backdrop').remove();
},
error: function (data) {
// Handle errors here
console.log('Errors ajaxSubmitForm: ' + data.error);
}
});
} // end submitForm
ajaxFileUpload.php
<?php
$data = [];
// if any files, start...
if (isset($_FILES[0])) {
$success = true;
$files = [];
// upload dir example
$uploadDir = 'uploads/files/';
if (!is_dir($uploadDir)) {
mkdir($uploadDir);
}
foreach ($_FILES as $file) {
$fileName = time() . '_' . $file['name'];
if (move_uploaded_file($file['tmp_name'], $uploadDir . basename($fileName))) {
$fileModel = new FileExampleModel();
$fileModel->filename = $fileName;
$fileModel->filepath = $uploadDir . $fileName;
$fileModel->filemime = $file['type'];
$fileModel->filesize = $file['size'];
$fileModel->origname = $file['name'];
$fileModel->status = true;
if (!$fileModel->save()) {
$success = false;
break;
}
// return id from database to link later in the last step
$files[] = $fileModel->id;
} else {
$success = false;
}
}
if ($success === true) {
$data = ['success' => $success, 'files' => $files];
} else {
$data = ['error' => 'There was an error uploading your files'];
}
} else {
$data = ['success' => $success];
}
echo json_encode($data);
ajaxSubmitForm.php
<?php
$success = false;
$message = null;
if (isset($_POST['Model'])) {
// example save Model data
$model = new ModelExample();
$model->setAttributes($_POST['Model']);
$model->validate();
if ($model->save()) {
// assign files if we send them by 'filenames' value in the javascript function submitForm
if (isset($_POST['filenames'])) {
foreach ($_POST['filenames'] as $fileId) {
$modelFileRelation = new FileExampleRelationModel();
$modelFileRelation->model_id = $model->id;
$modelFileRelation->file_id = $fileId;
$modelFileRelation->save();
}
}
$success = true;
$message = 'Form submitted correctly';
} else {
// if something go wrong, we should control what to do with the uploaded files
$success = false;
$message = $model->getErrorMessage();
}
}
echo json_encode(['success' => $success, 'message' => $message]);