【问题标题】:jQuery File Upload in Rails 4.x Nested FormRails 4.x 嵌套表单中的 jQuery 文件上传
【发布时间】:2015-03-15 16:55:45
【问题描述】:

我有一个马模型和一个照片模型。由于我使用的是 Heroku,因此我正在使用 jQuery File Upload 来调整(客户端)图像的大小并直接保存在 Amazon s3 上。

我见过其他类似的问题,使用载波、回形针或非常古老的问题。我不确定你为什么要使用carrierwave/paperclip,但我认为根据heroku所说的,我不希望图像访问服务器可能导致超时。

Heroku recommends 使用 jQuery File Upload 并显示 js 将新文件输入附加到图像链接的值(从 amazon s3 返回)。单独保存照片时我有这个工作。我现在想让它以嵌套形式为 Horse 工作,但 js 没有找到输入(因为它还不存在,因为我认为它是嵌套的)。

我将 Cocoon 用于嵌套表单(我愿意接受任何更好的方法)。我对 javascript/jQuery 不太熟悉,但据我所知,Cocoon 会“隐藏”嵌套元素,直到我单击通过 add_association 添加它。

haml查看代码:

= link_to_add_association 'add photo', f, :photos

点击“添加照片”之前的html源代码

<div class='links'>
<a class="btn btn-default btn-sm add_fields" data-association-insertion-method="after" data-association="photo" data-associations="photos" data-association-insertion-template="&lt;div class=&#39;nested-fields&#39;&gt;
  &lt;fieldset class=&quot;inputs&quot;&gt;&lt;ol&gt;&lt;input type=&quot;file&quot; name=&quot;horse[photos_attributes][new_photos][url]&quot; id=&quot;horse_photos_attributes_new_photos_url&quot; /&gt;
  &lt;input type=&quot;hidden&quot; name=&quot;horse[photos_attributes][new_photos][_destroy]&quot; id=&quot;horse_photos_attributes_new_photos__destroy&quot; value=&quot;false&quot; /&gt;&lt;a class=&quot;remove_fields dynamic&quot; href=&quot;#&quot;&gt;remove photo&lt;/a&gt;
  &lt;/ol&gt;&lt;/fieldset&gt;
&lt;/div&gt;
" href="#">add photo</a>

如何使用此输入以及如何处理正确添加的多个文件上传?

我目前上传的js:

$(function() {
  if ($('#new_horse').length > 0) {
    $.get( "/presign", function( s3params ) {

  $('.direct-upload').find("input:file").each(function(i, elem) {
    var fileInput    = $(elem);
    var form         = $(fileInput.parents('form:first'));
    var submitButton = form.find('input[type="submit"]');
    var progressBar  = $("<div class='bar'></div>");
    var barContainer = $("<div class='progress'></div>").append(progressBar);

    fileInput.fileupload({
      fileInput:       fileInput,
      url:             "http://" + s3params.url.host,
      type:            'POST',
      autoUpload:       true,
      formData:         s3params.fields,
      paramName:        'file', // S3 does not like nested name fields i.e. name="user[avatar_url]"
      dataType:         'XML',  // S3 returns XML if success_action_status is set to 201
      disableImageResize: false,
      imageQuality: 0.5,
      disableImageResize: /Android(?!.*Chrome)|Opera/ 
        .test(window.navigator && navigator.userAgent),
      imageMaxWidth: 500,
      imageMaxHeight: 1000,
      imageOrientation: true,  //auto rotates images
      acceptFileTypes: /(\.|\/)(gif|jpe?g|png)$/i, //I added this to jquery.fileupload-validate: alert('Must Be JPG GIF or PNG Image')
      replaceFileInput: false,
      progressall: function (e, data) {
        var progress = parseInt(data.loaded / data.total * 100, 10);
        progressBar.css('width', progress + '%')
      },
      start: function (e) {
        submitButton.prop('disabled', true);
        fileInput.after(barContainer);
        progressBar.
          css('background', 'green').
          css('display', 'block').
          css('width', '0%').
          text("Loading...");
      },
      done: function(e, data) {
        submitButton.prop('disabled', false);
        progressBar.text("Pre-uploading done... Please Save or Cancel");

        // extract key and generate URL from response
        var key   = $(data.jqXHR.responseXML).find("Key").text();
        var url   = 'https://' + s3params.url.host +'/' + key;

        // remove first input to prevent phantom upload delay
       fileInput.remove();

        // create new hidden input with image url
        var input = $("<input />", { type:'hidden', name: fileInput.attr('name'), value: url })
        var imgPreview =  '<img src="' + url + '">';

        form.append(input);
        form.append(imgPreview);
      },
      fail: function(e, data) {
        submitButton.prop('disabled', false);

        progressBar.
          css("background", "red").
          text("Failed");
      }
    });
  });

    }, 'json');
  }
});

