Here is my jsfiddle link and I am trying to print below DropDown a message - "Select option B" when any option other than B is selected.
When Option B is selected , I have to print Id and option Name
http://jsfiddle.net/fortm/MGX9k/1/
What is happening is that "Select Option B" message is never getting printed. Always Id and Name is being shown.
So, there is some problem with Handlebar conditional -
{{#if App.SearchController.selectedB}}
Where , selectedB is a function that returns true when Option is B, but this seems to be not working..
selectedB: function() {
return this.get('selectedName.id') == 2 ;
}
As a side question , I needed to style Select Dropdown and so I added "class" atrribute. It got custom styled but it still has ember-select as one of styles.. Can we remove ember CSS when adding a new own style ?
The problem I see here isn't much about the conditional itself, but with how you're using your data. A few things:
(You can see more here: http://jsfiddle.net/schawaska/enRhT/)
If you want your template to react on selectedB
, you have to make it into a computed property, also specifying its dependencies, which in your case is the selectedName
property:
selectedB: function() {
return this.get('selectedName.id') == 2;
}.property('selectedName') // This is important
Also, I've noticed that in your templates you are assigning your bindings to the controller class and not the instance. Consider changing your application to include the Router
, which will allow you to set your model data differently.
With the routing mechanism, a controller will be assigned to your route and bound to the view/template automatically, so instead of binding to App.SearchController.property
, you can do it with controller
or controller.property
:
{{view Ember.Select class="my_custom_class"
contentBinding="controller.content"
optionValuePath="content.id"
optionLabelPath="content.firstName"
selectionBinding="controller.selectedName"}}
This would require a few more changes tho.
Setting up the Router
App.Router.map(function() {
this.route('search');
});
// this would require that you either create an IndexRoute
// to redirect from the root to the SearchRoute, or
// change the route path: this.route('search', { path: '/' });
returning data from the route's model function and not from controller
App.SearchRoute = Em.Route.extend({
model: function() {
return [
{firstName: "Any", id: 0},
{firstName: "A", id: 1},
{firstName: "B", id: 2},
{firstName: "C", id: 3},
{firstName: "D", id: 4},
{firstName: "E", id: 5}
];
}
});
Adding an {{outlet}}
to the application template
<script type="text/x-handlebars">
{{outlet}}
</script>
moving your template body to a specific template, using the correct controller
Now, because the route is providing the controller and its data, you should be able to use the controller
key in your Handlebars template, and it will refer to the SearchController (see below).
<script type="text/x-handlebars" data-template-name="search">
{{view Ember.Select class="my_custom_class"
contentBinding="controller.content"
optionValuePath="content.id"
optionLabelPath="content.firstName"
selectionBinding="controller.selectedName"}}
{{#if selectedB}}
<p>Selected: {{controller.selectedName.firstName}}
(ID: {{controller.selectedName.id}})</p>
{{else}}
<p>Select option B</p>
{{/if}}
</script>
Fixing controller
App.SearchController = Ember.ArrayController.extend({
selectedName: null,
selectedB: function() {
return this.get('selectedName.id') == 2 ;
}.property('selectedName')
});
Because of naming conventions, your route expects your app to have a SearchController
(this exact name), and that's how it connects everything together. And if your controller doesn't implement an ArrayController
, it will blow up since your model function now returns a ModelArray
and it wouldn't bind to an ObjectController
(default)