Ember and TinyMCE - ember.js

I want to use the TinyMCE component in an Ember app. My basic question is: how and where can you init the tinymce ?
Template contains the textarea element:
<textarea class='test' name="content" style="width:100%">
I need to init TinyMce as follows:
tinymce.init({
selector: "textarea"
});
Where do I need to do the init and how ? In think in the controller init, but this does not work as expected ...
App.IndexController = Ember.Controller.extend({
init: function() {
tinymce.init({
selector: "textarea"
});
}
});
See JSFiddle: http://jsfiddle.net/cyclomarc/wtktK/6/
Hope somebody can help ...

Before tinymce.init you must make sure that your textarea tag is in DOM. On the time your controller gets initialized your view (in this case IndexView) is not yet rendered. A valid way to wait for a view be be rendered is to use didInsertElement hook in that view. In your case:
App.IndexView = Ember.View.extend({
didInsertElement: function(){
tinymce.init({
selector: "textarea"
});
}
});

Related

Ember 2.0 - views for pages

I am used to put some jquery code in View files, that I create for pages.
For instance:
I have the route this.route('buildings');
Next create the view file app/views/buildings.js
import Ember from "ember";
export default Ember.View.extend(Ember.TargetActionSupport, {
didInsertElement: function () {
//jquery here
}
});
But now with Ember 2.0 we have no such ability, what should I do?
In Ember 2.0.0 you can still do the following:
App.ApplicationView = Ember.Component.extend({
classNames: ['customClassName'],
didInsertElement: function() {
alert('did insert element')
}
});
App.BuildingsView = Ember.Component.extend({
classNames: ['customClassName2'],
didInsertElement: function() {
alert('did insert element2');
}
});
See this jsbin for a working example.
P.S. Comment by Robert Jackson: "Using a component as ApplicationView will allow customization of classNames and whatnot, but is definitely going to have a number of negative results as well (for example controller is not correct)." https://github.com/emberjs/ember.js/issues/11486#issuecomment-131366332
Put it in a component. In components/my-component.js
import Ember from 'ember';
export default Ember.Component.extend({
didInsertElement: function(){
// jquery here.
}
});
In your template:
{{my-component}}
Or:
{{#my-component}}
Stuff
{{/my-component}}

Trigger an action on the change event with Ember.js checkbox input helper?

How can I fire a named action upon changing a checkbox in Ember.js? Any help will be greatly appreciated.
Here is what I have. Checking or unchecking the checkbox has no effect.
Template:
{{input type="checkbox" on="change" action="applyFilter"}}
Controller:
actions: {
applyFilter: function() {
console.log("applyFilter");
}
}
I'd like to post an update to this. In Ember 1.13.3+, you can use the following:
<input type="checkbox"
checked={{isChecked}}
onclick={{action "foo" value="target.checked"}} />
link to source
using an observer seems like the easiest way to watch a checkbox changing
Template
{{input type='checkbox' checked=foo}}
Code
foo:undefined,
watchFoo: function(){
console.log('foo changed');
}.observes('foo')
Example
http://emberjs.jsbin.com/kiyevomo/1/edit
Or you could create your own implementation of the checkbox that sends an action
Custom Checkbox
App.CoolCheck = Ember.Checkbox.extend({
hookup: function(){
var action = this.get('action');
if(action){
this.on('change', this, this.sendHookup);
}
}.on('init'),
sendHookup: function(ev){
var action = this.get('action'),
controller = this.get('controller');
controller.send(action, this.$().prop('checked'));
},
cleanup: function(){
this.off('change', this, this.sendHookup);
}.on('willDestroyElement')
});
Custom View
{{view App.CoolCheck action='cow' checked=foo}}
Example
http://emberjs.jsbin.com/kiyevomo/6/edit
Post Ember version >= 1.13 see Kori John Roys' answer.
This is for Ember versions before 1.13
This is a bug in ember's {{input type=checkbox}} helper.
see https://github.com/emberjs/ember.js/issues/5433
I like the idea of having a stand-in. #Kingpin2k's solution works, but accessing views globally is deprecated and using observers isn't great.
In the linked github ember issue, rwjblue suggests a component version:
App.BetterCheckboxComponent = Ember.Component.extend({
attributeBindings: ['type', 'value', 'checked', 'disabled'],
tagName: 'input',
type: 'checkbox',
checked: false,
disabled: false,
_updateElementValue: function() {
this.set('checked', this.$().prop('checked'));
}.on('didInsertElement'),
change: function(event){
this._updateElementValue();
this.sendAction('action', this.get('value'), this.get('checked'));
},
});
Example usage in a template ('checked' and 'disabled' are optional):
{{better-checkbox name=model.name checked=model.checked value=model.value disabled=model.disabled}}
For those using Ember > 2.x:
{{input
change=(action 'doSomething')
type='checkbox'}}
and the action:
actions: {
doSomething() {
console.warn('Done it!');
}
}
In Ember v1.13 it can be done simply by creating a component named j-check in my occasion(no layout content required):
import Ember from 'ember';
export default Ember.Checkbox.extend({
change(){
this._super(...arguments);
this.get('controller').send(this.get('action'));
}
});
And then you just call it from your template like this:
{{j-check checked=isOnline action="refreshModel" }}

How to get the parent controller for a custom TextField

I have a simple controller
App.UploadController = Ember.Controller.extend({
toUpload: Ember.A([])
});
I have a template backing this w/ a custom text field
<div>
{{view App.UploadFileView name="file" contentBinding="content"}}
</div>
My custom text field in JS is below. The problem I'm having is that in the change event, I need to push an object into the parent controllers "toUpload" array but when I do a get on the parentView.controller it's undefined. How can I get the parent in this scenario?
App.UploadFileView = Ember.TextField.extend({
type: 'file'
change: function() {
var foo = Ember.Object.create();
this.get('parentView.controller').get('toUpload').pushObject(foo);
}
});
The TextField is a component, so the parent controller doesn't exist, you'd need to use sendAction to get things out of it.
Here's my implementation of the upload button that's just a view.
App.UploadFileView = Ember.View.extend({
tagName: 'input',
attributeBindings: ['type'],
type: 'file',
change: function() {
console.log(this.get('controller'));
}
});
http://emberjs.jsbin.com/oQaReMi/1/edit
If you are using an Ember Component (like TextField for example) you would do this like so
App.UploadFileView = Ember.TextField.extend({
change: function() {
console.log(this.get('targetObject'));
}
});
Note- this is in the current version of ember 1.3.x

Binding model to template with emberjs

I am going to bind model to template with emberjs
<script type="text/x-handlebars" id="dashboard">
<div>
<span>this is user list</span>
<div>
{{render userinfo userinfo}}
</div>
</div>
</script>
<script type="text/x-handlebars" id="_userinfo">
{{#each model}}
<span>{{user}}
{{/each}}
</script>
App.Userinfo= DS.Model.extend({
user: DS.attr("string")
});
App.Userinfo.FIXTURES = [
{user:"user1"},
{user:"user2"},
{user:"user3"}
];
App.UserinfoView= Ember.View.extend({
});
App.UserinfoController = Ember.ObjectController.extend({
});
App.Router.map(function() {
this.resource('dashboard', {path: '/dashboard'}, function() {
});
});
App.DashboardRoute = Ember.Route.extend({
renderTemplate: function() {
this.render('dashboard', { // the template to render
controller: 'dashboard' // the controller to use for the template
});
}
});
App.DashboardController = Ember.ObjectController.extend({
});
When i go to /#/dashboard, Dashboard template is loaded.
In here, I have rendered userinfo.
I'd like to bind Userinfo Model to usersinfo template so that I display all users.
Help me, please.
The short: here a working jsbin.
The long: You hade slightly to much unnecessary going on in your code, basically this does the job:
First of all you had no redirect to your dashboard route, since it's your only route (at least as far I can see from your code) we redirect directly to it after entering the index route
App.IndexRoute = Ember.Route.extend({
redirect: function() {
this.transitionTo('dashboard');
}
});
I've removed the DashboardController since there is nothing to be done.
Then your DashboardRoute was missing the model hook to provide actually data for your dashboard template
App.DashboardRoute = Ember.Route.extend({
model: function(){
return App.Userinfo.find();
}
});
In the router map you don't need to define a path if the URL is the same name as your template name in your case it is the same dashboard
App.Router.map(function() {
this.resource('dashboard');
});
The userinfo model was correct
App.Userinfo= DS.Model.extend({
user: DS.attr("string")
});
But your fixtures where missing the id
App.Userinfo.FIXTURES = [
{id:1, user:"user1"},
{id:2, user:"user2"},
{id:3, user:"user3"}
];
Moreover you where using the render helper with a partial template _userinfo the correct way to render a partial is this
{{partial userinfo}}
As you can see we don't pass any additional parameters to it because the data will be made available trough your model hook. The partial helper uses the context and the data provided in the template it is rendered into, in your case the dashboard template, therefore the model hook is necessary.
Hope it helps.

Ember template displayed twice

There is a simple ember.js app with one view displayed in a particular place on the webpage. Have a look at this jsfiddle: http://jsfiddle.net/jkkK3/9/
App = Ember.Application.create({
ready: function(){
this._super();
this.ApplicationView.create().appendTo(".content");
},
ApplicationController: Ember.Controller.extend({
}),
ApplicationView: Ember.View.extend({
templateName: 'application'
}),
Router: Ember.Router.extend({
root: Ember.Route.extend({
})
})
});
My question is: Why is the "some content here" element displayed twice? It works when I remove the router, but that's exactly what I cannot do, since I try to add Router to my Ember app. Could you please help me to display application view only once, inside the red box?
When using router, applicationController/view are used by default. In your ready method you append it explicitly. So 'application' template is appended twice. Remove appending it in ready method and it will be appended only once.
By default it's appended to body but if you want to override use rootElement property of Ember.Application
Ember.Application.create( {
rootElement : '.content',
....
})