I have a form to update my news post which have title, content and image upload button at the same page. The image uploader use Kartik FileINput widget for Yii2 applying Ajax method.
This is my actionUpload that processed the AJAX uploading
public function actionUpload($id)
{
$model = $this->findModel($id);
$currentImage=$model->image;
if (Yii::$app->request->isAjax)
{
\Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
$image = $model->uploadImage();
if($image===false)
{
//echo "image instance is empty";
$model->image = $currentImage;
}
if ($model->validate() && $model->save())
{
if($image !== false)
{
$model->image = $image->basename.'.'.$image->extension;
$image->saveAs('uploads/batam/'.$model->image);
$model->save(false);
return \yii\helpers\Json::encode(array("image" => $model->image,
));
}
}
else
{echo "validation failed";}
}
}
This is my widget file upload filed in my form (note : it's inside the active form)
echo FileInput::widget([
'name' => 'image',
'options'=>[
'multiple'=>false
],
'pluginOptions' => [
'uploadUrl' => Url::to(['news/upload','id'=>$id]),
'uploadExtraData' => [
'id'=>$id,
],
'initialPreview'=>[
Yii::getAlias('@web').'/uploads/batam'.$model->image
],
'initialPreviewAsData'=>true,
'overwriteInitial'=>false,
'maxFileSize'=>2800
]
]);
this is my model rule and uploadImage method
public function rules()
{
return [
[['title', 'content'], 'required'],
[['content'], 'string'],
[['created_at', 'updated_at'], 'safe'],
[['image'], 'file','skipOnEmpty'=>true, 'extensions'=>'jpg,png,jpeg'],
[['title'], 'string', 'max' => 255],
];
}
public function uploadImage() {
$image = UploadedFile::getInstanceByName('image');
if (empty($image)) {
return false;
}
return $image;
}
I have 2 issues here that needs help :
1. The validation rules won't work. I can upload any file with any extension and it's succesfully uploaded and updated in the database
2. The image upload was contained within the active form, so after a successful upload using AJAX, when I press 'update' button, the image won't display. The image
field is treated as empty, so the update
button behave as if I updated an empty image. In my database the image path of the AJAX-uploaded file of the respected news-id
has been succesfully stored and the file is uploaded.
How to solve this? Actually I don't mind if the upload method didn't use AJAX but just the ordinary, single form submit method with post
, thus omitting the upload
ajax button, but according to Kartik documentary, if I want to use the widget that display the previously stored image, it needs Ajax.
I had looked around some similar question in StackOverflow etc but all of them had the problem with empty image instance in the Ajax call method ( well, I previously faced the same problem, but i had apply the Formdata on my ajax after I researched), while I don't have the problem with the empty instance on ajax call, but empty instance on the normal form submit.
This is my actionUpdate
public function actionUpdate($id)
{
$model = $this->findModel($id);
$image= UploadedFile::getInstanceByName('image');
if ($model->load(Yii::$app->request->post()) && $model->save() ){
var_dump($image);exit();
return $this->redirect(['view', 'id' => $model->id]);
} else {
return $this->render('update', [
'model' => $model,
]);
}
}
Thanks in advance!