Lors de la création du site de portfolio, j'avais une fonction de téléchargement d'image, mais il y avait un problème en ce qu'il était difficile de comprendre si une image pouvait être sélectionnée correctement car il n'y avait pas de fonction de prévisualisation.
Par conséquent, j'ai décidé d'ajouter une fonction de prévisualisation d'image et de l'implémenter.
Bien qu'il y ait quelques problèmes, je l'ai mis en œuvre, je voudrais donc le résumer.
View
erb:app/views/posts/_form.html.erb
<%= form_with(model: post, local: true) do |form| %>
<!--···réduction···-->
<div class="form-file custom-file mb-3">
<% if post.image.present? %>
<div class="form-image-uploader__saved-img">
<span class="form-image-uploader__saved-img-inner">
<%= image_tag post.image.to_s %>
</span>
</div>
<div class="block-toggle">
<div class="block-toggle__press">
<div class="btn btn-outline-secondary">
<i class="fas fa-arrow-circle-down"></i>Changer l'image
</div>
</div>
<div class="block-toggle__content" style="display:none;">
<label for="post_image" class="form-image-uploader__preview">
<%= image_tag 'nophoto.jpg' %>
</label>
<%= form.file_field :image, class:'form-image-uploader__save' %>
<%= form.hidden_field :image_cache, class:'form-image-uploader__cache' %>
</div>
</div>
<% else %>
<label for="post_image" class="form-image-uploader__preview">
<%= image_tag 'nophoto.jpg' %>
</label>
<%= form.file_field :image, class:'form-image-uploader__save' %>
<%= form.hidden_field :image_cache, class:'form-image-uploader__cache' %>
<% end %>
</div>
<!--···réduction···-->
<% end %>
JS
ʻThe this.noPhotoImgPath
de la classe ImgUplorader` définit n'importe quel chemin.
app/javascript/packs/application.js
/*Slide Toggle
------------------------------------------------------*/
$(document).on('turbolinks:load', () =>{
$('.block-toggle__press .btn').on('click', event =>{
$(event.currentTarget).parent('.block-toggle__press').next('.block-toggle__content').slideToggle(700);
});
});
/*Image uplorader
------------------------------------------------------*/
$(document).on('turbolinks:load', () =>{
const imgUplorader = new ImgUplorader;
imgUplorader.copyToSaveInput();
});
class ImgUplorader{
constructor(){
this.selectorPreview = '.form-image-uploader__preview';
this.selectorSave = '.form-image-uploader__save';
this.selectorCache = '.form-image-uploader__cache';
this.noPhotoImgPath = '/assets/nophoto.jpg';// <=Nophoto Définir le chemin de l'image
}
/*
* Change preview image to nophoto image when image is not selected
* @param input : Element of current target
*/
copyToSaveInput(){
$(document).on('change', this.selectorSave, event => {
const input = $(event.currentTarget);
const filesLength = input[0].files.length;
const cacheDefaultVal = $(input).next(this.selectorCache)[0].defaultValue;
// Change preview image to nophoto image when image is not selected
if (this.hasNotImg(filesLength)) {
this.changeNoPhotoImg(input);
return;
}
// Change preview image to selected image when image is selected
this.changeSelectedImg(input);
});
}
/*
* Return true when input doesn't have file
* @param filesLength : file length of input
* @return bool
*/
hasCacheDefaultImg(filesLength){
if(filesLength == 0){
return true;
}
return false;
}
/*
* Return true when input doesn't have file
* @param filesLength : file length of input
* @return bool
*/
hasNotImg(filesLength){
if(filesLength == 0){
return true;
}
return false;
}
/*
* Change preview image to nophoto image when image is not selected
* @param input : Element of current target
*/
changeNoPhotoImg(input){
$(input).prev(this.selectorImg).children('img').attr('src', this.noPhotoImgPath);
}
/*
* Change preview image to selected image when image is selected
* @param input : Element of current target
*/
changeSelectedImg(input){
const reader = new FileReader();
reader.onload = (progressEvent) => {
$(input).prev(this.selectorImg).children('img').attr('src', progressEvent.currentTarget.result);
}
const file = input[0].files[0];
reader.readAsDataURL(file);
}
}
SCSS
app/assets/stylesheets/application.scss
/*form-image-uploader
------------------------------------------------------*/
.form-image-uploader {
@at-root {
#{&}__saved-img {
margin-bottom: 1em;
@at-root {
#{&}-inner {
border: 1px solid #ced4da;
border-radius: 0.25rem;
display: inline-block;
}
}
img {
max-height: 300px;
}
}
#{&}__preview {
display: inline-block;
border: 1px solid #ced4da;
border-radius: 0.25rem;
position: relative;
cursor: pointer;
img {
max-width: 100px;
width: auto;
max-height: 100px;
height: 100%;
&:hover {
opacity: 0.7;
}
}
}
}
}
/*block-toggle
------------------------------------------------------*/
.block-toggle {
@at-root {
#{&}__press {
cursor: pointer;
margin-bottom: 0.5em;
}
#{&}__content {
border: 1px solid #ced4da;
border-radius: 0.25rem;
padding: 0.5em;
}
}
}
La vérification d'opération suivante a été effectuée sur Chrome, Firefox et Safari.
La prochaine fois, j'aimerais mettre en œuvre une fonction de prévisualisation d'image qui surmonte les problèmes ci-dessus.
[Rails] Implémentation de la fonction de prévisualisation d'image --Qiita
Aperçu d'image multiple de fichier personnalisé Bootstrap4
Recommended Posts