WYSIWYG Editor with Summernote

#27 WYSIWYG Editor with Summernote
5/2/2016

Summary

Integrate Summernote WYSIWYG Editor into your application. Learn how to use AJAX callbacks to filestore your images instead of database Base64.
7
rails wysiwyg view ajax javascript 7:40 min

Summary

Gemfilegem 'summernote-rails'
gem "refile", require: "refile/rails"
gem "refile-mini_magick"

Generate a new model for your images to be stored. Without Refile (or a similar uploader), the images will be converted to BASE64 and stored within the database.

bashrails g model image image_id image_filename image_size:integer image_content_type
application.js//= require summernote
application.css.scss/*
@import "bootstrap-sprockets";
@import "bootstrap";
*/

@import "summernote";
_form.html.erb    
    <%= f.input :summary, as: :summernote %>
    <%= f.input :content, as: :summernote %>


articles.coffee$ ->
  sendFile = (that, file) ->
    data = new FormData
    data.append 'image[image]', file
    $.ajax
      data: data
      type: 'POST'
      url: '/images'
      cache: false
      contentType: false
      processData: false
      success: (data) ->
        img = document.createElement('IMG')
        img.src = data.url
        img.setAttribute('id', data.image_id)
        $(that).summernote 'insertNode', img

  deleteFile = (file_id) ->
    $.ajax
      type: 'DELETE'
      url: "/images/#{file_id}"
      cache: false
      contentType: false
      processData: false

  ready = ->
    $('[data-provider="summernote"]').each ->
      $(this).summernote 
        height: 200
        callbacks: 
          onImageUpload: (files) ->
            img = sendFile(this, files[0])
          onMediaDelete: (target, editor, editable) ->
            image_id = target[0].id
            if !!image_id
              deleteFile image_id
            target.remove()
  $(document).ready(ready)
  $(document).on('page:load', ready)
images_controller.rbclass ImagesController < ApplicationController
  protect_from_forgery except: :create
 
  def create
    @image = Image.new(image_params)
    @image.save
 
    respond_to do |format|
      format.json { render :json => { url: Refile.attachment_url(@image, :image), image_id: @image.image_id } }
    end
  end
 
  def destroy
    @image = Image.find_by(image_id: params[:id])
    @image.destroy
    respond_to do |format|
      format.json { render :json => { status: :ok } }
    end
  end
  
  private
 
  def image_params
    params.require(:image).permit(:image)
  end
end
routes.rbRails.application.routes.draw do
  resources :articles
  resources :images, only: [:create, :destroy]
  root to: 'articles#index'
end
image.rbclass Image < ActiveRecord::Base
  attachment :image
  belongs_to :article
end


3416976?v=3&s=64
zulhfreelancer said over 1 year ago:

Really awesome video. Thanks!

9312729?v=3&s=64
CarlSosaDev said about 1 year ago:

Thanks very much  for the video!

635114?v=3&s=64
kobaltz said about 1 year ago:

Thank you for watching

4756285?v=3&s=64
adrianvalenz said 8 months ago:

Hi there! I just messaged you on Twitter. I actually have a question for Summernote as well. Whenever I save/publish a post that contains an iframe of a youtube video, it redirects me to the show page but it is blank and I have to update it. Have you  tried or noticed that? My customers will want to embed Youtube videos since they are Youtubers and I don't know what to do.

Thank you in advance for your time.

635114?v=3&s=64
kobaltz said 8 months ago:

Are you entering the iframe code in the "code view", using the Video button or are you pasting it into the WYSIWYG editor? 

Also, can you share the snippet that you're using to display the content of the editor? For example, do you have a <%= raw @model.content %> or something similar?

272344?v=3&s=64
nikkos said 6 months ago:

I have Rails 5 and turbolinks 5. The summernote plugin worked but I had a problem. When I was trying to edit the post, the summernote editor disappear. To fix this I changed one line on coffeescript code:

$(document).on('pages:load', ready)

to

$(document).on('turbolinks:load', ready)

15070?v=4&s=64
ramonrails said about 2 months ago:

Should you also include this in the notes?

class Image < ApplicationRecord # :nodoc:
  attachment :image, type: :image
end


635114?v=3&s=64
kobaltz said about 2 months ago:

Thanks for the heads up. I've updated the show notes.

15070?v=4&s=64
ramonrails said about 2 months ago:

# config/initializers/refile.rb
Refile.store = Refile::Backend::FileSystem.new(Rails.root.join('public', 'uploads', 'refile_store'))

Maybe this config can be included too in the article. It allows to persist the uploaded attachments properly.

Without this config, the uploads just stay in system tmp or cache folders and eventually get purged.


Photo
Andrew Selvadurai said 18 days ago:

Thank you for this video, it was awesome! 

I followed the video and also added aws s3 storage for my app. I am able to upload to s3 but when the images from summernote are loaded the image path of the loaded files are from my local drive and is not loading from s3. Do you know where and how I can configure summernote to display the image from s3 instead of from my local file?

635114?v=3&s=64
kobaltz said 15 days ago:

It could be an issue on the onImageUpload callback in the summernote initialization. Basically, this callback will listen for image uploads and in the example, we're calling a separate javascript function (sendFile). The sendFile function will make an AJAX post to your application at a different endpoint and will handle the uploading to S3. The success callback of this AJAX request should return a hash with the URL of the S3 image. The success callback will create the image element with the URL from the returned hash and that will be what gets inserted.

Login to Comment