UPDATE (RELEVANT DETAIL): This composite view is within a collection of composite views.
How can I construct the following HTML using a Backbone.Marionette composite view?
<optgroup label="Group 1">
<option>Item 1</option>
<option>Item 2</option>
<option>Item 3</option>
</optgroup>
<optgroup label="Group 2">
<option>Item 4</option>
<option>Item 5</option>
<option>Item 6</option>
</optgroup>
Since I want to avoid the <div>
wrapper, I will have to specify <optgroup>
as the tagName.
view = Backbone.Marionette.CompositeView.extend({
collection: some_collection,
itemView: some_itemview,
template: '#some_template', <!-- What goes inside the template? -->
itemViewContainer: 'optgroup',
tagName:'optgroup', <!--specify to avoid the default div-->
<!-- What should I specify in order to pass label="Group1" to the optgroup tag-->
});
Don't use a CompositeView for this. You don't need a wrapper template since the wrapper in this case is only the <optgroup>
tag.
Use a CollectionView instead, which doesn't render a wrapper template.
For the group #, use the onRender method
view = Backbone.Marionette.CollectionView.extend({
collection: some_collection,
itemView: some_itemview,
tagName:'optgroup',
onRender: function(){
this.$el.attr("label", "Group 1");
}
});
You could set the view element attributes in for example the initialize or onRender function, eg:
view = Backbone.Marionette.CompositeView.extend({
...
initialize: function() {
this.$el.attr('label', 'foobar');
}
});
or replace initialize with:
onRender: function() {
this.$el.attr('label', 'foobar');
}
OR
If you have an existing element such as:
<optgroup id="myGroup" label="Group 1">
</optgroup>
You can set the element of the view as such:
view = Backbone.Marionette.CompositeView.extend({
el: $('#myGroup'),
...
});
A combination of Derick and Lasse's answers lead me to the solution. The onRender
was what I was missing. Below is a summary for future readers.
The structure of the nested collection views:
Collection of Collections --> Collection --> Item
--> Collection --> Item
--> ... etc.
CollectionOfCollections =
Backbone.Marionette.CollectionView.extend({
collection: myCollectionOfCollections,
itemView: Collection <!--this refers to the next Collection view below-->
});
Collection =
Backbone.Marionette.CollectionView.extend({
collection: myCollection,
itemView: ItemView, <!-- again... the next view below -->
tagName: 'optgroup',
Nested collections with Backbone.Marionette
<!-- IF YOU ARE PASSING A SIMPLE ARRAY,
IT MUST BE CONVERTED TO A REAL COLLECTION FIRST -->
initialize: function(){
var xyz = this.model.get('abc');
this.collection = new Backbone.Collection.extend({});
});
onRender: function(){
<!-- Here's where you insert the attribute into the tag -->
this.$el.attr('label', this.model.get('name'));
}
});
});
ItemView =
ModalDropdownEntryView = TourView.extend({
model: myModel,
template: '#myTemplate',
tagName: 'option',
});