javascript - rails : Image preview inside a cocoon gem field

标签 javascript jquery ruby-on-rails cocoon-gem

我有一个简单表单(产品模型),并且我还使用cocoon gem作为嵌套字段(附件模型)我在那个表格里有。当我创建产品时,我使用 cocoon gem 作为嵌套字段,以便创建附件(图像)并将它们与该产品关联。用户可以添加茧字段并向该字段添加图像。我还在每个字段内提供预览,以便用户可以查看附加到该字段的图像。但唯一的问题是预览只显示在第一个茧域中。如果我尝试将图像添加到另一个茧域中,图像预览不会出现在该域内。我希望能够添加一个茧字段,然后将图像添加到该字段并查看该字段内该图像的预览。关于如何更改代码以实现上述目标的任何想法?

enter image description here

这是我的设置:

<%= 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 答案的细微调整使其工作。但我有一个小故障。如果我一次添加一个字段,预览会出现在每个字段中,但如果我添加多个字段,则会出现下图所示的问题。知道如何解决这个问题吗?

enter image description here

这是我正在使用的确切代码:

<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/

相关文章:

javascript - 检测打开新选项卡/窗口的原始选项卡(如果有)

javascript - D3 和​​弦图 Google Chrome

javascript - 使用 JavaScript 非阻塞地附加 DOM 元素

ruby-on-rails - Rails 3.2 严格的质量分配默认值

ruby-on-rails - View 中的 Rails 开关案例

javascript - 如何将解析后的URL值从javascript发送到html中img标签的src?

javascript - 垂直向下滑动加载页面

javascript - 使用 Bootstrap FormValidation 验证生成的数字输入

php - 如何在以逗号分隔的单个文本字段中使用多个关键字搜索 mysql 数据库列?

ruby-on-rails - Rails 自定义验证有错误但仍然保存?