dtczp02204 2019-06-28 03:17
浏览 127

使用Ajax方法通过Kartik FileInput Yii2小部件成功上传后更新图像时图像为空

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!

  • 写回答

1条回答 默认 最新

  • duanbai1974 2019-06-28 06:50
    关注

    First of all, the reason why the validators are not working is because you are NOT creating the file input widget from the model, you must do it this way in order for your rules in the class model to work:

    echo $form->field($model, 'image')->widget(FileInput::classname(), [
        'options' => ['accept' => 'image/*'],
    ]);
    

    Then I don't know how the structure of your database, but my advice for how to handle image uploads. Is, first, to create a public variable inside the class separated from the image field of the database, this public image variable will be the one that will instanciate the widget on the form and also the one with the rules. This way, when you post your form, the image field from the database will not be overwrited.

    So, then when you upload using ajax, you will send the id of the object too, and in the upload function once everything is set, you will store the path, or the image, or whatever in the image field of the database.

    评论

报告相同问题?

悬赏问题

  • ¥15 基于卷积神经网络的声纹识别
  • ¥15 Python中的request,如何使用ssr节点,通过代理requests网页。本人在泰国,需要用大陆ip才能玩网页游戏,合法合规。
  • ¥100 为什么这个恒流源电路不能恒流?
  • ¥15 有偿求跨组件数据流路径图
  • ¥15 写一个方法checkPerson,入参实体类Person,出参布尔值
  • ¥15 我想咨询一下路面纹理三维点云数据处理的一些问题,上传的坐标文件里是怎么对无序点进行编号的,以及xy坐标在处理的时候是进行整体模型分片处理的吗
  • ¥15 CSAPPattacklab
  • ¥15 一直显示正在等待HID—ISP
  • ¥15 Python turtle 画图
  • ¥15 stm32开发clion时遇到的编译问题