Gem jquery_file_upload 怎么配置使用

yeyong14 · 2013年09月11日 · 最后由 yeyong14 回复于 2013年09月12日 · 8635 次阅读

想用jquery_file_upload做一个上传多张图片 一个product有多张图片,把这个加进去之后,点击不能向 Demo 的那样,添加到下面待上传的地方, 但是我点击上传,居然也上传上了,但只是一张图片

class Photo < ActiveRecord::Base
  attr_accessible :image
  belongs_to :product
 mount_uploader :image, ImageUploader

end

 class Product < ActiveRecord::Base
  has_many :photos
end

#控制器
class ProductsController < ApplicationController

  def new
  @product = Product.new
  @product.photos.build
 end
<%= form_for @product do |f| %>
<div class="container">
  <h2>Upload file</h2>
  <%= f.fields_for :photos :html => { :multipart => true, :id => "fileupload"  } do |pho| %>
    <!-- The fileupload-buttonbar contains buttons to add/delete files and start/cancel the upload -->
    <div class="row fileupload-buttonbar">
      <div class="span7">
        <!-- The fileinput-button span is used to style the file input field as button -->
        <span class="btn btn-success fileinput-button">
          <i class="icon-plus icon-white"></i>
          <span>Add files...</span>
          <%= pho.file_field :image %>
        </span>
        <button type="submit" class="btn btn-primary start">
          <i class="icon-upload icon-white"></i>
          <span>Start upload</span>
        </button>
        <button type="reset" class="btn btn-warning cancel">
          <i class="icon-ban-circle icon-white"></i>
          <span>Cancel upload</span>
        </button>
        <button type="button" class="btn btn-danger delete">
          <i class="icon-trash icon-white"></i>
          <span>Delete</span>
        </button>
        <input type="checkbox" class="toggle">
      </div>
      <div class="span5">
        <!-- The global progress bar -->
        <div class="progress progress-success progress-striped active fade">
          <div class="bar" style="width:0%;"></div>
        </div>
      </div>
    </div>
    <!-- The loading indicator is shown during image processing -->
    <div class="fileupload-loading"></div>
    <br>
    <!-- The table listing the files available for upload/download -->
    <table class="table table-striped"><tbody class="files" data-toggle="modal-gallery" data-target="#modal-gallery"></tbody>
    </table>
  <% end %>

</div>
<script>
  var fileUploadErrors = {
  maxFileSize: 'File is too big',
  minFileSize: 'File is too small',
  acceptFileTypes: 'Filetype not allowed',
  maxNumberOfFiles: 'Max number of files exceeded',
  uploadedBytes: 'Uploaded bytes exceed file size',
  emptyResult: 'Empty file upload result'
  };
</script>

<!-- The template to display files available for upload -->
<script id="template-upload" type="text/x-tmpl">
  {% for (var i=0, file; file=o.files[i]; i++) { %}
  <tr class="template-upload fade">
    <td class="preview"><span class="fade"></span></td>
    <td class="name"><span>{%=file.name%}</span></td>
    <td class="size"><span>{%=o.formatFileSize(file.size)%}</span></td>
    {% if (file.error) { %}
    <td class="error" colspan="2"><span class="label label-important">{%=locale.fileupload.error%}</span> {%=locale.fileupload.errors[file.error] || file.error%}</td>
    {% } else if (o.files.valid && !i) { %}
    <td>
      <div class="progress progress-success progress-striped active"><div class="bar" style="width:0%;"></div></div>
    </td>
    <td class="start">{% if (!o.options.autoUpload) { %}
      <button class="btn btn-primary">
        <i class="icon-upload icon-white"></i>
        <span>{%=locale.fileupload.start%}</span>
      </button>
      {% } %}</td>
    {% } else { %}
    <td colspan="2"></td>
    {% } %}
    <td class="cancel">{% if (!i) { %}
      <button class="btn btn-warning">
        <i class="icon-ban-circle icon-white"></i>
        <span>{%=locale.fileupload.cancel%}</span>
      </button>
      {% } %}</td>
  </tr>
  {% } %}
</script>
<!-- The template to display files available for download -->
<script id="template-download" type="text/x-tmpl">
  {% for (var i=0, file; file=o.files[i]; i++) { %}
    <tr class="template-download fade">
      {% if (file.error) { %}
        <td></td>
        <td class="name"><span>{%=file.name%}</span></td>
        <td class="size"><span>{%=o.formatFileSize(file.size)%}</span></td>
        <td class="error" colspan="2"><span class="label label-important">{%=locale.fileupload.error%}</span> {%=locale.fileupload.errors[file.error] || file.error%}</td>
        {% } else { %}
        <td class="preview">{% if (file.thumbnail_url) { %}
          <a href="{%=file.url%}" title="{%=file.name%}" rel="gallery" download="{%=file.name%}"><img src="{%=file.thumbnail_url%}"></a>
          {% } %}</td>
        <td class="name">
          <a href="{%=file.url%}" title="{%=file.name%}" rel="{%=file.thumbnail_url&&'gallery'%}" download="{%=file.name%}">{%=file.name%}</a>
        </td>
        <td class="size"><span>{%=o.formatFileSize(file.size)%}</span></td>
        <td colspan="2"></td>
        {% } %}
      <td class="delete">
        <button class="btn btn-danger" data-type="{%=file.delete_type%}" data-url="{%=file.delete_url%}">
          <i class="icon-trash icon-white"></i>
          <span>{%=locale.fileupload.destroy%}</span>
        </button>
        <input type="checkbox" name="delete" value="1">
      </td>
    </tr>
    {% } %}
