patternjavascriptMinor
Wizard for displaying results divs based on answers
Viewed 0 times
wizarddivsanswersdisplayingforbasedresults
Problem
I have created a "Wizard" using JavaScript and based on people's answers you get taken to certain results divs. It works the way I want, but this code is VERY repetitive. Is there a way to clean up this JavaScript code?
Demo can be seen here.
```
$(".hidden").hide();
$(function() {
$("#start_button").click(function(){
$("#wizard_start").hide();
$("#Q1").show();
});
$("#reset").click(function(){
$("#wizard_start").show();
$(".hidden").hide();
$(":input").not(":button, :submit, :reset, :hidden").each( function() {
this.value = this.defaultValue;
});
});
$("#q1_button").click(function(){
if ($("input[value='q1_1']:checked").val()){
$("#Q2").show();
$("#Q1").hide();
}
else if ($("input[value='q1_2']:checked").val()) {
$("#results1").show();
$("#Q1").hide();
}
else if ($("input[value='q1_3']:checked").val()) {
$("#Q3").show();
$("#Q1").hide();
}
});
$("#q2_button").click(function(){
if ($("input[value='q2_1']:checked").val()){
$("#results2").show();
$("#Q2").hide();
}
else {
$("#results3").show();
$("#Q2").hide();
}
});
$("#q3_button").click(function(){
if ($("input[value='q3_1']:checked").val()){
$("#Q4").show();
$("#Q3").hide();
}
else {
$("#results1").show();
$("#Q3").hide();
}
});
$("#q4_button").click(function(){
if ($("input[value='q4_1']:checked").val()){
$("#Q5").show();
$("#Q4").hide();
}
else {
$("#Q6").show();
$("#Q4").hide();
}
});
$("#q5_button").click(function(){
if ($("input[value='q5_1']:checked").val()){
$("#results4").show();
$("#Q5").hide();
}
else {
$("#Q7").sho
Demo can be seen here.
```
$(".hidden").hide();
$(function() {
$("#start_button").click(function(){
$("#wizard_start").hide();
$("#Q1").show();
});
$("#reset").click(function(){
$("#wizard_start").show();
$(".hidden").hide();
$(":input").not(":button, :submit, :reset, :hidden").each( function() {
this.value = this.defaultValue;
});
});
$("#q1_button").click(function(){
if ($("input[value='q1_1']:checked").val()){
$("#Q2").show();
$("#Q1").hide();
}
else if ($("input[value='q1_2']:checked").val()) {
$("#results1").show();
$("#Q1").hide();
}
else if ($("input[value='q1_3']:checked").val()) {
$("#Q3").show();
$("#Q1").hide();
}
});
$("#q2_button").click(function(){
if ($("input[value='q2_1']:checked").val()){
$("#results2").show();
$("#Q2").hide();
}
else {
$("#results3").show();
$("#Q2").hide();
}
});
$("#q3_button").click(function(){
if ($("input[value='q3_1']:checked").val()){
$("#Q4").show();
$("#Q3").hide();
}
else {
$("#results1").show();
$("#Q3").hide();
}
});
$("#q4_button").click(function(){
if ($("input[value='q4_1']:checked").val()){
$("#Q5").show();
$("#Q4").hide();
}
else {
$("#Q6").show();
$("#Q4").hide();
}
});
$("#q5_button").click(function(){
if ($("input[value='q5_1']:checked").val()){
$("#results4").show();
$("#Q5").hide();
}
else {
$("#Q7").sho
Solution
Something like this is probably a good way to start consolidating. Do the buttons share a class by chance?
The amount of code duplication this will eliminate will depend on how similar your function bodies actually are. You'd add case statements to the switch to accommodate special cases.
Alternatively, you could add an object that contained values referring to what you check against, what you show, and what you hide. That would look something like this:
Then our click function becomes something like this:
Hopefully one of those two fit with your idea of reducing duplication and/or simplifying.
-- Edit --
I realized I didn't address your "Jump to start" functionality. I added that to the first example. It could be added to the second as well.
$('.myButtonClass').click(function () {
// Extract an id:
var myid = this.id.substr(1, 3);
switch (myid) {
case 'reset':
$('wizard_start').show();
$('questionClass').hide();
default:
if ($("input[value='q' + myid + '_1']:checked").val()){
$("#Q" + (myid + 1)).show();
} else {
$("#Q" + (myid + 2)).show();
}
$("#Q" + myid).hide();
}
});The amount of code duplication this will eliminate will depend on how similar your function bodies actually are. You'd add case statements to the switch to accommodate special cases.
Alternatively, you could add an object that contained values referring to what you check against, what you show, and what you hide. That would look something like this:
var wizardOrder = {
'q1': {
'check': "input[value='q1_1']:checked",
'show': 'Q2',
'hide': 'Q3'
}
};Then our click function becomes something like this:
$('myButtonClass').click(function () {
var myid = this.id.substr(1, 3);
if ($(wizardOrder[myid]['check']).val()) {
$(wizardOrder[myid]['show'].show();
$(wizardOrder[myid]['hide'].show();
}
});Hopefully one of those two fit with your idea of reducing duplication and/or simplifying.
-- Edit --
I realized I didn't address your "Jump to start" functionality. I added that to the first example. It could be added to the second as well.
Code Snippets
$('.myButtonClass').click(function () {
// Extract an id:
var myid = this.id.substr(1, 3);
switch (myid) {
case 'reset':
$('wizard_start').show();
$('questionClass').hide();
default:
if ($("input[value='q' + myid + '_1']:checked").val()){
$("#Q" + (myid + 1)).show();
} else {
$("#Q" + (myid + 2)).show();
}
$("#Q" + myid).hide();
}
});var wizardOrder = {
'q1': {
'check': "input[value='q1_1']:checked",
'show': 'Q2',
'hide': 'Q3'
}
};$('myButtonClass').click(function () {
var myid = this.id.substr(1, 3);
if ($(wizardOrder[myid]['check']).val()) {
$(wizardOrder[myid]['show'].show();
$(wizardOrder[myid]['hide'].show();
}
});Context
StackExchange Code Review Q#3060, answer score: 5
Revisions (0)
No revisions yet.