3
votes

I'm trying to link a label to an input field using the {{bindAttr}} and the input field's [viewName].elementId. It works on a single entry view, but not when there are several records being displayed: it just links the label to the last input field in the collection. (This used to work in a previous iteration using an older ember library but now it doesnt.) I've created a fiddle but the gist of it is:

{{#each controller}}
    <fieldset>              
        <label {{bindAttr for="view.tbFullName.elementId"}}>Full Name</label>
        {{view App.DetailTextField viewName="tbFullName" placeholder="Full Name" valueBinding="fullName" readonly="readonly"}}                              
    </fieldset>
{{/each}}

I thought maybe I could create a collectionView and create a calculated property for viewName which would generate a unique ID for each item in the collection, sort of mentioned in answer to another problem here. But that is getting WAY too complicated - just so that I can have the input field highlight itself if the user clicks on the corresponding label.

Any help appreciated.

3

3 Answers

3
votes

Create a wrapper Ember.View around the label and input field. Let's call it App.FieldView:

App.FieldView = Ember.View.extend({
  tagName: 'fieldset'
});

Then in your template:

{{#each controller}}
  {{#view App.FieldView}}              
    <label {{bindAttr for="view.tbFullName.elementId"}}>Full Name</label>
    {{view App.DetailTextField viewName="tbFullName" placeholder="Full Name" valueBinding="fullName" readonly="readonly"}}                              
  {{/view}}
{{/each}}

Fiddle: http://jsfiddle.net/NQKvy/26/

3
votes

Panagiotis Panagi, has answered the question correctly. I'll just add why this is happening, ie:- linking to the incorrect view.

The view property inside a template refers to the Ember View wrapping the html markup. This property however has different value depending on the context it is in.

This value is dependent on the view block it placed in. By default the template itself corresponds to a view in this case, ListOfPeopleTemplateView.

So when you are binding to view.tbFullName.elementId, you are actually binding to an {instance of ListOfPeopleTemplateView}.tbFullName.elementId. And when the loop finishes the only tbFullName visible is the last one.

Panagiotis Panagi's solution is to wrap the label inside another view, so the value of view changes to within that block, and hence points to the correct tbFullName

Finally an even easier way to achieve the same result is to wrap the textfield inside the label. Then you do not need the label for binding at all.

<label>Full Name
  {{view App.DetailTextField viewName="tbFullName" placeholder="Full Name" valueBinding="fullName" readonly="readonly"}}    
</label>

See this jsfiddle

1
votes

Forms are somewhat tricky I must admit if you want to do things right. But there are is an ember add-on that comes to the rescue, for example easyForm.

Have a look it might helps you solving exact the problems you are facing, like the ones on having unique labels for your form fields etc.

Hope it helps.