Question on YII2. Why when you open the edit form field fileinput is empty?

Good afternoon.
Make a simple form with file download and information on file. To use the fileinput widget from kartik.
Download file figured out. After downloading the file to the variable file I put the name of the file.
The problem is that when I try to edit a record in a form that fileinput field is empty and need to re-load the file. How to fix it? Maybe I need again the file which are stored in the database only the file name to cause the full path to the file?
Code is not posted in full, unrelated entries removed so as not to burden perception.

Post implementation code:
Model InvoicesFile
public function rules()
{
 return [
 [['iid', 'itype', 'name'], 'required'],
 [['iid'], 'integer'],
 [['itype'], 'string'],
 [['file'], 'file'],
 [['name'], 'string', 'max' => 150],
];
}

 public function attributeLabels()
{
 return [
 'id' => 'ID',
 'iid' => 'Account',
 'itype' => 'View file',
 'file' => 'file Link',
 'name' => 'Title',
];
}
public function beforeSave($insert) {
 if ($insert) {
$this->itype='invoice';
}
 return parent::beforeSave($insert);
 }

Mapping (view)
<?php

use yii\helpers\Html;
use kartik\widgets\ActiveForm;
use kartik\select2\Select2;
use kartik\file\FileInput;

/* @var $this yii\web\View */
/* @var $model common\models\InvoicesFiles */
/* @var $form yii\widgets\ActiveForm */
?>

<div class="box box-primary">
 <div class="box-body">
 <?php $form = ActiveForm::begin(['id'=>'form_invoice_file','type' => ActiveForm::TYPE_INLINE ,'options' => ['enctype' => 'multipart/form-data']]);?>
<?=$form->errorSummary($model);?>
 <div class='row'>
 <div class='col-md-6'>
 <?=$form->field($model, 'iid')->widget(Select2::classname(), [
 'data' => Yii::$app->MyFunctions->InvoicesArray(),
 'options' => ['placeholder' => 'Select account','id'=>'invoices-selector'], 
 'pluginOptions' => [
 'allowClear' => true, 
]

]);?>
</div>
 <div class='col-md-6'>
 <?= $form->field($model, 'name')->textInput(['maxlength' => true,'style'=>'width:100%']) ?>
</div>
</div>
 <div class='row'>
 <div class='col-md-6'>
 <?=$form->field($model, 'itype')->widget(Select2::classname(), [
 'data' => $model->typesArray,
 'language' => 'EN',
 'options' => ['placeholder' => 'file View','id'=>'filetype-selector'],
 'pluginOptions' => [
 'allowClear' => true, 
 'width' => '100%'
]
]);?>
</div><?=$model->file;?>
 <div class='col-md-6'>
 <?php echo $form->field($model, 'file')->fileInput(); ?>
 <?php $form->field($model, 'file')->widget(FileInput::classname(), [
 'showMessage' => true,
 'pluginOptions' => [
 'showPreview' => false,
 'showCaption' => true,
 'showRemove' => true,
 'showUpload' => false,
'maxFileSize'=>30720,
]]
);?>
</div>
</div>
 <div class="box-footer">
 <?= Html::submitButton('Save', ['class' => 'btn btn-primary btn-flat']) ?>
</div>

 <!-- /.box-footer-->
 <?php ActiveForm::end(); ?>
</div>

Well, the controller:
namespace backend\controllers;

