Reputation: 366
I'd like to create a CompositeView that contains a dropdown-list from a collection:
my views:
var ItemView = Backbone.Marionette.ItemView.extend({
template: '#item-tpl'
});
var CompositeView = Backbone.Marionette.CompositeView.extend({
template: '#comp-tpl',
itemView: ItemView,
itemViewContainer: '#mySelect'
});
my templates:
<script id = "item-tpl" type="text/template">
<option value="<%= id %>"><%= name %></option>
</script>
<script id = "comp-tpl" type="text/template">
...
<form>
<div class="control-group">
<select id='mySelect'></select>
</div>
</form>
...
</script>
the rendered HTML displays the default div's, which break the options list
<select id="mySelect">
<div>
<option value="5">name 1</option>
</div>
<div>
<option value="6">name 2</option>
</div>
</select>
how can I achieve this:
<select id="mySelect">
<option value="5">name 1</option>
<option value="6">name 2</option>
</select>
Upvotes: 0
Views: 3111
Reputation: 36
Is pretty easy actually the only thing you need to do is wrap the "el" (element) with jquery so the view should look like this:
var aItemView = Backbone.Marionette.ItemView.extend({
..
..
el: $('#mySelect'),
..
that avoid the default div and you can use only the elements you need. so will get this instead
<select id="mySelect">
<option value="5">name 1</option>
<option value="6">name 2</option>
</select>
Upvotes: 0
Reputation: 25994
I would use this technique: http://jsfiddle.net/c9Lrm/8/
Start by simplifying your template:
<script id = "item-tpl" type="text/template">
<%= name %>
</script>
Then, you need to provide the information about the item view so it renders with the data you want:
var aItemView = Backbone.Marionette.ItemView.extend({
template: '#item-tpl',
tagName: "option",
onRender: function(){
this.$el.attr('value', this.model.get('id'));
}
});
You specify the tagName
attribute so it doesn't get rendered with the default div
tag but uses the option
tag you need. Then, when the option gets rendered, you need to set the value
attribute, which you do with the onRender
function.
Finally, here's your new composite view:
var aCompositeView = Backbone.Marionette.CompositeView.extend({
template: '#comp-tpl',
itemView: aItemView,
itemViewContainer: "select"
});
We specify the itemViewContainer
to tell Marionette where to put our item views. That way, there's no need for us to redefine appendHtml
.
This solution is a lot cleaner, since we're using Marionette functionality instead of doing everything on our own... But of course, the other solutions will work also.
If you want to learn more about generating the proper HTML structure with Marionette, you might be interested in this blog post of mine: http://davidsulc.com/blog/2013/02/03/tutorial-nested-views-using-backbone-marionettes-compositeview/
Upvotes: 6