Since yours is a common enough problem, the extra div functionality is often debated. See, for example, this very interesting issue.
Unfortunately, Backbone nor Marionette Views are aware of their parent view, even if that parent view is a LayoutView. In fact, Marionette inherited the wrapper behavior from Backbone, and in the majority of cases its the most common-sense structure for a view to have.
Change the CollectionView el
, Live dangerously
You can take the more treacherous route of assigning your Region's element to the CollectionView's el
, which I described in this Answer. What I suggest there, is to override the Region's .attachHtml()
method to insert the contents (and not the el
) of the sub-view directly into the el
of the Region, and, most importanlty, setting the sub-view's el
to the Region's el
using view.setElement()
. But read the warnings there carefully. The events between the two views will be shared! You can't avoid that.
Embrace the wrapper, embrace Backbone
Personally, I advocate to work with, and not against, Backbone/Marionette on this one. I understand that you may have very good reason to want the <select/>
element inside your LayoutView. However, if you can live without that element in there, I can offer you a very simple and quick fix: You can use whatever (proper) HTML element you want for a view's wrapper. So your .show()
can look like this:
onRender: function() {
this.getRegion("drop").show(new (Marionette.CollectionView.extend({
tagName: "select",
attr: {
name:"type"
},
id: "drop",
className: "select",
childView: FieldView
}))(collection: fieldCollection)));
}
All I did up there was change the vanilla <div/>
el
of the view, to
<select name="type" id="drop" class="select"></select>
Don't forget, you'll want to assign a new element to your Region. Let's the take the original <div/>
enclosing the <select/>
, for instance,
<div class="col-xs-12" id="field-region">
</div>
Access the <select/>
element in your LayoutView
The <select/>
statement is not the el
of your CollectionView. This may not bother you, but chances are, at some point you'll do something like $("#drop").val()
in your LayoutView. The good news is that you can natively access <select/>
since its the el
of the CollectionView you're passing in. The cost is that you'll want to keep a reference of that view. Something like,
onRender: function() {
this.fieldView = new Marionette.CollectionView.extend({
tagName: "select",
attr: {
name:"type"
},
id: "drop",
className: "select",
childView: FieldView
});
this.getRegion("drop").show(this.fieldView(collection: fieldCollection));
},
onSelectOption: function () {
console.log(this.fieldView.$el.val());
}