I'm trying to upload an image via Ajax request and seem to be hitting a similar issue as this question but it has no answer. I'm not sure if they are exactly the same so I'll post all the details I can here and hope the more detail helps someone find an answer.
I'm paraphrasing the below from my code (cutting out a lot of what I think is irrelevant to this question) so any typos you see are likely just me changing the code below.
The following is included in my model:
use yii\web\UploadedFile;
...
class Image extends \yii\db\ActiveRecord
{
public $imageFile;
public function rules()
{
return [
[['imageFile'], 'file', 'skipOnEmpty' => true, 'extensions' => 'png, jpg'],
];
}
public function upload()
{
if ($this->validate()) {
$this->imageFile->saveAs('uploads/' . $this->imageFile->baseName . '.' . $this->imageFile->extension);
return true;
} else {
return false;
}
}
Here is a portion of my view file:
<?php $form = ActiveForm::begin(['options' => ['enctype' => 'multipart/form-data']]) ?>
<?= $form->field($model, 'title') ?>
<?= $form->field($model, 'imageFile')->fileInput() ?>
<?= Html::submitButton('Upload', ['class' => 'btn btn-success']) ?>
<?php ActiveForm::end(); ?>
And the Ajax in the view
$('form').on('beforeSubmit', function(e) {
var form = $(this);
$.post(form.attr('action'), form.serialize()).done(function(result) {
console.log(result)
});
return false; // Prevent default form submit action
});
And the following in my controller
use yii\web\UploadedFile;
...
public function actionUpload()
{
$model = new Image();
if (Yii::$app->request->isAjax) {
$model->load(Yii::$app->request->post());
$model->imageFile = UploadedFile::getInstance($model, 'imageFile');
if ($model->upload()) {
$model->save(); // To save the title to the database
Yii::$app->getSession()->addFlash('success', 'Image uploaded');
return $this->redirect(['index']);
}
}
Yii::$app->response->format = Response::FORMAT_JSON;
return ['return' => 'just me testing here'];
}
The above Ajax will only ever save the title to the database and will not upload the file. If I transition everything to a standard post request I can get it all to work (title is saved to the database and image is uploaded to the proper directory). If I debug around the various views, models, and controllers, it looks like I'm just not getting the imageFile via the Ajax request. The $model->load(Yii::$app->request->post());
loads the title that was submitted via Ajax, so why does that not also pull the file? I thought maybe the $model->imageFiles = UploadedFile::getInstances($model, 'imageFiles');
would be the part that pulls the Ajax submitted files but it doesn't seem to get what I need either. As a test, I even tried treating the imageFile property as plain text and assigning it to another database property to be written and it worked just fine. So it seems it's being included in the model properly, just not being send with the Ajax submit.
Can anyone tell me how, in Yii2, I can submit the form over Ajax, including the selected file?