You are viewing revision #18 of this wiki article.
This version may not be up to date with the latest version.
You may want to view the differences to the latest version.
This is for folks who are using \kartik\widgets\FileInput
to upload files from your client. How do you display an image for update after you have uploaded it to the server using the widget?
Note: The FileInput plugin has been upgraded to v1.5.0 since this wiki is written. With this release, it allows you to set an initial preview and caption of files (for update scenarios). Refer usage demo or plugin docs and plugin demos.
Understanding Basics ¶
The FileInput widget is an enhancement of the HTML5 file input. It offers you the ability to preview your selected files from the client before it is uploaded to the server. It also supports a method to upload single or multiple files from the client to the server. However, this process occurs only one way, as this is limited by the HTML5 file input capability. Hence the file input only pushes/uploads files from client to server and not vice-versa. Therefore, it does not offer a method to fetch a preselected value from the server and display on the client. Hence, once the file is uploaded to the server, you cannot display the uploaded file directly from the file input.
Displaying Uploaded File for Update ¶
Here are the steps for you to show the uploaded file considering a scenario for User profile image upload.
Step 1: Setup Model ¶
You have a User
model and an attribute image_file
that stores the file name of the uploaded image file.
Step 2: Setup Upload Access Paths ¶
You have set the images to be uploaded to a location $baseUrl/uploads
where $baseUrl
is the application baseUrl.
Step 3: Get Display Image Function ¶
Create a simple function in your User
model like this
const IMAGE_PLACEHOLDER = '/images/default_user.jpg';
public function getDisplayImage() {
if (empty($model->image_file)) {
// if you do not want a placeholder
$image = null;
// else if you want to display a placeholder
$image = Html::img(self::IMAGE_PLACEHOLDER, [
'alt'=>Yii::t('app', 'No avatar yet'),
'title'=>Yii::t('app', 'Upload your avatar by selecting browse below'),
'class'=>'file-preview-image'
// add a CSS class to make your image styling consistent
]);
}
else {
$image = Html::img(Yii::$app->urlManager->baseUrl . '/' . $model->image_file, [
'alt'=>Yii::t('app', 'Avatar for ') . $model->username,
'title'=>Yii::t('app', 'Click remove button below to remove this image'),
'class'=>'file-preview-image'
// add a CSS class to make your image styling consistent
]);
}
// enclose in a container if you wish with appropriate styles
return ($image == null) ? null :
Html::tag('div', $image, ['class' => 'file-preview-frame']);
}
Step 4: Delete Image Function ¶
In your model write your function to delete and remove an uploaded image.
public function deleteImage() {
$image = Yii::$app->basePath . '/uploads/' . $this->image_file;
if (unlink($image)) {
$this->image_file = null;
$this->save();
return true;
}
return false;
}
Step 5: Your view/form ¶
Here is how you should render the view/form where you have the file input widget:
// profile.php
// display your image or a placeholder first
echo $model->imageDisplay;
if (empty($model->image_file)) {
echo $form->field($model, 'image_file')->widget(FileInput::classname(), [
'options' => ['accept' => 'image/*'],
]);
}
else {
echo Html::a(
Yii::t('app', 'Remove Image'),
Url::to['/user/deleteImage', 'id'=>$model->id],
['class' => 'btn btn-danger']
);
}
Step 6: Your controller ¶
Include the file removal action in your controller that redirects back to the profile view above
// UserController.php
// NOTE: You must set controller access rules for this action
// below to allow only specific user(s) to delete the image
public function actionDeleteImage($id) {
$model = User::findOne($id);
if ($model->deleteImage()) {
Yii::$app->session->setFlash('success',
'Your image was removed successfully. Upload another by clicking Browse below');
} else {
Yii::$app->session->setFlash('error',
'Error removing image. Please try again later or contact the system admin.');
}
return $this->render('profile', ['model'=>$model]);
}
how to handle non-image files ?
What if the files are not images but pdf, doc, txt, csv or xls. How do you display them ?
Error in Step 5
I'm getting an error here
echo Html::a( Yii::t('app', 'Remove Image'), Url::to['/user/deleteImage', 'id'=>$model->id], ['class' => 'btn btn-danger'] );
syntax error, unexpected '[' on line Url::to['/user/deleteImage', 'id'=>$model->id]
Delete Button in update scenario
It is a very nice widget and super easy to use. As per your note above that in the later versions ( => v1.5.0) the initial preview of images is now possible. However I am looking for a delete button in update scenario when we want to delete a file (already uploaded). For example there 3 files already uploaded (and previewed) but now I want to delete the 3rd one. Is there any option for delete button ?
Thanks
If you have any questions, please ask in the forum instead.
Signup or Login in order to comment.