【问题讨论】:

    标签: javascript jquery ruby-on-rails


    【解决方案1】:

    我想我应该先查看 cocoon 文档: http://www.rubydoc.info/gems/cocoon#Callbacks__upon_insert_and_remove_of_items_ http://www.rubydoc.info/gems/cocoon/1.2.6

    我将 upload.js 文件修改为以下内容,它完美地适用于嵌套形式的多个文件:

    // added for file uploading
    // https://devcenter.heroku.com/articles/direct-to-s3-image-uploads-in-rails
    // Get our s3params from our endpoint
    
    $(document).on('ready page:load', function () {
      $('.direct-upload')
        .on('cocoon:after-insert', function(e, photo) {
          console.log('inside cocoon image function');
    
          $.get( "/presign", function( s3params ) {
             $('.direct-upload').find("input:file").each(function(i, elem) {
               console.log('inside nested-fields photo input form');
    
              var fileInput    = $(elem);
              var form         = $(fileInput.parents('form:first'));
              var submitButton = form.find('input[type="submit"]');
              var progressBar  = $("<div class='bar'></div>");
              var barContainer = $("<div class='progress'></div>").append(progressBar);
    
              fileInput.fileupload({
                fileInput:       fileInput,
                url:             "http://" + s3params.url.host,
                type:            'POST',
                autoUpload:       true,
                formData:         s3params.fields,
                paramName:        'file', // S3 does not like nested name fields i.e. name="user[avatar_url]"
                dataType:         'XML',  // S3 returns XML if success_action_status is set to 201
                disableImageResize: false,
                imageQuality: 0.5,
                disableImageResize: /Android(?!.*Chrome)|Opera/ 
                  .test(window.navigator && navigator.userAgent),
                imageMaxWidth: 500,
                imageMaxHeight: 1000,
                imageOrientation: true,  //auto rotates images
                acceptFileTypes: /(\.|\/)(gif|jpe?g|png)$/i, //I added this to jquery.fileupload-validate: alert('Must Be JPG GIF or PNG Image')
                replaceFileInput: false,
                previewMaxWidth: 100,
                previewMaxHeight: 100,
                previewCrop: true,
                progressall: function (e, data) {
                  var progress = parseInt(data.loaded / data.total * 100, 10);
                  progressBar.css('width', progress + '%')
                },
               start: function (e) {
                  submitButton.prop('disabled', true);
                  fileInput.after(barContainer);
                  progressBar.
                  css('background', 'green').
                  css('display', 'block').
                  css('width', '0%').
                  text("Loading...");
               },
               done: function(e, data) {
                  submitButton.prop('disabled', false);
                  progressBar.text("Photo Uploaded");
    
                  // extract key and generate URL from response
                  var key   = $(data.jqXHR.responseXML).find("Key").text();
                  var url   = 'https://' + s3params.url.host +'/' + key;
    
                  // remove first input to prevent phantom upload delay
                 fileInput.remove();
    
                  // create new hidden input with image url
                  var input = $("<input />", { type:'hidden', name: fileInput.attr('name'), value: url })
                  var imgPreview =  '<img src="' + url + '">';
    
                  form.append(input);
                  form.append(imgPreview);
                },
                fail: function(e, data) {
                  submitButton.prop('disabled', false);
                  progressBar.
                  css("background", "red").
                  text("Failed");
                }
    
        }, 'json'); //fileupload
       }); //each file 
    
     }); //presign call
    
    });    // function cocoon
    });    // page ready  
    

    我猜谷歌和一个有据可查的 gem 可以在短期内取代 JS 知识 :-) 我相信它不是很紧,所以请提供任何改进。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-01-06
      • 2014-05-22
      • 1970-01-01
      • 2015-11-21
      • 2012-03-10
      • 1970-01-01
      • 1970-01-01
      • 2011-07-28
      相关资源
      最近更新 更多