zoukankan      html  css  js  c++  java
  • rails使用bootstrap3-wysiwyg可视化编辑器并实现自定义图片上传插入功能

    之前在rails开发中使用了ckeditor作为可视化编辑器,不过感觉ckeditor过于庞大,有很多不需要的功能,而且图片上传功能不好控制不同用户可以互相删除图片,感觉很不好。于是考虑更改可视化编辑器,多方考虑选择了bootstrap3-wysiwyg,但是这个编辑器无法实现图片上传功能,还有换行使用br而不是p标签不是很好。于是考虑自定义完善其功能。

    个人原创,版权所有,转载请注明原文出处,并保留原文链接:

    https://www.embbnux.com/2015/03/17/rails_use_bootstrap3-wysiwyg_with_carrierwave_picture_upload

    一 bootstrap3-wysiwyg安装

    这里使用bootstrap-wysihtml5-rails集成到rails中,安装和配置具体见该github.

    在gemfile添加: gem ‘bootstrap-wysihtml5-rails‘,bundle install安装。

    在app/assets/stylesheets/application.css添加

    1
    *= require bootstrap-wysihtml5

    在app/assets/javascripts/application.js里添加

    1
    2
    //= require bootstrap-wysihtml5
    //= require bootstrap-wysihtml5/locales/zh-CN

    在要使用编辑器的地方添加”class=’wysihtml5′”,比如:

    1
    = f.text_area :content,class: "wysihtml5"

    然后在js文件里面初始化编辑器:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    $('.wysihtml5').each(function(i, elem) {
        $(elem).wysihtml5({
          toolbar: {
            "color": true,
            "size": 'sm'
          },
          "locale" : 'zh-CN',
        });
      });

    这样应该就可以了但是现在没办法实现图片上传,图片只能够插入链接的方式,如下

    选区_032

    上传图片功能还是很重要的,幸亏bootstrap3-wysiwyg提供了很好的扩展功能,可以自己实现上传功能.

    二 使用carrierwave实现图片上传功能

    首先要修改编辑器的图片弹窗,js配置如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    $(document).ready(function(){
      var csrf_token = $('meta[name=csrf-token]').attr('content');
      var csrf_param = $('meta[name=csrf-param]').attr('content');
      var customTemplates = {
        image : function(context) {
          var locale = context.locale;
          var options = context.options;
          return "<li>" +
            "<div class='bootstrap-wysihtml5-insert-image-modal modal fade' data-wysihtml5-dialog='insertImage'>" +
            "<div class='modal-dialog'>" +
            "<div class='modal-content'>" +
            "<div class='modal-header'>" +
            " <a class='close' data-dismiss='modal'>×</a>" +
            "<h3>" + locale.image.insert + "</h3>" +
            "</div>" +
            "<div class='modal-body'>" +
            "<div class='upload-picture'>" +
            "<form accept-charset='UTF-8' action='/images/upload' class='form-horizontal' id='wysiwyg_image_upload_form' method='post' enctype='multipart/form-data'>"+
            "<div style='display:none'>"+
            "<input name='utf8' value='✓' type='hidden'></input>"+
            "<input name='"+ csrf_param +"' value='"+ csrf_token +"' type='hidden'></input>" +
            "</div>" +
            "<div class='form-group'>" +
            "<div class='col-xs-9 col-md-10'>"+
            "<input value='' accept='image/jpeg,image/gif,image/png' class='form-control' id='wysiwyg_image_picture' name='image[picture]' type='file' required='required'></input>"+
            "</div>" +
            "<div class='col-xs-3 col-md-2'>"+
            "<input class='btn btn-primary' id='wysiwyg_image_submit' name='commit' type='submit' value='上传'></input>"+
            "</div>" +
            "</div>" +
            "</form>"+
            "</div>"+
            "<div class='form-group'>" +
            "<input value='http://' id='bootstrap-wysihtml5-picture-src' class='bootstrap-wysihtml5-insert-image-url form-control' data-wysihtml5-dialog-field='src'>"+
            "</div>" +
            "<div id='wysihtml5_upload_notice'>"+
            "</div>"+
            "</div>" +
            "<div class='modal-footer'>" +
            "<a href='#' class='btn btn-default' data-dismiss='modal'>" + locale.image.cancel + "</a>" +
            "<a class='btn btn-primary' data-dismiss='modal' data-wysihtml5-dialog-action='save' href='#'>" + locale.image.insert + "</a>"+
            "</div>" +
            "</div>" +
            "</div>" +
            "</div>" +
            "<a class='btn btn-sm btn-default' data-wysihtml5-command='insertImage' title='" + locale.image.insert + "' tabindex='-1'><span class='glyphicon glyphicon-picture'></span></a>" +
            "</li>";
        }
      };
      $('.wysihtml5').each(function(i, elem) {
        $(elem).wysihtml5({
          toolbar: {
            "color": true,
            "size": 'sm'
          },
          "locale" : 'zh-CN',
          customTemplates: customTemplates
        });
      });
     
    })

    这样编辑器图片弹窗就会变成下面这样:

    选区_033

    这只是前端view,controller和model层都得再实现

    MODEL: Image

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    #migration:
     def change
        create_table :images do |t|
          t.string   :picture
          t.string   :title, default: 'www.embbnux.com'
          t.references :user, index: true
          t.timestamps
        end
      end
    #model
    class Image < ActiveRecord::Base
      belongs_to :user
      mount_uploader :picture, PictureUploader
      validates :user_id, presence: true
      validates :title, length: { maximum: 250 }
    end

    这里的图片上传使用carrierwave,具体使用请见该github readme

    Controller:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    #routes
    post "/images/upload" => "images#upload"
     
    #controller
    class ImagesController < ApplicationController
      before_action :logged_in_user
      def upload
        @image = current_user.images.build(images_params)
        image_url = ""
        if @image.save
          image_url = "http://" << ENV["HOME_URL"] << @image.picture.url
          status = "上传成功!点击插入图片按钮插入."
        else
          status = "上传失败!"
        end
        respond_to do |format|
          format.json { render :json =>{:image_url => image_url,:status => status} }
        end
      end
      private
      def images_params
        params.require(:image).permit(:picture)
      end
    end

    这里的controller我使用ajax提交post代码,这样体验比较好,上传成功后把图片的地址传回客户端,自动放在原来的插入图片链接处:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    $('#wysiwyg_image_upload_form').on('submit',function(event){
        event.stopPropagation();
        event.preventDefault();
        $('#wysiwyg_image_submit').val('Uploading');
        var wysiwyg_file = $('#wysiwyg_image_picture')[0].files[0];
        var wysiwyg_formData = new FormData();
        wysiwyg_formData.append('utf8', "✓");
        wysiwyg_formData.append(csrf_param, csrf_token);
        wysiwyg_formData.append('image[picture]', wysiwyg_file,wysiwyg_file.name);
        $.ajax({
            url: '/images/upload',
            type: 'POST',
            data: wysiwyg_formData,
            dataType: 'json',
            processData: false,
            contentType: false,
            success: function(data, textStatus, jqXHR)
            {
              $('#wysiwyg_image_submit').val('上传');
              $('#wysiwyg_image_picture').val('');
              $('#bootstrap-wysihtml5-picture-src').val(data.image_url);
            },
            error: function(jqXHR, textStatus, errorThrown)
            {
            }
        });

    这样上传功能基本就完成了,ajax关键要提供csrf-token参数,其他都没问题

    最终效果可以到我开发的网站看:   huaborn.com

    三 替换br标签为p标签

    这个编辑器如果你键盘按回车键,他是自动加入br标签,感觉比较丑,段落之间还是使用p比较好看

    无意中发现要是原来文本编辑器里存在<p></p>它换行就会自动添加p标签而不是br标签。

    所以最终使用下面代码实现:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    $('.wysihtml5').each(function(i, elem) {
        $(elem).wysihtml5({
          toolbar: {
            "color": true,
            "size": 'sm'
          },
          "locale" : 'zh-CN',
          customTemplates: customTemplates
        });
        var input_text = $(elem).html();
        $(elem).html(input_text+"<p>&nbsp</p>");
      });
  • 相关阅读:
    常见字符编码扫盲(UTF,Unicode, GB2312) 四
    Ogre 实用技巧 四
    CEGUI中文显示问题的解决方法 四
    大幅革新 AMD下一代图形产品前瞻 四
    力争上游 ——我眼中的“计算机产业链” 四
    养成 SQL SERVER 的好习惯 四
    说说 Windows 中的中文字体 四
    Unicode字符集和多字节字符集关系 四
    各种电影 四
    [projectEuler.net]12
  • 原文地址:https://www.cnblogs.com/ly-radiata/p/5849105.html
Copyright © 2011-2022 走看看