之前在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',
    });
  });

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

上传图片功能还是很重要的,幸亏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
    });
  });
 
})

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

这只是前端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>");
  });

rails使用bootstrap3-wysiwyg可视化编辑器并实现自定义图片上传插入功能的更多相关文章

  1. vue项目富文本编辑器vue-quill-editor之自定义图片上传

    使用富文本编辑器的第一步肯定是先安装依赖 npm i vue-quill-editor 1.如果按照官网富文本编辑器中的图片上传是将图片转为base64格式的,如果需要上传图片到自己的服务器,需要修改 ...

  2. 使用百度UMeditor富文本编辑器,修改自定义图片上传,修改源码

    富文本编辑器,不多说了,这个大家应该都用到过,至于用到的什么版本,那就分很多种 CKEditor:很早以前叫FCK,那个时候也用过,现在改名了,比较流行的一个插件,国外很多公司在用 UEDITOR:百 ...

  3. drupal中安装CKEditor文本编辑器,并配置图片上传功能

    一.下载: 1.CKEditor模块 2.IMCE模块 二.安装       1.复制: 下载完上面两个模块之后,解压,将解压后整个文件夹,复制粘贴,放到 sites\all\modules下面,个人 ...

  4. vue-quill-editor富文本编辑器,上传图片自定义为借口上传

    vue-quill-editor富文本编辑器,上传图片自定义为借口上传 博客地址:https://blog.csdn.net/lyj2018gyq/article/details/82585194

  5. 在线HTML文档编辑器使用入门之图片上传与图片管理的实现

    在线HTML文档编辑器使用入门之图片上传与图片管理的实现: 官方网址: http://kindeditor.net/demo.php 开发步骤: 1.开发中只需要导入选中的文件(通常在 webapp ...

  6. ASP利用xhEditor编辑器实现图片上传的功能。

    本人这几天在做一个软件,无意中用到xhEditor在线编辑器,这个编辑器虽然看着比较简单,但功能非常强大,大家可以去官网上查看,废话不说了. 这篇文件主要是实现在ASP环境中利用xhEditor编辑器 ...

  7. summernote(富文本编辑器)将附件与图片上传到自己的服务器(vue项目)

    1.上传图片至自己的服务器(这个官方都有例子,重点介绍附件上传)图片上传官方网址 // onChange callback $('#summernote').summernote({ callback ...

  8. 百度UEditor在线编辑器的配置和图片上传

    前言 最近在项目中使用了百度UEditor富文本编辑器,配置UEditor过程中遇到了几个问题,在此记录一下解决方案和使用方法,避免以后使用UEditor出现类似的错误. 基本配置 一.下载UEdit ...

  9. 百度开源富文本编辑器 UEditor配置:图片上传和文件上传独立使用方法

    使用UEditor编辑器自带的插件实现图片上传和文件上传功能,这里通过配置UEditor单独使用其内置的第三方插件swfupload来实现图片和文件的上传,通过对UEditor配置轻松实现图片批量上传 ...

随机推荐

  1. 节点NODE

    1.整个文档是一个文档节点 * 每个 XML 标签是一个元素节点 * 包含在 XML 元素中的文本是文本节点 * 每一个 XML 属性是一个属性节点 * 注释属于注释节点2. 获取NODE的方式 2. ...

  2. 由cobertura插件生成测试覆盖率报告

    由于cobertura已经集成到maven中,所以可以很方便的直接调用此插件生成报告: 直接运行命令:mvn cobertura:cobertura 就可以直接生成测试报告了. 下面是截图:

  3. leetcode日记 Combination sum IV

    题目: Given an integer array with all positive numbers and no duplicates, find the number of possible ...

  4. IP地址及其子网划分

    说实话,弄到子网划分的时候还是及其头晕的,又是这又是那的,现在我们来讲解一下这些东西, 首先我们来介绍一下IP地址,要弄清子网划分,子网掩码首先还是要弄清IP地址的划分 IP地址是给Internet上 ...

  5. Windows Server 2003 IIS6.0+PHP5(FastCGI)+MySQL5环境搭建教程

    准备篇 一.环境说明: 操作系统:Windows Server 2003 SP2 32位 PHP版本:php 5.3.14(我用的php 5.3.10安装版) MySQL版本:MySQL5.5.25 ...

  6. HTML 5 <script> 标签

    HTML 4.01 与 HTML 5 之间的差异 async 属性是 HTML 5 中的新属性. 在 HTML 5 中,不再支持 HTML 4.01 中的一些属性. 提示和注释 注释:脚本按照如下方式 ...

  7. 【python】3.x,string与bytes的区别(文本,二进制数据)

    Python 3对文本和二进制数据作了更为清晰的区分.文本总是Unicode,由str类型表示, 二进制数据则由bytes类型表示. 不能拼接字符串和字节包,也无法在字节包里搜索字符串(反之亦然),也 ...

  8. 调试 zeromq 发现 accept 死循环

    起因:在群里一个同学说使用 zeromq 的时候出了点儿问题,问题描述如下“router连接十几万客户端后,然后把router杀死,重启,这时候zeromq的某个线程99%的cpu,卡死了,再也接受不 ...

  9. KTV项目 SQL数据库的应用 结合C#应用窗体

    五道口北大青鸟校区 KTV项目 指导老师:袁玉明 歌曲播放原理 SQL数据库关系图 C#解决方案类图 第一步:创建数据库连接方法和打开方法和关闭方法! public class DBHelper { ...

  10. STM32 HAL固件库编程的文件构架

    对于我这种以前只接触过51和AVR单片机编程的小菜来说,现在开始学习STM32的编程,对于函数的功能以及C语言的语法都还好理解,难的是它提供的那一套硬件抽象层(HAL)驱动是怎么和其他的东东搭配在一起 ...