我有一个简单表单(产品模型)
,并且我还使用cocoon gem
作为嵌套字段(附件模型)
我在那个表格里有。当我创建产品时,我使用 cocoon gem 作为嵌套字段,以便创建附件(图像)并将它们与该产品关联。用户可以添加茧字段并向该字段添加图像。我还在每个字段内提供预览,以便用户可以查看附加到该字段的图像。但唯一的问题是预览只显示在第一个茧域中。如果我尝试将图像添加到另一个茧域中,图像预览不会出现在该域内。我希望能够添加一个茧字段,然后将图像添加到该字段并查看该字段内该图像的预览。关于如何更改代码以实现上述目标的任何想法?
这是我的设置:
<%= 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>
attachment_fields 部分:
<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>
图像预览:
$("#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.");
}
});
更新1
我通过对 @nathanvda 答案的细微调整使其工作。但我有一个小故障。如果我一次添加一个字段,预览会出现在每个字段中,但如果我添加多个字段,则会出现下图所示的问题。知道如何解决这个问题吗?
这是我正在使用的确切代码:
<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.");
}
})
});
最佳答案
您使用 id 为 #divImageMediaPreview
的元素:这意味着 html 期望该元素在页面上仅出现一次。您需要为元素指定一个类,然后搜索最接近的实例。
例如,在您的 View 中写
<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>
然后在您的代码中执行以下操作:
$("#ImageMedias").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.");
}
});
所以主要的变化是
let dvPreview = $(this).parents(".image-border").find(".image-media-preview");
这将在 DOM 树中使用 image-border
类向上搜索父元素,然后我们沿着 DOM 向下查找预览元素。更简单的 $(this).closest('.image-media-preview')
也可能有效,但我不确定。
关于javascript - rails : Image preview inside a cocoon gem field,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61793003/