Yii2 - Kartik file input - update

In this situation: I am new to Yii2 and wanted to use some file loader widget in ActiveForm .. so far I have found this great option: \ Kartik \ widget \ FileInput

With this widget, I can control the downloading of files, and then, when you enter the editing mode, show the previous downloaded image with the possibility of replacing it.

The problem is that if I click the "Refresh" button on the form without changing the image, yii says that the image "cannot be empty" because I set the rule to "mandatory" in my model.

+6
source share
4 answers

After a terrible day and a more productive night, I came across a solution that worked for me.

The main problem was that when updating the input file does not send its value (the name of the file stored in the database). It only sends information about the picture if it is viewed and selected by entering a file.

So, my workaround was to create another "virtual" field for controlling file upload called "upload_image". To do this, I simply added a public property with this name to my model class: public $upload_image;

I also add the following validation procedure to the Model class:

  public function rules() { return [ [['upload_image'], 'file', 'extensions' => 'png, jpg', 'skipOnEmpty' => true], [['image'], 'required'], ]; } 

Here "upload_image" is my virtual column. I added the “file” with “skipOnEmpty” = true, and the “image” is a field in my database, which should be necessary in my case.

Then, in my opinion, I set up the upload_image widget, for example:

  echo FileInput::widget([ 'model' => $model, 'attribute' => 'upload_image', 'pluginOptions' => [ 'initialPreview'=>[ Html::img("/uploads/" . $model->image) ], 'overwriteInitial'=>true ] ]); 

In the "initialPreview" option, I assign the name of my image stored in the "$ model-> image" property returned from the database.

Finally, my controller looks like this:

 public function actionUpdate($id) { $model = $this->findModel($id); $model->load(Yii::$app->request->post()); if(Yii::$app->request->isPost){ //Try to get file info $upload_image = \yii\web\UploadedFile::getInstance($model, 'upload_image'); //If received, then I get the file name and asign it to $model->image in order to store it in db if(!empty($upload_image)){ $image_name = $upload_image->name; $model->image = $image_name; } //I proceed to validate model. Notice that will validate that 'image' is required and also 'image_upload' as file, but this last is optional if ($model->validate() && $model->save()) { //If all went OK, then I proceed to save the image in filesystem if(!empty($upload_image)){ $upload_image->saveAs('uploads/' . $image_name); } return $this->redirect(['view', 'id' => $model->id]); } } return $this->render('update', [ 'model' => $model, ]); } 
+7
source

I came across another solution by creating scripts. In your case, I would change the following rules:

 public funtion rules() { [['image'], 'file'], [['image'], 'required', 'on'=> 'create'] } 

Therefore, the fileupload field is only required in the create action. In the update action, I have this code:

 public function actionUpdate($id) { $model = $this->findModel($id); if ($model->load(Yii::$app->request->post())) { $newCover = UploadedFile::getInstance($model, 'image'); if (!empty($newCover)) { $newCoverName = Yii::$app->security->generateRandomString(); unlink($model->cover); $model->cover = 'uploads/covers/' . $newCoverName . '.' . $newCover->extension; $newCover->saveAs('uploads/covers/' . $newCoverName . '.' . $newCover->extension); } if ($model->validate() && $model->save()) { return $this->redirect(['view', 'id' => $model->post_id]); } else { // error saving model } } else { return $this->render('update', [ 'model' => $model, ]); } } 

In the upgrade script, an image is not required, but the code checks to see if nothing has been loaded and will not change the previous value.

My form file:

 <?= $form->field($model, 'image')->widget(FileInput::classname(), [ 'options' => ['accept'=>'image/*'], 'pluginOptions'=>[ 'allowedFileExtensions'=>['jpg', 'gif', 'png', 'bmp'], 'showUpload' => true, 'initialPreview' => [ $model->cover ? Html::img($model->cover) : null, // checks the models to display the preview ], 'overwriteInitial' => false, ], ]); ?> 

I think this is a little easier than a virtual field. Hope this helps!

+4
source

Try to preload the file input field with the contents of this field. This way you won’t lose data after submitting your form.

I looked at the kartik file input widget (nice find, btw) and I came across a way to do this

 // Display an initial preview of files with caption // (useful in UPDATE scenarios). Set overwrite `initialPreview` // to `false` to append uploaded images to the initial preview. echo FileInput::widget([ 'name' => 'attachment_49[]', 'options' => [ 'multiple' => true ], 'pluginOptions' => [ 'initialPreview' => [ Html::img("/images/moon.jpg", ['class'=>'file-preview-image', 'alt'=>'The Moon', 'title'=>'The Moon']), Html::img("/images/earth.jpg", ['class'=>'file-preview-image', 'alt'=>'The Earth', 'title'=>'The Earth']), ], 'initialCaption'=>"The Moon and the Earth", 'overwriteInitial'=>false ] ]); 

You may also want to relax the required rule in your model for this field so that it does not complain about validation. You can request the user through more subtle means.

+2
source

From Kraj:

http://webtips.krajee.com/advanced-upload-using-yii2-fileinput-widget

Create, delete, update: very simple, look no further.

(1) I also set the 'required' rule in my model.

(2) To work with Wampserver:

 Yii::$app->params['uploadPath'] = Yii::$app->basePath . '/web/uploads/'; Yii::$app->params['uploadUrl'] = Yii::$app->urlManager->baseUrl . '/uploads/'; 
-4
source

Source: https://habr.com/ru/post/1216243/


All Articles