3

I am using tinymce to create a rich Textarea, and I am using backbone.js.

The problem is that when i move to that "page" in my router from a previous URL that is on the same site, it just doesn't work.

If i refresh the page with the direct link to that route it works fine. I really don't understand what can go wrong.

Here is the view:

var template = function (name) {
    var source = $('#' + name + '-template').html();
    return Handlebars.compile(source);
}; 
  BT.Common.FormTextArea = Backbone.View.extend({
    template : template('form-input-textarea'),
    tagName: 'div',
    className: "control-group",
    initialize: function(){
    },
    render: function(){
        console.debug("Render FormTextArea");
        var html = this.template(this.model.toJSON());
        this.$el.html(html);    
        tinymce.init({selector:'textarea'});
        return this;
    },
});

The template:

  <script type="text/x-handlebars-template" id="form-input-textarea-template">
      <label class="control-label" for="message">{{lable}}</label>
      <div class="controls">
        <textarea name="msgpost" id="msgpost" cols="50" rows="10">
            {{text}}  
        </textarea>
      </div>
</script>
2
  • Did you check the console section for any errors Commented Jul 31, 2013 at 23:34
  • No errors. i actually tried to keep a record of the Instance and use it again. Didn't work as well. I solved it by using an Iframe. i will write am answer soon Commented Aug 1, 2013 at 0:02

3 Answers 3

2

TinyMCE apparently doesn't like to work on detached nodes. At all.

This setup reproduces your predicament:

var v = new BT.Common.FormTextArea({
    model: new Backbone.Model({text: 'init'})
});

v.render().$el.appendTo('body');

and an accompanying Fiddle http://jsfiddle.net/nikoshr/pCdSy/

A simple workaround would be to provide your view an attached node. For example, assuming #render is in the DOM:

var v = new BT.Common.FormTextArea({
    model: new Backbone.Model({text: 'init'}),
    el: '#render'
});

v.render();

and an updated Fiddle http://jsfiddle.net/nikoshr/pCdSy/2/

Another solution would be to temporarily add your view el to the DOM, apply TinyMCE and then detach it.

var BT.Common.FormTextArea = Backbone.View.extend({
    template : template('form-input-textarea'),
    tagName: 'div',
    className: "control-group",

    initialize: function(){
    },

    render: function(){
        console.debug("Render FormTextArea");

        var html = this.template(this.model.toJSON());
        this.$el.html(html);    

        $('body').append(this.$el);   
        tinymce.init({selector: 'textarea'});
        this.$el.detach();

        return this;
    }
});

http://jsfiddle.net/nikoshr/pCdSy/4/ for a demo

Warning : this really looks like a hack and might produce unexpected results.

Sign up to request clarification or add additional context in comments.

1 Comment

I have actually did not try your solution. It might be good. i am not accepting my answer, will see what the audience say :)
0

I Solved it by creating an Iframe view and bringing small html code for the text area.

BT.Common.IframeTextArea = Backbone.View.extend({
    tagName: "div",
    className: "row",
    template : template('form-input-textarea'),
    render: function(){
        var html = this.template();
        this.$el.html(html);
        return this;
    }
});

and the template is just:

<script type="text/x-handlebars-template" id="form-input-textarea-template">
    <div class="span12">
      <iframe src="resources/textArea.html" style="width:100%;height:600px;border:0;padding:0"></iframe>
    </div>
</script>

and the textArea.html is:

<script src="js-frameworks/tinymce/tinymce.min.js"></script>
<script type="text/javascript">
tinymce.init({
selector: "textarea",
plugins: [
    "advlist autolink lists link image charmap print preview anchor",
    "searchreplace visualblocks code fullscreen",
    "insertdatetime media table contextmenu paste"
],
toolbar: "insertfile undo redo | styleselect | bold italic | alignleft aligncenter alignright
     alignjustify | bullist numlist outdent indent | link image"});
  </script>
  <textarea name="content" style="width:100%"></textarea>

Comments

0

When rendering (Backbone.View.render), the el isn't inserted in the dom yet. Also, it is impossible to catch the moment when the view's el will be inserted in the dom. But a thing that is sure, is that at the end of the current browser's process, the el will be inserted in the DOM. Then tinyMCE will be "initializable". Simply wait 1 millisecond using "setTimeout" :

var FormTextArea = Backbone.View.extend({
    template : _.template('<%=value%>'),
    tagName: 'textarea',
    className: "control-group",
    render: function(){ 
        this.$el.html(this.template(this.model.toJSON()));
        setTimeout(_.bind(this.initMCE, this), 1);
        return this;
    },
    initMCE: function(){
        tinymce.init({selector: 'textarea'});
    }
});

var v = new FormTextArea({
    model: new Backbone.Model({value: '<h2>Heading 2</h2><p>A paragraph here</p>'})
});

$('body').append(v.render().el);

The jsfiddle :

http://jsfiddle.net/pCdSy/10/

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.