use Yii;
use common\models\InvoicesFiles;
use common\models\InvoicesFilesSearch;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
use yii\web\UploadedFile;

 public function actionCreate()
{
 $model = new InvoicesFiles();
 if ($model->load(Yii::$app->request->post()) && $model->save()) {

 //File download
 if($model->file = UploadedFile::getInstance($model,'file')){
 //Save the file
 $uploadPath = Yii::getAlias('@frontend/web/uploads/invoices/'.$model->iid.'/');
 if (!file_exists($uploadPath)) { 
 mkdir($uploadPath, 0755, true);
}
 $filename = $model->file->baseName.'.'.$model->file->extension;
if(file_exists($uploadPath.$filename)){unlink($uploadPath.$filename);}
$model->file->saveAs($uploadPath.$filename);
 $model->file =$filename;
$model->save();
 } 
 return $this->redirect(['view', 'id' => $model->id]);
}

 return $this->render('create', [
 'model' => $model,
]);
}

 public function actionUpdate($id)
{
 $model = $this->findModel($id);

 if ($model->load(Yii::$app->request->post()) && $model->save()) {

 //File download
 if($model->file = UploadedFile::getInstance($model,'file')){
 //Save the file
 $uploadPath = Yii::getAlias('@frontend/web/uploads/invoices/'.$model->iid.'/');
 if (!file_exists($uploadPath)) { 
 mkdir($uploadPath, 0755, true);
}
 $filename = $model->file->baseName.'.'.$model->file->extension;
if(file_exists($uploadPath.$filename)){unlink($uploadPath.$filename);}
$model->file->saveAs($uploadPath.$filename);
 $model->file =$filename;
$model->save();
 } 

 return $this->redirect(['view', 'id' => $model->id]);
}

 return $this->render('update', [
 'model' => $model,
]);
 }

March 23rd 20 at 19:37
1 answer
March 23rd 20 at 19:39
Good afternoon.
For this we need to create a couple methods in the model and add some settings in the widget itself.
On the official website there is an example with the settings how to do it. See the output of the widget with two images, and the code is below.
It is necessary to "pluginOptions" to configure the following settings:
1) initialPreview
2) initialPreviewAsData
3) initialPreviewConfig
4) overwriteInitial

The method in the model can look like this:
public function getImagesLinks()
{
 $path = ArrayHelper::getColumn(self::find()->all(), 'pathImg');
 return $path;
}

 public function getImagesLinksData()
{
 $files = UploadsFiles::find()->all();
 return ArrayHelper::toArray($files[
 UploadsFiles::class => [
 'caption' => 'file',
 'key' => 'id'
]
]);
 }

The field widget is:
echo $form->field($model, 'imagesFile')->widget(FileInput::class, [
 'options' => ['accept' => 'image/*', 'multiple' => true],
 'pluginOptions' => [
 'showUpload' => false,
 'showRemove' => false,
'overwriteInitial'=>false,
 'initialPreviewAsData' => true,
 'initialPreview' => $model->imagesLinks,
 'initialPreviewConfig' => $model->imagesLinksData,
 'uploadUrl' => Url::to(['upload-img']),
 'deleteUrl' => Url::to(['delete-img']),
]
])->label('<h3>Test Img</h3>');
Thank you. In principle I do not have images will be and the documents. Therefore, the part from the Preview I think is not needed.
I just don't understand I have a file stored in a folder and in database only the file name. I need to initialPreview to return a value as specified in the database or it is necessary to Supplement it by to the file on the server?

And another question, I don't know why but I have in the model, how strange is a BeforeSave.
Added this code and when in the create action it gives me the record is updated! instead of added. don't understand why.
public function beforeSave($insert)
{
 if (parent::beforeSave($insert)) {
 if ($insert) {
 Yii::$app->session->setFlash('success', 'Record added!');
 } else {
 Yii::$app->session->setFlash('success', 'Record updated!');
}
 return true;
 } else {
 return false;
}
 }
- Chasity.Langosh commented on March 23rd 20 at 19:42
@By.Langosh,
or it is necessary to Supplement it by up to a file on the server

I have stored in the database file path and file name.
If You have stored only the file name, then add to the file name path
In the example I gave, use a method that returns the path to the image and is used in getImagesLinks()
public function getImagesLinks()
{
 $path = ArrayHelper::getColumn(self::find()->all(), 'pathImg');
 return $path;
}

 public function getPathImg()
{
 return Url::home(true) . 'uploads/' . $this->file;
 }

and while in the create action it gives me the record is updated

Because beforeSave() is executed before saving the record.
Do these messages in action, for example:
public function actionSignUp()
{
 $model = new SignupForm();
if($model->load(Yii::$app->request->post())){
if($model->signup()){
 Yii::$app->session->setFlash('success', 'Successfully');
 return $this->goHome();
}
}
 return $this->render('signup', ['model' => $model]);
 }

And in beforeSave() is not necessary to do so. - Sigmund1 commented on March 23rd 20 at 19:45

Find more questions by tags Yii