Javascript Rails:cocoon gem字段内的图像预览
我有一个Javascript Rails:cocoon gem字段内的图像预览,javascript,jquery,ruby-on-rails,cocoon-gem,Javascript,Jquery,Ruby On Rails,Cocoon Gem,我有一个简单表单(产品模型),我还使用cocoon gem作为表单中的嵌套字段(附件模型)。创建产品时,我使用嵌套字段的cococoon gem,以便创建附件(图像),并将它们与该产品关联。用户可以添加cocoon字段并向该字段添加图像。我在每个字段中都有一个预览,用户可以查看他们附加到该字段的图像。但唯一的问题是预览只显示在第一个cocoon字段中。如果我尝试将图像添加到另一个cocoon字段,则该字段内不会显示图像预览。我希望能够添加一个cocoon字段,然后将图像添加到该字段中,并查看该字
简单表单(产品模型)
,我还使用cocoon gem
作为表单中的嵌套字段(附件模型)
。创建产品时,我使用嵌套字段的cococoon gem
,以便创建附件(图像)
,并将它们与该产品关联。用户可以添加cocoon字段并向该字段添加图像。我在每个字段中都有一个预览,用户可以查看他们附加到该字段的图像。但唯一的问题是预览只显示在第一个cocoon字段中。如果我尝试将图像添加到另一个cocoon字段,则该字段内不会显示图像预览。我希望能够添加一个cocoon字段,然后将图像添加到该字段中,并查看该字段中该图像的预览。关于如何改变代码以实现上述目标,有什么想法吗
这是我的设置:
<%= f.simple_fields_for :attachments do |attachment| %>
<%= render 'products/attachment_fields', form: attachment %>
<% end %>
<div class="links" id="add_attachment">
<%= link_to_add_association raw('<i class="fas fa-plus"></i>'), f, :attachments, form_name: 'form' %>
</div>
附件\u部分字段:
<div class="nested-fields">
<div class="col-md-12">
<div class="image-border">
<div class="image-border-content">
<div class="parent">
<div class="image-content" id="divImageMediaPreview">
<div class="font-awesome-image"><i class="far fa-image"></i></div>
</div>
</div>
<label class="btn btn-light btn-sm" style="width: 100%;">
Add a file!
<span style="display:none;">
<%= form.input :image, label: false, as: :file, input_html: { class:"custom-file-input", id: "ImageMedias" } %>
</span>
</label>
</div>
</div>
<div class="links" style="margin-bottom: 10px;">
<%= link_to_remove_association raw('<i class="far fa-trash-alt"></i> Remove'), form, class: "btn btn-light btn-sm", :style => "width: 100%; margin-top: -15px;" %>
</div>
</div>
</div>
添加一个文件!
“宽度:100%;页边距顶部:-15px;”%>
图像预览:
$("#ImageMedias").change(function () {
if (typeof (FileReader) != "undefined") {
let dvPreview = $("#divImageMediaPreview");
dvPreview.html("");
$($(this)[0].files).each(function () {
let file = $(this);
let reader = new FileReader();
reader.onload = function (e) {
let img = $("<img />");
img.attr("style", "width: 100%; height:auto;");
img.attr("src", e.target.result);
dvPreview.append(img);
}
reader.readAsDataURL(file[0]);
});
} else {
alert("This browser does not support HTML5 FileReader.");
}
});
$(“#图像媒体”).change(函数(){
if(typeof(FileReader)!=“未定义”){
让dvPreview=$(“#divImageMediaPreview”);
dvPreview.html(“”);
$($(此)[0]。文件)。每个(函数(){
让file=$(this);
let reader=new FileReader();
reader.onload=函数(e){
设img=$(“
更新1
我对@nathanvda answer做了一些小调整,但我有一个小问题。如果我一次添加一个字段,每个字段中都会出现预览,但如果我添加多个字段,就会出现下图所示的问题。你知道如何解决这个问题吗
这正是我使用的代码:
<div class="nested-fields">
<div class="col-md-12">
<div class="image-border">
<div class="image-border-content">
<div class="parent">
<div class="image-content image-media-preview">
<div class="font-awesome-image"><i class="far fa-image"></i></div>
</div>
</div>
<label class="btn btn-light btn-sm" style="width: 100%;">
Add a file!
<span style="display:none;">
<%= form.input :image, label: false, as: :file, input_html: { class:"custom-file-input" } %>
</span>
</label>
</div>
</div>
<div class="links" id="remove_attachment" style="margin-bottom: 10px;">
<%= link_to_remove_association raw('<i class="far fa-trash-alt"></i> Remove'), form, class: "btn btn-light btn-sm", :style => "width: 100%; margin-top: -15px;" %>
</div>
</div>
</div>
$(function() {
$('input[type=file]').change(function(){
if (typeof (FileReader) != "undefined") {
let dvPreview = $(this).parents(".image-border").find(".image-media-preview");
dvPreview.html("");
$($(this)[0].files).each(function () {
let file = $(this);
let reader = new FileReader();
reader.onload = function (e) {
let img = $("<img />");
img.attr("style", "width: 100%; height:auto;");
img.attr("src", e.target.result);
dvPreview.append(img);
}
reader.readAsDataURL(file[0]);
});
} else {
alert("This browser does not support HTML5 FileReader.");
}
})
});
添加一个文件!
“宽度:100%;页边距顶部:-15px;”%>
$(函数(){
$('input[type=file]')。更改(函数(){
if(typeof(FileReader)!=“未定义”){
让dvPreview=$(this).parents(“.image border”).find(“.image media preview”);
dvPreview.html(“”);
$($(此)[0]。文件)。每个(函数(){
让file=$(this);
let reader=new FileReader();
reader.onload=函数(e){
让img=$(“使用id为#divImageMediaPreview
的元素:这意味着html希望该元素在页面上只出现一次。您需要为该元素指定一个类,然后搜索最近的实例
例如,在您的视图中
<div class="nested-fields">
<div class="col-md-12">
<div class="image-border">
<div class="image-border-content">
<div class="parent">
<div class="image-content image-media-preview">
<div class="font-awesome-image"><i class="far fa-image"></i></div>
</div>
</div>
<label class="btn btn-light btn-sm" style="width: 100%;">
Add a file!
<span style="display:none;">
<%= form.input :image, label: false, as: :file, input_html: { class:"custom-file-input", id: "ImageMedias" } %>
</span>
</label>
</div>
</div>
<div class="links" style="margin-bottom: 10px;">
<%= link_to_remove_association raw('<i class="far fa-trash-alt"></i> Remove'), form, class: "btn btn-light btn-sm", :style => "width: 100%; margin-top: -15px;" %>
</div>
</div>
</div>
这将使用类图像边框
在DOM树中搜索父元素,然后我们向下搜索DOM以查找预览元素。可能更简单的$(this).closest(“.image media preview”)
也能工作,但我不确定。下面的代码解决了同样的问题,我用class=“upload\u preview”
创建了一个div,其中包含给定的图像标记id=“preview\u image”
,然后在更改事件class=“upload\u image”
以形成图像字段:-
注意:-我在创建和编辑页面时使用了相同的表单,这就是为什么我在预览图像时使用了if-else
条件
<%= f.fields_for :images, f.object.images.present? ? f.object.images : f.object.images.build do |image_form| %>
<div class="field-group">
<div class="form-group">
<label class="font-weight-bold">Image</label>
<div class="upload_preview preview_style">
<% if image_form.try(:object).try(:image).present? %>
<img id="preview_image" class="preview_img" src="<%= image_form.try(:object).try(:image_url) %>" alt="" width="40px" height="40px" /> ## image preview
<%else%>
<img id="preview_image" class="preview_img" src="/assets/default-image.png" alt="" width="40px" height="40px" /> ## image preview
<% end %>
</div>
<%= image_form.file_field :image, class: "form-control upload_image"%> ## on change event
</div>
<div class="form-group">
<%= image_form.link_to_remove "Delete image", class: "btn btn-danger btn-sm" %>
</div>
</div>
<% end %>
<div class="form-group">
<%= f.link_to_add "Add more image", :images, class: "btn btn-info btn-sm" %>
</div>
形象
“alt=”“width=“40px”height=“40px”/>图像预览
##图像预览
##关于变革事件
java脚本代码
$(文档).ready(函数(){
$(document).on('change','upload_image',function()){
readURL(this);
});
});
函数readURL(输入){
if(input.files&&input.files[0]){
var reader=new FileReader();
reader.onload=函数(e){
$(输入)。同级('.upload_preview')。子级('#preview_image')。attr('src',e.target.result);
}
reader.readAsDataURL(input.files[0]);
}
}
谢谢@nathanvda的回复。我添加了上面的代码,只有第一个字段显示图像预览,当我尝试将另一个图像添加到另一个字段时,没有显示任何内容。我在控制台中也没有收到任何错误。这是您以前遇到的,对吗?您确实删除了图像内容的id
div?是的,我替换了entire div与此:
我得到了您的答案的帮助。尽管我仍然有一个小问题,我已经更新了我的问题,并提供了有关该问题的所有详细信息,请您看一看,并让我知道我可以做些什么来修复它。这与更新有关。您允许用户选择多个图像吗?如果是,您希望做什么向用户显示?在您的屏幕截图中,似乎只有一张图像的空间。问题是显示两张图像时,只有一张图像的空间。这是如何发生的?当您说“一次添加多个字段”-->这到底意味着什么?
let dvPreview = $(this).parents(".image-border").find(".image-media-preview");
<%= f.fields_for :images, f.object.images.present? ? f.object.images : f.object.images.build do |image_form| %>
<div class="field-group">
<div class="form-group">
<label class="font-weight-bold">Image</label>
<div class="upload_preview preview_style">
<% if image_form.try(:object).try(:image).present? %>
<img id="preview_image" class="preview_img" src="<%= image_form.try(:object).try(:image_url) %>" alt="" width="40px" height="40px" /> ## image preview
<%else%>
<img id="preview_image" class="preview_img" src="/assets/default-image.png" alt="" width="40px" height="40px" /> ## image preview
<% end %>
</div>
<%= image_form.file_field :image, class: "form-control upload_image"%> ## on change event
</div>
<div class="form-group">
<%= image_form.link_to_remove "Delete image", class: "btn btn-danger btn-sm" %>
</div>
</div>
<% end %>
<div class="form-group">
<%= f.link_to_add "Add more image", :images, class: "btn btn-info btn-sm" %>
</div>
<script type="text/javascript">
$(document).ready(function(){
$(document).on('change', '.upload_image', function() {
readURL(this);
});
});
function readURL(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function(e) {
$(input).siblings('.upload_preview').children('#preview_image').attr('src', e.target.result);
}
reader.readAsDataURL(input.files[0]);
}
}
</script>