Nesting existing textfield view in a new view - ember.js

I have been getting a bit stuck in finding a way to reuse an ember textfield so any help would be appreciated.
What I have is (simplified here) a selection of rows like:
<div class="detailItem">Email: {{view Ember.TextField valueBinding="email"}} </div>
<div class="detailItem">Name: {{view Ember.TextField valueBinding="name"}} </div>
and instead of always wrapping in a div I'd like to make use of a new view. e.g.:
<script type="text/x-handlebars" data-template-name="detailItem">
<div class="detailItem">{{Item name}}: {{view Ember.TextField valueBinding="itemValue"}} </div>
</script>
App.DetailItemView = Em.View.extend({
templateName: 'detailItem',
name: "",
......
});
The thing I am not sure is how I get the textfield's valueBinding to link up to my controller (well actually it's content). I can obviously add another property to DetailItemView and instantiate it with that property having the values 'email' and 'name'. How though would I then pass these into the contained Ember.TextField?
Thanks for any assistance

You can do the following:
App.DetailItemView = Ember.View.extend({
templateName: 'detail_item',
classNames: ['detailItem'],
label: null,
value: ''
});
and the template:
<script type="text/template" id="detail_item">
{{view.label}}:
{{view Ember.TextField valueBinding="view.value"}}
</script>
And then use it like this:
{{view App.DetailItemView label="Email" valueBinding="email"}}
{{view App.DetailItemView label="Name" valueBinding="name"}}

Related

In my controller I can't read a value from a form in my template

I have the following templates defined in my HTML:
<script type="text/x-handlebars" data-template-name="application">
<div>
<p>{{outlet}}</p>
</div>
</script>
<script type="text/x-handlebars" data-template-name="registration">
<form autocomplete="on">
First name:<input type='text' name='firstName'><br>
Last name: <input type='text' name='lastName'><br>
E-mail: <input type='email' name='primaryEmailAddress'><br>
Password: <input type='password' name='password' autocomplete='off'><br>
<button type='button' {{action 'createUser'}}>Register</button>
</form>
</script>
My JavaScript is as follows:
App.UsersController = Ember.ObjectController.extend({
createUser : function () {
var name = this.get('firstName');
}
});
When I click the button on my form the 'createUser' function is called. However, I am unable to read any of the values from the form.
My view is as follows:
App.UsersView = Ember.View.extend({
templateName : 'registration'
});
I appreciate it makes the association between my controller and the template, however in this scenario I'm not seeing any other value - does it offer me anything else?
The reason being you did not bind any values from the input fields to any of the property in the controller, you can use Ember's built in Ember.TextField as follows
<script type="text/x-handlebars" data-template-name="registration">
<form autocomplete="on">
<!--
The valueBinding="firstName" binds the value entered by the user in the
textfield to the property firstName in the controller
-->
First name:{{view Ember.TextField valueBinding="firstName"}}<br>
Last name:{{view Ember.TextField valueBinding="lastName"}}<br>
E-mail:{{view Ember.TextField valueBinding="email"}}<br>
Password: {{view Ember.TextField valueBinding="password" type="password"}}<br>
<button type='button' {{action 'createUser'}}>Register</button>
</form>
</script>
Now can get the access
App.UsersController = Ember.ObjectController.extend({
createUser : function () {
alert(this.get('firstName'));
alert(this.get('lastName'));
alert(this.get('email'));
alert(this.get('password'));
}
});
Fiddle: http://jsfiddle.net/QEfCG/4/

Create reusable Ember.Select control with parameters

