Targetting elements
$('select')
is generic selector and will select all <select>
elements on the page. There might be some <select>
elements which are not needed to target for this functionality.
You can target only required elements using
Unique parent selector + descendant selector
In this, there will be a main container element and using this all the descendant <select>
elements can be targeted.
Example:
HTML:
<div id="container">
<select name="list" id="list">
<option value="">...</option>
</select>
<input name="refresh" />
<input name="add" type="button" value="add" />
<select name="list1" id="list1">
<option value="">...</option>
</select>
<input name="refresh1" />
<input name="add1" type="button" value="add1" />
...
</div>
JavaScript:
$('#container select').change(function() {
Using common class
Sometimes, adding all the elements under a container is not possible. In such cases, adding a common class to all the elements will allow to select elements using class selector.
$('.someCommonClass').change(function() {
Common attributes can also be added and selected using Attribute Equals Selector [name=”value”]. However, this can be slower than class selectors.
Similarly, another common + unique class should be applied to buttons.
<input name="refresh" class="anotherUnique" />
<input name="add" class="anotherUnique" />
Then, to disable/enable these buttons, they can be referenced.
HTML5 data-*
attributes
HTML5's custom data-*
attribute can be used to store custom data on HTML elements.
<select name="list" id="list" data-key="value">
Getting data-*
attribute value
jQuery provides data(name)
method to get the value of the data-name
attribute value. Core JavaScript has dataset
property that allows access to data attributes.
$('elemSelector').data('key')
Using prop()
with value
prop()
accepts second parameter which will be converted to Boolean internally and depending on the value, the action will be taken. So, the if
and else
statements in the question can be combined as
$('elemSelector').prop('disabled', booleanValueHere);
If second parameter is truthy, element will be disabled. If falsy then element will be enabled.
Putting it all together
// Bind change event on all select elements
// having unique class
$('select.unique').change(function () {
// Cache this
var $this = $(this);
// Get the data-* attribute values
var button1 = $this.data('button1'),
button2 = $this.data('button2');
// Get the value of this select box
// Use this as second parameter to prop
$('input[name="' + button1 + '"]').prop('disabled', this.value);
$('input[name="' + button2 + '"]').prop('disabled', !this.value);
});
/* For Demo Purpose */
input {
color: green;
font-weight: bold;
}
input:disabled {
color: gray;
opacity: .5;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select name="list" id="list" class="unique" data-button1="refresh" data-button2="add">
<option value="">choose</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<input name="refresh" type="button" class="anotherUnique" value="Refresh" />
<input name="add" type="button" class="anotherUnique" value="Add" disabled />
<hr />
<!-- Another select box -->
<select name="list1" id="list1" class="unique" data-button1="refresh1" data-button2="add1">
<option value="">choose</option>
<option value="10">10</option>
<option value="20">20</option>
<option value="30">30</option>
</select>
<input name="refresh1" type="button" class="anotherUnique1" value="Refresh 1" />
<input name="add1" type="button" class="anotherUnique1" value="Add 1" disabled />
Conclusion
Now, the JavaScript code don't have to be written again for each new select
element. Just adding the markup with required attributes will automatically work. The relation between HTML element-JavaScript handler is reduced from many to many to many to one.