LoremFooBar
LoremFooBar

Reputation: 135

Ember.js - CollectionView, add an attribute to the div wrapper of the child view

I'm trying to combine two ebmer.js examples: Integrating with jQuery UI and the todos example from emberjs.com. I want to have a todo list that is sortable.

Everything went smooth until I got to a point where I wanted to serialize the sortable. For that to work, I need to be able to add an attribute to the sortable items. this is the template:

{{#collection Todos.TodosListView}}
    {{#view Todos.TodoView contentBinding="content" checkedBinding="content.isDone"}}
        <label>{{content.title}}</label>
    {{/view}}
{{/collection}}

Todos.TodosListView is a CollectionView, similar to the menu in the jQuery UI example. Todos.TodoView is a Checkbox. This generates the following html:

<div class="ember-view todo-list ui-sortable" id="ember267">
    <div class="ember-view" id="ember284">
        <input type="checkbox" class="ember-view ember-checkbox todo" id="ember297">
            <label>
            <script type="text/x-placeholder" id="metamorph-1-start"></script>
            something to do
            <script type="text/x-placeholder" id="metamorph-1-end"></script>
            </label>
    </div>
</div>

What I need to be able to do is edit the <div> that wraps the <input>. Assuming the todo's id is 1, I want to add serial=todos_1. I tried to add didInsertElement to TodoView and add an attribute to the parent view, but I didn't have access to the content of the view (the todo itself).

Is this possible?

Thanks for your help.


EDIT:
I found a workaround - adding the ID to the DOM as a hidden element. The updated template:

{{#collection Todos.TodosListView}}
    {{#view Todos.TodoView contentBinding="content" checkedBinding="content.isDone" serial="content.serial"}}
        <label>{{content.title}}</label>
        <span style="display: none;" class="todo-id">{{content.id}}</span>
    {{/view}}
{{/collection}}

Todos.TodoView.didInsertElement:

didInsertElement: function() {
    var $div = this.get('parentView').$();
    var id = $div.children('.todo-id').text();
    $div.attr('serial', 'todos_' + id);
}

Generated html:

<div class="ember-view todo-list ui-sortable" id="ember267">
    <div class="ember-view" id="ember284" serial="todos_100">
        <input type="checkbox" class="ember-view ember-checkbox todo" id="ember297">
            <label>
                <script type="text/x-placeholder" id="metamorph-1-start"></script>
                something to do
                <script type="text/x-placeholder" id="metamorph-1-end"></script>
            </label>
            <span class="todo-id" style="display: none;">
                <script type="text/x-placeholder" id="metamorph-2-start"></script>
                100
                <script type="text/x-placeholder" id="metamorph-2-end"></script>
            </span>
    </div>
</div>

I would still like to know if there's a more elegant way of achieving this.

Upvotes: 1

Views: 2444

Answers (1)

pangratz
pangratz

Reputation: 16163

You can create a computed property serial and add this property to the attributeBindings (documented here) of your itemViewClass of Todos.TodosListView, see http://jsfiddle.net/pangratz666/6X4QU/:

Todos.TodosListView = Ember.CollectionView.extend({
    itemViewClass: Ember.View.extend({
        attributeBindings: ['serial'],

        serial: function() {
            return 'todos_' + Ember.getPath(this, 'content.id');
        }.property('content.id').cacheable()
    })
});

Upvotes: 3

Related Questions