kroofy
kroofy

Reputation: 984

Ember valueBinding to Redactor WYSIWYG

I'm using the Redactor WYSIWYG editor and it allows you to use minimal markup before initializing its code like this:

<textarea id="redactor" name="content">
…
</textarea>

However during initialization Redactor will wrap this textarea with the following content:

<div class="redactor_box">
  <div class="redactor_ redactor_editor" contenteditable="true" dir="ltr">
    …
  </div>
  <textarea id="redactor" name="content" style="display: none;">
    …
  </textarea>
</div>

I currently have done this in Ember

Template:

{{ view App.RedactorView valueBinding='contentAttributes.headerContent' class='header-redactor' name='headerContent' }}

View extending Ember.TextArea:

App.RedactorView = Ember.TextArea.extend({
  didInsertElement: function() {
    $("#"+this.elementId).redactor();
  }
});

This still holds a binding to the textarea (now hidden), but I now need to bind the redactor_editor class instead. How can I do this?

Upvotes: 6

Views: 990

Answers (3)

Marcel Ueno
Marcel Ueno

Reputation: 61

I'm using Ember + Foundation, and kroofy's solution worked like a charm for me.

The height of the contentEditable were loading without paddings (were missing a paragraph), so ive changed to redactor's insertHtml method to update the value.

from:

return $el.innerHTML = value;

to:

return this.$().redactor('insertHtml', value);

thanks kroofy.

Upvotes: 3

kroofy
kroofy

Reputation: 984

After a bit of digging in the Redactor code I found out that if your element destined to be an editor is not a textarea element, Redactor will do the reverse thing and add the textarea if your a using a div instead for example.

Updated my view and tweaked it based on code from Ember.TextArea and Ember.TextSupport so it would get the correct value, this will probably work fine if you're using a contenteditable enabled element as well.

App.RedactorView = Ember.View.extend({
  tagName: 'div',
  init: function() {
    this._super();

    this.on("focusOut", this, this._elementValueDidChange);
    this.on("change", this, this._elementValueDidChange);
    this.on("paste", this, this._elementValueDidChange);
    this.on("cut", this, this._elementValueDidChange);
    this.on("input", this, this._elementValueDidChange);
  },
  _updateElementValue: Ember.observer(function() {
    var $el, value;
    value = Ember.get(this, "value");
    $el = this.$().context;
    if ($el && value !== $el.innerHTML) {
      return $el.innerHTML = value;
    }
  }, "value"),
  _elementValueDidChange: function() {
    var $el;
    $el = this.$().context;
    return Ember.set(this, "value", $el.innerHTML);
  },
  didInsertElement: function() {
    this.$().redactor();
    this._updateElementValue();
  }
});

Here's a JSBin demonstrating it: http://emberjs.jsbin.com/cefebepa/1/edit

Upvotes: 7

Georgi Atsev
Georgi Atsev

Reputation: 3045

First, when you want to access the Ember View's DOM element, you should use this:

this.$()

instead of

$("#"+this.elementId)

About the Redactor issue... I am not sure how wise it is to tie up the Ember code with the WYSIWYG editor's functionality, but if you are determined about it, you can do the following:

App.RedactorView = Ember.TextArea.extend({
  didInsertElement: function() {
    var box = this.$().closest('.' + this.elementId + '_box');
    box.find('.' + this.elementId + '_redactor_editor').redactor();
  }
});

Upvotes: 0

Related Questions