</script>

<script type="text/javascript" charset="utf-8">
  $(function () {
      // Initialize the jQuery File Upload widget:
      $('#fileupload').fileupload();
      // 
      // Load existing files:
      $.getJSON($('#fileupload').prop('action'), function (files) {
        var fu = $('#fileupload').data('blueimpFileupload'), 
          template;
        fu._adjustMaxNumberOfFiles(-files.length);
        console.log(files);
        template = fu._renderDownload(files)
          .appendTo($('#fileupload .files'));
        // Force reflow:
        fu._reflow = fu._transition && template.length &&
          template[0].offsetWidth;
        template.addClass('in');
        $('#loading').remove();
      });

  });
</script>
<%= f,submit %>
<% end %>

代码太长,没仔细看,不负责任猜想呢:既然上传是可以成功的,那么代表代码逻辑没有问题,所以问题很可能出现在没有正确的选择 preview 的标签位置,插件不知道该把 preview 插到 DOM 哪里。

BTW,你下面给出的 JS 里只有加载存在的文件的部分,没有上传或插入 preview 的部分啊?还是已经封装在插件里面了?这样的话插件里应该有 option 可以指定 preview 的插入位置吧?找找看。

preview 是需要自己寫的,可以看下它的 demo 裏是怎麼寫的。

这个 build,默认只 build 一个 photo,不知道有没有关系(代码太长没仔细看,也不负责任猜一个)

demo 给的 preview 好像是用 js 的 template 写的,看着代码好多,那块看着感觉不太好定制的样子...可以只用 jquery_file_upload 最基本的那个插件 https://github.com/blueimp/jQuery-File-Upload/wiki/Basic-plugin ,其他的自己写

猜想你点击上传,应该是你直提交了表单

这个插件有一些默认的规则吧,form 的 action 属性为图片上传的 create 和 index 而你这里,却是 product 的 create 和 index

我前天刚好实现,没有嵌套,只有一层:

<%= form_for Photo.new, :html => { :multipart => true, :id => "fileupload"  } do |f| %>
<%= f.file_field :image, :multiple => true, :name => "photo[image]" %>
<% end %>
$.getJSON($('#fileupload').prop('action'), function (files) { .... });

这里会去你的 PhotosController#index as JSON 里去拿你上传过的图片

你需要在 Model 里加一个 to_jq_upload 方法

class Photo < ActiveRecord::Base
  include Rails.application.routes.url_helpers
  mount_uploader :image, PhotoUploader

  def to_jq_upload
    {
      :name => image.file.filename,
      :size => image.file.size,
      :url => image_url,
      :thumbnail_url => image.small.url,
      :delete_url => photo_path(self),
      :delete_type => "DELETE"
    }
  end
end

Controller:

class PhotosController < ApplicationController

  def index
    @photos = Photo.all

    respond_to do |format|
      format.html
      format.json { render :json => @photos.map{|photo| photo.to_jq_upload }}
    end
  end

  def create
    @photo = @entity.photos.new(params[:photo])

    respond_to do |format|
      if @photo.save
        format.html { redirect_to @photo, notice: 'Photo was successfully created.' }
        format.json { render :json => {files: [@photo.to_jq_upload]}, status: :created }#, location: photo_url(@photo)
      else
        format.html { render action: 'new' }
        format.json { render json: @photo.errors, status: :unprocessable_entity }
      end
    end
  end

end

如果你一定要在 product 的 new 页面里先把图片给上传掉,那你应该在

$('#fileupload').fileupload();

里面指定上传的 url

https://github.com/blueimp/jQuery-File-Upload/wiki/Options#url

不要直接抄他们的示例代码,建议你自己做个简单的小 demo 一步一步的增加配置, 把 basic 插件先运行起来,如果有需要更多更高级功能,再折腾 UI 仔细读读 jquery-files-upload 的 API 和 Options 这两篇 WikiPage。


另外,我这里有个刚出炉的副产物,jQuery-File-Upload 直传文件到 Qniu,如果有人用 Qiniu 可以看看 https://github.com/huobazi/qiniu_direct_upuloader

@huobazi @miclle @KoALa 谢谢你们指导,我现在就试,

需要 登录 后方可回复, 如果你还没有账号请 注册新账号