Integration of WYSIWYG editor to best-in-place tex

2020-06-17 04:04发布

问题:

I'm using best_in_place gem to editing client's info in-place.

My question is, how can I integrate a WYSIWYG Editor for editing this content as HTML? I'm currently using this editor: https://github.com/Nerian/bootstrap-wysihtml5-rails/

I'm not good at javascript and cofeescript, so I'm probably doing something wrong.

My code in view:

<%= best_in_place @client, :info, :type => :textarea, :nil => "Click here to add content!", :html_attrs => { class: "wysihtml5" }, :sanitize => false %>

And clients.js.cofee

$(document).ready ->

# Activating Best In Place
jQuery(".best_in_place").best_in_place()

# Loading editor
$(".wysihtml5").each (i, elem) ->
$(elem).wysihtml5()

Does anyone knows what to do about it?

Thanks

回答1:

Try like this, inner_class: "wysihtml5" if present activate WisiHTML5 editor, buttons 'Save' and 'Cancel' must be present (default event handler disabled for correct work)

In show.html.erb:

  <%= best_in_place @client, :info, type: :textarea, 
                                    nil: "Click here to add content!", 
                                    inner_class: "wysihtml5", 
                                    sanitize: false,
                                    ok_button: 'Save',
                                    cancel_button: 'Cancel',
                                    display_with: lambda { |v| v.html_safe }
  %>

In coffee script file:

jQuery ->
  # WisiHTML5 Edit
  $('.best_in_place')
    # append
    .best_in_place()
    # init
    .on 'best_in_place:activate', () -> 
      if $(this).attr('data-inner-class') == 'wysihtml5'
        html = $(this).attr('data-original-content')
        area = $('textarea', this)
        area.addClass('span7').unbind('blur')
        area.wysihtml5().data('wysihtml5').editor.on 'load', (e)->
          this.setValue(html, true)
    # update
    .on 'best_in_place:success', (e, data) ->
      if $(this).attr('data-inner-class') == 'wysihtml5'
        attr = $(this).attr('data-attribute')
        data = jQuery.parseJSON(data)
        if data[attr]
          $(this).attr('data-original-content', data[attr])
          $(this).html(data[attr])

In show.json.jbuilder:

json.extract! @client, :info, ... <any other attributes>


回答2:

It could be a simple indentation issue of coffeescript. Just indent the lines below $(document).ready -> by a tab.

$(document).ready ->
  # Activating Best In Place
  jQuery(".best_in_place").best_in_place()

  # Loading editor
  $(".wysihtml5").each (i, elem) ->
  $(elem).wysihtml5()

To validate further, copy your code in the coffeescript frame @ http://js2coffee.org/: the resulting javascript should look like this:-

$(document).ready(function() {
  jQuery(".best_in_place").best_in_place();
  $(".wysihtml5").each(function(i, elem) {});
  return $(elem).wysihtml5();
});

That is, the plugins should be called after the dom is loaded.



回答3:

You have to iterate over every element with class "wysihtml5" so it should be this way.

$(function(){
  jQuery(".best_in_place").best_in_place();
  $.each('.wysihtml5', function(i, elem){
    $(elem).wysihtml5();
  });
});

And converted to Coffee with Js2Coffee it should work.

$ ->
 jQuery(".best_in_place").best_in_place()
 $.each ".wysihtml5", (i, elem) ->
   $(elem).wysihtml5()   


回答4:

I'm using CK-Editor, which I believe would similar to your wysiwyg Editor case somehow.

Here is an example and solution for that: Long article about how he is switching to this:

http://blog.amps211.com/this-is-me-professing-my-love-for-jquery-and-how-i-got-ckeditor-working-with-jeditable/

files to the editor update http://blog.amps211.com/wp-content/uploads/2009/10/jquery.generateId.js http://blog.amps211.com/wp-content/uploads/2009/10/jquery.jeditable.ckeditor.js



回答5:

I've been playing with this myself, and it was not obvious to say the least.

This is how I eventually got it working:

You need to call wysihtml5() on the textarea element, bound to best_in_place:activate event. This is my application.js.coffee:

$(".best_in_place").each (index, element) ->
  $element  = $(element)

  $element
  .best_in_place()
  .on 'best_in_place:activate', () ->
    $element.find(".wysihtml5").each ->
      $this = $(this)
      $this.wysihtml5()

I added the wysihtml5 css class using inner_class option on the helper:

<%= best_in_place @client, :info, type: :textarea, nil: "Click here to add content!", inner_class: 'wysihtml5' }, sanitize: false, display_as: :info_html %>

Note that I'm using display_as: :info_html, since I have that field on the model to store processed html, but you can use display_with: lambda { |v| v.html_safe } if that is not your case.

And now it comes the tricky part: the current version (3.0.3) of best_in_place does not play nice with wysihtml5 since the textarea got blurred to be substituted by the contenteditable iframe, what in turn made the editable operation to be cancelled. I needed to roll a few modifications to the gem on my own that I hope that got merged (you can see the full discussion here), but in the meanwhile you can use my fork. If you do that, then you need to provide your view helper this extra option: skip_blur: true.