I want to toggle button visibility based on values a user selects within a group of checkboxes.
For example, the user may be given a group of checkboxes with colors:
<input type="checkbox" value="red">Redbr>
<input type="checkbox" value="blue">Blue<br>
<input type="checkbox" value="green">Green
And the available vehicles would be visible based on the colors selected:
<button class="choice-button" data-attributes= "red,blue" type="button">Truck</button><br>
<button class="choice-button" data-attributes= "green" type="button">Car</button><br>
I have code that works, but I do not believe it is optimized:
<!DOCTYPE HTML>
<html>
<head>
<script src="http://code.jquery.com/jquery-1.8.2.min.js"></script>
<script type="text/javascript">
//http://stackoverflow.com/questions/1181575/javascript-determine-whether-an-array-contains-a-value
var indexOf = function(needle) {
if(typeof Array.prototype.indexOf === 'function') {
indexOf = Array.prototype.indexOf;
} else {
indexOf = function(needle) {
var i = -1, index;
for(i = 0; i < this.length; i++) {
if(this[i] === needle) {
index = i;
break;
}
}
return index;
};
}
return indexOf.call(this, needle);
};
function doTheMagic()
{
//Re-initialize buttons by showing all of them
$('.choice-button').show();
//Find out which buttons are checked and store their value into an array
var buttonRequirements = new Array();
$('#myform :checkbox').each(function(){
if($(this).is(':checked'))
buttonRequirements.push($(this).val());
});
//Loop through each of the available "choice buttons" and hide ones that do not fit the checked criteria (e.g. buttonRequirements)
$('.choice-button').each(function(){
buttonAttributes = $(this).data('attributes');
buttonArray = buttonAttributes.toString().split(',');
for (var i = 0; i < buttonRequirements.length; i++) {
//If the button does not contain the checked attribute, hide it
index = indexOf.call(buttonArray, buttonRequirements[i]);
if (index<0)
$(this).hide();
}
});
}
$(document).ready(function() {
//Every time a checkbox value changes, call the function to show/hide the appropriate button
$('#myform :checkbox').click(function() {
doTheMagic();
});
});
</script>
</head>
<body>
<form id="myform">
<h3>Filter choices based on attributes:</h3>
<input type="checkbox" value="1">Attribute 1<br>
<input type="checkbox" value="2">Attribute 2<br>
<input type="checkbox" value="3">Attribute 3<br>
<input type="checkbox" value="4">Attribute 4<br>
<input type="checkbox" value="5">Attribute 5<br>
<h3>Available choices</h3>
<button class="choice-button" data-attributes="1,3,4,5" type="button">Choice 1</button><br>
<button class="choice-button" data-attributes="2,3,4,5" type="button">Choice 2</button><br>
<button class="choice-button" data-attributes= "1,2,3,4" type="button">Choice 3</button><br>
<button class="choice-button" data-attributes= "1" type="button">Choice 4</button><br>
<button class="choice-button" data-attributes= "2" type="button">Choice 5</button><br>
<button class="choice-button" data-attributes= "3" type="button">Choice 6</button><br>
<button class="choice-button" data-attributes= "4" type="button">Choice 7</button><br>
<button class="choice-button" data-attributes= "5,2" type="button">Choice 8</button>
</form>
</body>
</html>
For my particular Use Case, I am pulling both the “choices” and “attributes” from a database. This form will be created dynamically every time and I want all data loaded up front in the UI.
There are currently 130 “choice buttons” and 78 “attributes”.
Throughout the lifetime of this application, this list will not change much. It would be a very rare scenario to grow even 20% over the next five years.
I thought about using bit comparison but that looks to be out of the question since I have more than 32 options to choose from.
I would like to steer away from the loops and minimize the code if possible.
How can I make this faster?
magic
in its name is usually pretty bad. \$\endgroup\$