Reputation: 143
Hi I am very new to javascript and I have made a lot of buttons on a site which have different calls. They are all the same minus the results which are pretty much like hide.1 and show.2 etc. Its pretty big but there must be a way to make it smaller? Its no biggy just bad coding that i would like not to get in the habbit of doing. And the only reason for (a) after some of them is that the call doesnt works twice, so when i set it show in a full size screen and a mobile screen it does not work right? Thanks
The code is :
$(document).ready(function() {
$('#btn-continue').on('click', function() {
$('#loginbox').hide();
$('#1box').show();
})
});
$(document).ready(function() {
$('#btn-next1').on('click', function() {
$('#1box').hide();
$('#2box').show();
})
});
$(document).ready(function() {
$('#btn-next2').on('click', function() {
$('#2box').hide();
$('#3box').show();
})
});
$(document).ready(function() {
$('#btn-back2').on('click', function() {
$('#2box').hide();
$('#1box').show();
})
});
$(document).ready(function() {
$('#btn-next2a').on('click', function() {
$('#2box').hide();
$('#3box').show();
})
});
$(document).ready(function() {
$('#btn-back2a').on('click', function() {
$('#2box').hide();
$('#1box').show();
})
});
$(document).ready(function() {
$('#btn-next3').on('click', function() {
$('#3box').hide();
$('#4box').show();
})
});
$(document).ready(function() {
$('#btn-back3').on('click', function() {
$('#3box').hide();
$('#2box').show();
})
});
$(document).ready(function() {
$('#btn-next3a').on('click', function() {
$('#3box').hide();
$('#4box').show();
})
});
$(document).ready(function() {
$('#btn-back3a').on('click', function() {
$('#3box').hide();
$('#2box').show();
})
});
$(document).ready(function() {
$('#btn-next4').on('click', function() {
$('#4box').hide();
$('#5box').show();
})
});
$(document).ready(function() {
$('#btn-back4').on('click', function() {
$('#4box').hide();
$('#3box').show();
})
});
$(document).ready(function() {
$('#btn-next4a').on('click', function() {
$('#4box').hide();
$('#5box').show();
})
});
$(document).ready(function() {
$('#btn-back4a').on('click', function() {
$('#4box').hide();
$('#3box').show();
})
});
$(document).ready(function() {
$('#btn-back5').on('click', function() {
$('#5box').hide();
$('#4box').show();
})
});
$(document).ready(function() {
$('#btn-back5a').on('click', function() {
$('#5box').hide();
$('#4box').show();
})
});
And the calls work like this :
<div class="col-sm-6 controls hidden-xs">
<div><button id='btn-back2' name ='back2' type='button' class='btn btn-success'>Back</button></div></div><div class="hidden-xs"><button id='btn-next2' name ='next2' type='button' class='btn btn-primary'>Next</button></div>
</div>
<div class="col-xs-6 controls hidden-sm hidden-md hidden-lg">
<div><button id='btn-back2a' name ='back2a' type='button' class='btn btn-success'>Back</button></div></div><div class="hidden-sm hidden-md hidden-lg"><button id='btn-next2a' name ='next2a' type='button' class='btn btn-primary'>Next</button></div
>
Upvotes: 1
Views: 54
Reputation: 656
Just make it more generic. You can use classes or data attributes. There is a lot of different ways to do this.
jsfiddle - https://jsfiddle.net/vouvcedj/4/
There is still a lot of cleanup that can be done but this should be pretty clear as to what you can do.
JS
$(function() {
var handleFirstLast = function() {
if ($('.shown').is('.section:first')) {
$('#btn-back').hide();
} else {
$('#btn-back').show();
}
if ($('.shown').is('.section:last')) {
$('#btn-forward').hide();
} else {
$('#btn-forward').show();
}
}
handleFirstLast();
$('#btn-back').on('click', function(e) {
// find the currently shown section and get the previous
// https://api.jquery.com/next/
var $showing = $('.section.shown');
$showing.prev().removeClass('hidden').addClass('shown');
$showing.removeClass('shown').addClass('hidden');
handleFirstLast();
});
$('#btn-forward').on('click', function(e) {
var $showing = $('.section.shown');
$showing.next().removeClass('hidden').addClass('shown');
$showing.removeClass('shown').addClass('hidden');
handleFirstLast();
});
});
HTML
<div class="sections">
<div class="section shown">
section 1
</div>
<div class="section hidden">
section 2
</div>
<div class="section hidden">
</div>
</div>
<div class="actions">
<button id="btn-back">Back</button>
<button id="btn-forward">Forward</button>
</div>
Upvotes: 4
Reputation: 5978
This refers to DRY (Don't Repeat Yourself) principle and it is one of the core principles in programming. If you find yourself repeating in code, means trouble, a small change can be catastrophic for you if you need to go to each place and implement it.
With DRY principle you write code once and reuse it via numerous techniques. A change can be applied once and to one place only.
When the DRY principle is applied successfully, a modification of any single element of a system does not require a change in other logically unrelated elements. Additionally, elements that are logically related all change predictably and uniformly, and are thus kept in sync.
You code can be changed to something like this:
var myNs = myNs || {};
$(document).ready(function() {
$(myNs.map).each(function(index, value) {
$(value.clickedElement).on('click', clickHandler.bind(this, value));
});
function clickHandler(value) {
$(value.hideElement).hide();
$(value.showElement).show();
}
});
What about the myNs
? This is a configuration object, a namespace to load your configuration for elements. This can be a completely different JavaScript file, which of course is loaded before this particular script.
Example:
// This can be in a completely different file
var myNs = {
map: [{
clickedElement: '#btn-continue',
hideElement: '#loginbox',
showElement: '#1box'
}, {
clickedElement: '#btn-next1',
hideElement: '#1box',
showElement: '#2box'
}, {
clickedElement: '#btn-next2',
hideElement: '#2box',
showElement: '#3box'
}, {
clickedElement: '#btn-back2',
hideElement: '#2box',
showElement: '#1box'
},
...
]
};
You can take this a step forward and use the new ES6 modules or even AMD modules. Of course you need a module loader for that, like SystemJS, Webpack or RequireJS.
Check out the following plunk to peak on some code.
Upvotes: 0
Reputation: 50797
Perhaps something like this would make sense:
$(document).ready(function() {
const buttons = [
['btn-continue', 'loginbox', '1box'],
['btn-next1', '1box', '2box'],
['btn-next2', '2box', '3box'],
['btn-back2', '2box', '1box'],
['btn-next2a', '2box', '3box'],
['btn-back2a', '2box', '1box'],
['btn-next3', '3box', '4box'],
['btn-back3', '3box', '2box'],
['btn-next3a', '3box', '4box'],
['btn-back3a', '3box', '2box'],
['btn-next4', '4box', '5box'],
['btn-back4', '4box', '3box'],
['btn-next4a', '4box', '5box'],
['btn-back4a', '4box', '3box'],
['btn-back5', '5box', '4box'],
['btn-back5a', '5box', '4box']
]
buttons.forEach(function(b) {
$('#' + b[0]).on('click', function() {
$('#' + b[1]).hide();
$('#' + b[2]).show();
});
});
});
This captures the repetitive data in a single structure, and replaces the repetitive code with a loop.
Note that this is entirely untested.
Upvotes: 2