I have 3 views, SectionAView
, SectionBView
and SectionCView
.
Each view has 2 radio buttons, Yes
and No
.
When I select Yes
in SectionAView
, it should display SectionBView
. Selecting ‘No’ should display SectionCView
(and hide SectionBView
)
The application could have many views, so I guess my question is to keep things a little bit more DRY and possibly the best way to approach this?
I have something like this:
var Section = Backbone.Model.extend({
defaults: {
block: null
}
});
var List = Backbone.Collection.extend({
model: Section
});
var SectionAView = Backbone.View.extend({
el: 'body',
initialize: function() {
this.model = new Section();
this.collection = new List();
this.listenTo(this.model, "change", this.render);
this.render();
},
events: {
'click .section-a': 'updateElement'
},
render: function(e) {
this.$el.find('.section-b').hide();
return this;
},
updateElement: function(e) {
var $target = $(e.target);
var activeValue = $target.val();
// Default - SectionA is displayed (at all times)
this.model.set('block', 'section-a');
this.collection.push(this.model);
if (activeValue == 'no') {
this.$el.find('.section-b').show();
this.$el.find('.section-c').hide();
} else {
this.$el.find('.section-c').show();
this.$el.find('.section-b').hide();
}
}
});
var SectionBView = Backbone.View.extend({
el: 'body',
model: Section,
initialize: function() {
this.render();
},
render: function(e) {
this.$el.find('.section-b').hide();
return this;
},
});
var SectionCView = Backbone.View.extend({
el: 'body',
initialize: function() {
this.render();
},
render: function(e) {
this.$el.find('.section-c').hide();
return this;
}
});
HTML:
<div class="section-a" data-active-value="true">
<h2>Section A</h2>
<label>Yes<input type="radio" name="section-a" class="section-a" value="yes" /></label>
<label>No<input type="radio" name="section-a" class="section-a" value="no" /></label>
</div>
<div class="section-b" data-active-value="">
<h2>Section B</h2>
<label>Yes<input type="radio" name="section-b" class="section-b" value="yes" /></label>
<label>No<input type="radio" name="section-b" class="section-b" value="no" /></label>
</div>
<div class="section-c">
<h2>Section C</h2>
<label>Yes<input type="radio" name="section-c" class="section" value="yes" /></label>
<label>No<input type="radio" name="section-c" class="section" value="no" /></label>
</div>
It is better if you cache elements and use toggleClass:
render: function(e) {
//cache
var elemB = this.$el.find('.section-b')
var elemC = this.$el.find('.section-c')
elemB.toggleClass('show', false);//remove 'show' class if any
return this;
},
updateElement: function(e) {
var $target = $(e.target);
var activeValue = $target.val();
// Default - SectionA is displayed (at all times)
this.model.set('block', 'section-a');
this.collection.push(this.model);
elemB.toggleClass('show', (activeValue === 'no'));
elemC.toggleClass('show', (activeValue === 'yes'))
}
Additionally if you set activeValue to true or false, you will not have to check for 'no' value and code becomes shorter
elemB.toggleClass('show', activeValue);