Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ember valueBinding to Redactor WYSIWYG

Tags:

ember.js

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?

like image 275
kroofy Avatar asked Feb 04 '13 13:02

kroofy


2 Answers

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

like image 91
kroofy Avatar answered Oct 20 '22 00:10

kroofy


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.

like image 39
Marcel Ueno Avatar answered Oct 19 '22 23:10

Marcel Ueno