Reputation: 425
I want to upload file using Ajax in yii2 framework this is my code, but in controller "get Instance" return null because of serialize data; how can i do this?
This is my controller:
<?php
public function actionUpdate($id)
{
$model = Signature::findOne([
'user_id' => $id,
]);
if ($model->load(Yii::$app->request->post())) {
$model->file = UploadedFile::getInstance($model, 'file');
$model->file->saveAs('uploads/signature/' . $model->user_id . '.' . $model->file->extension);
$model->url = 'uploads/signature/' . $model->user_id . '.' . $model->file->extension;
if ($model->save()) {
echo 1;
} else {
echo 0;
echo $model->file;
}
} else {
return $this->renderAjax('update', [
'model' => $model,
]);
}
}
?>
This is my script code I can't get my file in controller and it return null
<?php $script = <<<JS
$('form#{$model->formName()}').on('beforeSubmit', function(e)
{
var \$form = $(this);
$.post(
\$form.attr("action"),
\$form.serialize(),
)
.done(function(result){
if(result == 1)
{
$(document).find('#update_signature_modal').modal('hide');
$.pjax.reload({container:'#branchesGrid'});
//alert();
} else {
alert(result);
}
}).fail(function()
{
console.log("server error");
});
return false;
});
JS;
$this->registerJs($script);
?>
Upvotes: 4
Views: 19616
Reputation: 1036
Use FormData to get the instance of file/image type data
$( '#my-form' )
.submit( function( e ) {
$.ajax( {
url: 'http://host.com/action/',
type: 'POST',
data: new FormData( this ),
processData: false,
contentType: false
} );
e.preventDefault();
} );
Upvotes: 3
Reputation: 3450
The Problem
What the problem in ajax is that $_FILES
details are not sent in asynchroous request.
When we submit the filled form without ajax request and debug in backend side in PHP by
echo '<pre>';
print_r($_FILES);
print_r($_POST);
echo '</pre>';
die;
then we successfuly get $_FILES
and $_POST
data.
But when we debug the same thing in ajax request, we get only $_POST
values and we get $_FILES
as NULL
. This led us to conclusion that $_FILES
data are not sent in ajax request by our above code.
The Solution
We need to use FormData
of JavaScript.
What does it do?
In simple words, it adds all necessary information of file which needs to be uploaded to data
param in $.ajax
OR fill up $_FILES
as well as all $_POST
data ie non file input such as strings number etc.
In your view file
<?php $form = ActiveForm::begin(['options' => ['enctype' => 'multipart/form-data']]) ?>
<?= $form->field($model, 'title') ?>
<?= $form->field($model, 'imageFile')->fileInput() ?>
<button type="button" class="btn btn-success subm">Upload</button>
<?php ActiveForm::end(); ?>
<script>
$('.subm').click(function(e){
var formData = new FormData($('form')[0]);
console.log(formData);
$.ajax({
url: "some_php_file.php", //Server script to process data
type: 'POST',
// Form data
data: formData,
beforeSend: beforeSendHandler, // its a function which you have to define
success: function(response) {
console.log(response);
},
error: function(){
alert('ERROR at PHP side!!');
},
//Options to tell jQuery not to process data or worry about content-type.
cache: false,
contentType: false,
processData: false
});
});
</script>
Testing
Now make ajax request and debug in PHP code by print_r()
as shown above, you will notice that $_FILES
is not NULL and its contains all file (which needs to be uploaded) data. And if it is set you can upload using move_uploaded_file()
funtion
So this is how you file is uploaded via Ajax.
Upvotes: 8