RoR:使用带有jQuery可排序的Dropzone.js

时间:2015-01-11 07:24:56

标签: jquery ruby-on-rails jquery-ui-sortable dropzone.js

我在我的rails应用程序中将Dropzone Js与paperclip结合使用,我还设法应用jquery进行排序。

我的目标是:

  1. 能够将每个图像的位置保存到数据库中 上传成功
  2. 当我更改(排序)图像的顺序时,更新数据库中每个图像的位置。
  3. 我的上传模型有:image和:position 我的路线有收集{post" sort"}

    我的控制器代码:

    class UploadsController < ApplicationController
    
      def new
        @upload = Upload.new
      end
    
      def upload_list
        @uploads = Upload.all.select(:id, :image_file_name, :image_file_size).order("position")
    
        respond_to do |format|
          format.json {render json: @uploads.to_json(methods: [:path])}
        end
      end
    
      def create
        @upload = Upload.create(upload_params)
        @upload.position = params[:upload][:position]
    
        if @upload.save
          render json: { message: "success", fileID: @upload.id }, :status => 200
        else
          render json: { error: @upload.errors.full_messages.join(',')}, :status => 400
        end
      end
    
      def sort
        //params[:upload] gives undefined method for nil error 
        Upload.all.each_with_index do |id, index|
          Upload.where(id: id).update_all({position: index+1})
        end
        render nothing: true
      end
    
      def destroy
        @upload = Upload.find(params[:id])
        if @upload.destroy
          render json: { message: "File deleted from server" }
        else
          render json: { message: @upload.errors.full_messages.join(',') }
        end
      end
    
      private
        def upload_params
          params.require(:upload).permit(:image, :position)
        end
    end  
    

    upload.rb:

    class Upload < ActiveRecord::Base
    
      has_attached_file :image, :styles => { :medium => "300x300>",:thumb => "100x100>" }
    
      validates_attachment :image,
                       :presence => true,
                       :content_type => { :content_type => /\Aimage\/.*\Z/ },
                       :size => { :less_than => 1.megabyte } 
    
      def path
        image.url
      end
    
      def as_json(options = { })
        h = super(options)
        h["name"] = h.delete "image_file_name"
        h["size"] = h.delete "image_file_size"
        h
      end
    
    end 
    

    new.html.erb:

    <h1>Uploads#new</h1>
    
    <%= form_for(@upload, html: { multipart: true, class: "dropzone"}) do |f| %>
      <div class="fallback">
        <%= f.file_field :image %>
        <%= f.submit "Upload" %>
      </div>
    <% end %>  
    

    最后是uploads.js:

    $(document).ready(function(){
    
      Dropzone.autoDiscover = false;
    
      $("#new_upload").dropzone({
        maxFilesize: 1,
        paramName: "upload[image]",
        addRemoveLinks: true,
        dictRemoveFile: "Delete",
    
        //to show existing images from db 
        init: function() {
          var thisDropZone = this;
          $.getJSON('upload_list', function(data) {
            $.each(data, function(index, val) {
              var mockFile = { name: val.name, size: val.size };
              thisDropZone.emit("addedfile", mockFile);
              thisDropZone.emit("thumbnail", mockFile, val.path);
              $(mockFile.previewTemplate).find('.dz-remove').attr('id', val.id);
    
              // adding id attribute for serialize
              $(".dz-preview:last-child").attr('id', "image_" + val.id);
            });
          });
        },
    
        success: function(file, response){
          $(file.previewTemplate).find('.dz-remove').attr('id', response.fileID);
          $(file.previewElement).addClass("dz-success");
    
          var order = $('.dropzone').sortable('serialize');
          $.ajax({
            type: 'POST',
            url: '/uploads/sort',
            data: order,
            success: function(data){
              console.log(data);
            }        
          });
        },
    
        removedfile: function(file){
          var id = $(file.previewTemplate).find('.dz-remove').attr('id');
          file.previewElement.remove();
    
          $.ajax({
            type: 'DELETE',
            url: '/uploads/' + id,
            success: function(data){
              console.log(data.message);
            }
          });
    
          var order = $('.dropzone').sortable('serialize');
          $.ajax({
            type: 'POST',
            url: '/uploads/sort',
            data: order,
            success: function(data){
              console.log(data);
            }        
          });
        }
      });
    
     //this function is for sorting + updating positions of old images loaded by the init function.
      $(function() {
        $(".dropzone").sortable({
          items:'.dz-preview',
          cursor: 'move',
          opacity: 0.5,
          containment: '.dropzone',
          distance: 20,
          update: function(event, ui) {
            var order = $('.dropzone').sortable('serialize');
            $.ajax({
              type: 'POST',
              url: '/uploads/sort',
              data: order,
              success: function(data){
                console.log(data);
              }        
            });
          }
        });
        $(".dropzone").disableSelection();
      });
    }); 
    

    我知道我需要做很多清理工作但是我试图让它先工作。

    我知道我需要一个前面带有&#34; _&#34;在每个图像的.dz-dropzone中预览序列化工作。但是成功函数中的ajax帖子工作正常而没有应用任何id属性,所以当我上传3个图像时,在db中的位置分别为1,2和3,如果删除第二个图像,removefile函数也可以工作, image1获得位置&#34; 1&#34;由于控制器中的sort方法,image3将位置属性更新为2。

    我尝试的是在init函数中添加一行来将id属性附加到.dz-preview并刷新页面,以便我测试init函数并再次尝试排序,但它是一样的,我得到的是:

    Started POST "/uploads/sort" for 127.0.0.1 at 2015-01-12 12:47:39 +0200
    Processing by UploadsController#sort as */*
    Parameters: {"image"=>["318", "320", "319"]}
    Upload Load (2.7ms)  SELECT "uploads".* FROM "uploads"
    SQL (5.4ms)  UPDATE "uploads" SET "position" = 1 WHERE "uploads"."id" = 318
    SQL (14.7ms)  UPDATE "uploads" SET "position" = 2 WHERE "uploads"."id" = 319
    SQL (1.8ms)  UPDATE "uploads" SET "position" = 3 WHERE "uploads"."id" = 320
    Rendered text template (0.1ms)
    Completed 200 OK in 54ms (Views: 2.0ms | ActiveRecord: 29.6ms)
    

    注意参数的顺序,以便图像&#34; 318&#34;应该采取位置1,&#34; 320&#34;应该采取位置2和&#34; 319&#34;应该采取位置3 ......但如图所示,新订单将从更新中被忽略......

    我缺少什么想法?是排序方法还是.sortable函数?

    由于

1 个答案:

答案 0 :(得分:1)

使用以下代码更新排序操作。

  def sort
    images = Upload.where(id: params[:image])
    images.each do |image|
      if position = params[:image].index(image.id.to_s)
        image.update_attribute(:position, position + 1) unless image.position == position
      end 
    end 
    render nothing: true
  end