How to display specific item from array in Ember.js's template? - ember.js

Is there any way to do something like that in Ember.js template?
{{someObject.someArray[0].arrayPropery}}
When object structure looks like this:
someObject: {
someArray: [
{
arrayProperty: 'Show me in template!'
}
]
}

You could use: {{ someObject.someArray.firstObject.property }} but it's better to provide a computed property in your controller which returns the desired property.

Related

Ember HTML attribute with spaces

I have this Bootstrap accordion item
{{#bs-accordion-item value=index title=client.name}}
But I would like the title attribute to contain a string with a mix of variable data and static text, such as title="{{client.value}} at {{client.name}}" but since I can't use the quotes I'm stuck...
You can use the concat helper.
{{#each model as |rental|}}
{{#bs-accordion selected=selected}}
{{#bs-accordion-item value=rental.id title=(concat rental.title " Owned by " rental.owner)}}
{{!--The accordion content goes here--}}
{{/bs-accordion-item}}
{{/bs-accordion}}
{{/each}}
This is what Computed Properties in Ember are for...
You can construct the desired string using a computed property in your controller, for example, and assign the computed property to the title attribute.
In the controller, you could do something like this:
client: {
name: 'Indianapolis Motor Speedway',
value: 'Alexander Rossi',
},
constructedString: Ember.computed('client.value', 'client.name', function () {
const clientValue = this.get('client.value');
const clientName = this.get('client.name');
return `${clientValue} at ${clientName}`;
}),
In the bs-accordion-item helper, the constructedString value is assigned to the title attribute:
{{ bs-accordion-item value=index title=constructedString }}
And the bs-accordion-item template could then reference title, like so:
<h3>{{ title }}</h3>
I've created an Ember Twiddle example to demonstrate.

Ember, disable input based on condition

I have an Ember form, where I want to disable input's based on the user.
I get an array of modifiable fields from my back end.
How do I get this to work with Ember?
Ideal scenario would be to do this,
{{input type="text" disabled=isModifiable("middleName") value=middleName}}
I know that isn't possible.
Fairly new to Ember, advice would be appreciated. Thanks.
Define a property in you Controller or Component like this:
fields:[],
loadFields : function(){
var that = this;
$.get(FIELDS_API).done(function(serverResponse){
//process server response in an array with objects with this form:
// [ field:"middleName", isDisabled:true}]
that.set("fields",fieldsArray);
})
}
isModifiable : function(fieldName){
var field = this.get("fields").findBy("field",fieldName);
return (field) ? field.isDisabled: false;
},
isMiddleNameInputDisabled : function(){
return this.isModifiable("middleName");
}.property("fields.#each")
Use that property in your template like this:
{{input type="text" disabled=isMiddleNameInputDisabled value=middleName}}

Binding several attributes to the same element

I am trying to do something like this:
<a href="#/{{unbound goto}}" {{bind-attr class=":menu-entry-text :nowrap active:selected-menu-entry-text"}} {{bind-attr id="active:active-nav:inactive-nav"}} {{bind-attr data-goto="goto"}}>
But only the first attribute (class) gets set: id and data-goto are not defined. Is it possible to set several attributes with bind-attr in the same element? How?
Yes you can bind several attributes at once by either using multiple bind-attr helpers like in your example, or just putting all the attributes in a single bind-attr helper. You have an issue in your example though, which is why things aren't working as expected.
The "value if true" form that you're using for the class attribute cannot be applied to other types of attributes. All other attributes must be bound to a dynamic property on the controller. For example, if you had a controller that looked like this:
App.MyController = Ember.ObjectController.extend({
myId: function() {
if (this.get("active") === true) {
"active-nav"
} else {
"inactive-nav"
}
}.property("active")
});
Then you would bind that like so:
<a href="#/{{unbound goto}}" {{bind-attr id="myID"}}>
Just a side note on that example, it's probably a code smell if you have a dynamic ID for an HTML element. IDs are supposed to uniquely identify a single element and I wouldn't expect them to change. It seems like a class would be a better fit for this use case.

Interpolating variables when passing arguments to a view

I'm trying to render a bunch of dynamic <select> boxes, supplied by a model. The user is supposed to fill these out, after which the data is saved. Currently I'm looping over the availableParameters object and rendering an Ember.Select view for each of the pairs in the object. This works alright. However, I'm having trouble setting up the valueBinding in such a way that I can retrieve the values in the controller, because I can't seem to interpolate the label variable in the passed argument to the view.
{{#each availableParameters}}
{{label}}
{{view Ember.Select
contentBinding="values"
valueBinding="controller.param.[label]"
}}
{{/each}}
The availableParameters object looks like this:
[
{
label: "label1",
values: [
"value1",
"value2",
"value3"
]
},
...
]
Is there a way to dynamically set the value of the valueBinding to controller.param.[label1] (using the array of objects above) or is there a better way of achieving what I'm looking for?
No, you need to do:
selectedValue: function() {
this.get('values')[this.get('label')]
}.property('values.[]', 'label')
This property can be on the itemController for the {{#each}} helper if you need it to be (an itemController is a good way to approach this problem)

EmberJS - change how an object property is displayed (not tied to route's controller)

Within my Ember app, I have an object model, called Item, with a property 'price', which holds a float value, such as 20.5. When I use the property in a template {{price}}, I would like for it to be formatted to look like so: $20.50.
This object is not the model that is tied to the controller at the route, but rather an element in an Ember Array, called items, which is a property of the model at the route. So I have something like this in my template:
{{#each item in items}}
{{item.price}}
{{/each}}
The problem seems pretty simple, but I can't really find a solution. The idea is that I do not want to change the name of the property to get it to look the way I want, since I could make a computed property that formats the price property, but then I would have to use a new name in the templates.
What you could do is write your own custom handlebars helper.
For your use case it would look something like this:
Ember.Handlebars.registerBoundHelper('formatNumber', function(value) {
return "$" + value.toFixed(2);
});
And then use it in your templates this way:
{{#each item in items}}
{{formatNumber item.price}}
{{/each}}
Please see here for a working jsbin.
Hope it helps.