I would like to create a specialized select control view, which should simply add some functionality. For simplicity I would just like to be able to add a title.
The Control/View:
window.App.ControlsSelectView = Ember.View.extend({
templateName: 'controls/SelectView',
title:"Hello Control",
contentBinding: null
});
The matching html:
<div class="sub_heading">
<h2>{{title}}</h2>
</div>
<div class="inner_12 input_wrapper custom_select">
{{view Ember.Select
multiple="true"
contentBinding= "contentBinding" // how to pass parameters through?
selectionBinding="content.tempSelectedFunctions"
optionLabelPath="content.displayname"
optionValuePath="content.id"
}}
</div>
Usage should be something like this:
{{ view App.ControlsSelectView
contentBinding="content.data.responsibilities"
selectionBinding="content.tempSelectedFunctions"
title="content.responsibilitTitle"
}}
Problem is, that it doesn't work like that. Is the above possible? Or is there a better pattern to create simple reuasble controls?
This post helped me to get on the right track:
get content in view from ContentBinding
Inside the html of the control view I need to reference the view parameters with view.propertyname
Working solution:
HTML:
<div class="sub_heading">
<h2>{{view.title}}</h2>
</div>
{{#if view.content}}
<div class="inner_12 input_wrapper custom_select">
{{view Ember.Select
multiple="view.multiple"
contentBinding= "view.content"
selectionBinding="view.selection"
optionLabelPathBinding="view.optionLabelPath"
optionValuePathBinding="view.optionValuePath"
}}
</div>
{{/if}}
ControlView
window.App.ControlsSelectView = Ember.View.extend({
templateName: 'controls/SelectView'
});
Usage:
{{view App.ControlsSelectView
title = "Function"
multiple="true"
contentBinding="content.data.functions"
selectionBinding="content.tempSelectedFunctions"
optionLabelPath="content.displayname"
optionValuePath="content.id"
}}

handlebars view not refreshing when {{#if}} {{else}} condition changes

(edit: simplified things a bit below)
I have a handlebars template with an {{#if etc}} conditional, and when I change the associated data the view updates the first time, but then does not continue to update on subsequent changes. I am toggling a boolean that is in the condition, and I know the toggle is running and switching the property because I can watch it do so on the console, but the actual view, a I said, only refreshes once. In my html file this looks like this:
<script type="text/x-handlebars" data-template-name="application">
<body>
<div class="row">
{{#if App.Nav.show}}
{{outlet nav}}
{{/if}}
<div class="span10">
<h1>Hello</h1>
{{outlet}}
</div>
</div>
</body>
</script>
and a bit further on, to toggle:
<script type="text/x-handlebars" data-template-name="people">
<a {{action toggleMenu}}> toggle </a>
</script>
and in the javascript:
App.NavController = Ember.Controller.extend();
App.NavView = Ember.View.extend({
templateName: 'nav'
});
App.Nav = Ember.Object.create({
show: true
});
and finally the relevant bits of the router:
App.Router = Ember.Router.extend({
enableLogging: true,
root: Ember.Route.extend({
index: Ember.Route.extend({
route: '/',
showPerson: Ember.Route.transitionTo('aName'),
toggleMenu: function(){
console.log('Changing the toggle!');
App.Nav.toggleShow();
},
connectOutlets: function(router){
router.get('applicationController').connectOutlet('nav', 'nav');
router.get('applicationController').connectOutlet('allPeople', unrelated_function())
}
})
})
});
I would say to put your if into your view. Something like this:
<script type="text/x-handlebars" data-template-name="people">
<a {{action toggleMenu}}> toggle </a>
{{#if App.Nav.show}}
<div>navigation</div>
{{/if}}
<div class="span10">
<h1>Hello {{name}}</h1>
</div>
</script>
Then your application view should look something like this:
<script type="text/x-handlebars" data-template-name="application">
<body>
<div class="row">{{outlet}}</div>
</body>
</script>
Let me know if you tried it and it worked.
I did not use connectOutlet to display the view, let me know if there is some purpose behind using connectOutlet method, Meanwhile here is my implementation of toggling the view visibility

data-template-name issue in emberjs

There is a strange issue am facing with ember.js, i.e when I add "data-template-name" attribute to the script tag, nothing is working. If data-template-name name is removed, things are working fine.
This is NOT WORKING
<script data-template-name="my-template" type="text/x-handlebars">
Input:
{{#view App.MyView}}
{{view Ember.TextField
valueBinding="view.theValue"
placeholder="input ..." }}
{{/view}}
</script>
Now if **data-template-name="my-template"** is removed it works fine.
I mean, In UI TextField is visible.
<script type="text/x-handlebars">
Input:
{{#view App.MyView}}
{{view Ember.TextField
valueBinding="view.theValue"
placeholder="input ..." }}
{{/view}}
</script>
App.MyView = Ember.View.extend({
templateName: 'my-template',
theValue: null,
init: function(){
this._super();
this.set('theValue','asdf');
},
keyDown: function(e){
if(e.keyCode === 13){
alert(this.get('theValue'));
}
}
});
Ok, don't worry about the jsfiddle, it's a good start :). There is a link on the ember.js site, where you can find a starting point, including Ember.js related sources: http://emberjs.com/community/
That beeing said, when creating an Ember.js application like this, there is an implicit default anonymous template, in wich you can then define yours.
<!-- default template, introducing the view App.MyView -->
<script type="text/x-handlebars">
{{view App.MyView}}
</script>
<!-- template of App.View -->
<script data-template-name="my-template" type="text/x-handlebars">
Input:
{{view Ember.TextField
valueBinding="view.theValue"
placeholder="input ..."}}
</script>​
javacript:
App.MyView = Ember.View.extend({
templateName: 'my-template',
theValue: null,
init: function(){
this._super();
this.set('theValue','asdf');
}
});​
Here is a working example of your sample:
http://jsfiddle.net/6p6XJ/171/

Ember.js Binding without a view

Sorry If something like this has already been asked, but I can't find exactly what I am looking for. I'd like to preface the question by saying that I feel I have a decent understanding of content bindings. I plan on using a third party jquery carousel plugin that requires a list of img tags in a div in order to work properly. On to the actual question, let's say I have a collection of urls to images in an App controller. Assume that content will contain a list of valid urls to actual images.
App = Ember.Application.create({});
App.Controller = Em.Object.create({
content: [{url: 'http://www.google.com'}, {url: 'http://www.yahoo.com'}]
});
App.ImgView = Em.View.extend({
tagName: 'img'
});
How do I bind the src of each image to the current url without nesting another {{view}} in the #each? I've tried many combinations, but haven't been able to put my finger on the correct bindings.
<div id="foo">
{{#each App.Controller.content}}
{{view App.ImgView bindAttr src="this.url"}}
{{/each}}
</div>
The handlebar script above will error out, but I feel like it's the best why I can communicate what I am trying to do.
Thanks in advance for any help.
EDIT: After some more research I came across this issue here. Apparently srcBinding to a string was a bug in ember-0.9.4, and has been fixed in ember-0.9.5. I ended up going back to something like...
App.ImgView = Em.View.extend({
tagName: 'div'
});
<div id="foo">
{{#each App.Controller.content}}
{{#view App.ImgView contentBinding="this"}}
<img {{bindAttr src="content.url"}} />
{{/view}}
{{/each}}
</div>
so I could have a click handler on my view. I also modified the plugin to also target images inside of divs inside of #foo.
Thanks for all answers.
It seems like you want:
<div id="foo">
{{#each App.Controller.content}}
<img {{bindAttr src="url"}}>
{{/each}}
</div>
Does that work for you?
You should use srcBinding on your {{view ... }}. See example: http://jsfiddle.net/M2S3Z/
If you just want to render an image and don't need a specific Ember.View which renders the img tag, I would use ebryn's answer.
Template:
<script type="text/x-handlebars" >
<div id="foo">
{{#each App.Controller}}
{{view App.ImgView srcBinding="url"}}
{{/each}}
</div>
</script>​
JS:
App = Ember.Application.create({});
App.Controller = Em.ArrayProxy.create({
content: [{
url: 'http://www.google.com'},
{
url: 'http://www.yahoo.com'}]
});
App.ImgView = Em.View.extend({
tagName: 'img',
didInsertElement: function() {
console.log(this.get('src'));
}
});​
I would rather use something leveraging power of Ember views like this:
App.ImageView = Ember.View.extend({
tagName: 'img',
attributeBindings: ['src'],
src: url_attribute_or_variable
});