Reputation: 11289
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>
Upvotes: 3
Views: 994
Reputation: 1080
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 :
Upvotes: 0
Reputation: 11289
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>
Upvotes: 0
Reputation: 33364
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.
Upvotes: 2