homepage Welcome to WebmasterWorld Guest from 54.204.94.228
register, free tools, login, search, pro membership, help, library, announcements, recent posts, open posts,
Become a Pro Member

Home / Forums Index / Code, Content, and Presentation / JavaScript and AJAX
Forum Library, Charter, Moderator: open

JavaScript and AJAX Forum

    
Dynamically enable/disable <option> using jQuery
jamesMP



 
Msg#: 4598786 posted 2:08 pm on Aug 2, 2013 (gmt 0)

I have three drop-down menus, which work as a product selector. Not all options are available for all products and so I need a script to enable/disable each <option> based on user input.

Lets say I'm selling jelly-beans. They're available in a number of sizes, colours and flavours. Not all colours or flavours are available in all sizes.

I'm currently doing something like the following:

"Size" drop-down with id="size" and options small, medium, large
"Colour" drop-down with id="colour" and options red, green, blue, yellow
"Flavour" drop-down with id="flavour" and options strawberry, banana, peach
etc


// enable all options then disable based on user-input
$("#size option[value='small']").removeAttr("disabled");
$("#size option[value='medium']").removeAttr("disabled");
...

$("#colour option[value='red']").removeAttr("disabled");
$("#colour option[value='green']").removeAttr("disabled");
...

$("#flavour option[value='strawberry']").removeAttr("disabled");
$("#flavour option[value='banana']").removeAttr("disabled");
...

if(size == 'small') {
$("#colour option[value='red']").prop("disabled","disabled"); //remove red option
$("#flavour option[value='banana']").prop("disabled","disabled"); //remove banana option
...
}


and hooking into the script with $("select").on("change", function() { foo() });

I'm looking to automate this process, as currently I have to write a script for each product we sell, and as you can appreciate it gets quite cumbersome with large numbers of options.

Ideally I'd like to provide a table/list of available options and have either php or javascript work out the rest... any ideas?

Thanks!

 

DrDoc

WebmasterWorld Senior Member drdoc us a WebmasterWorld Top Contributor of All Time 10+ Year Member



 
Msg#: 4598786 posted 3:31 pm on Aug 2, 2013 (gmt 0)

I've had to do this on many occasions. What I generally do is let PHP/Perl/whatever generate a JavaScript object, then,
onchange, I first set all <option>s to display: none (using CSS, of course) after which I loop through my object to set available <option>s to display: inline.

Sample JS object:
var widget = { 
"fine": ["red", "blue". "green"],
"mighty fine": ["red", "yellow", "black"],
"shiny": ["blue", "yellow", "silver"]
}

jamesMP



 
Msg#: 4598786 posted 3:38 pm on Aug 2, 2013 (gmt 0)

Sorry, should have mentioned this needs to be dynamic - I;m sure I can do something with JS Ojects though to tidy the process up...

DrDoc

WebmasterWorld Senior Member drdoc us a WebmasterWorld Top Contributor of All Time 10+ Year Member



 
Msg#: 4598786 posted 5:07 pm on Aug 2, 2013 (gmt 0)

The solution I refer to above would be 100% dynamic. You use PHP/Perl/whatever to dynamically generate the JavaScript object. Then you use JavaScript code to dynamically enable/disable the options based on the selected value in your first dropdown.

Readie

WebmasterWorld Senior Member 5+ Year Member



 
Msg#: 4598786 posted 6:47 pm on Aug 2, 2013 (gmt 0)

The things I do when I'm bored... :)

<!DOCTYPE html>
<html lang="en">
<head>
<title>T-shirt Builder</title>
<style type="text/css">
body {
font-family: Verdana;
font-size: 0.7em;
}
.optionBox {
border: 1px solid #000000;
margin-bottom: 8px;
padding: 5px;
border-radius: 5px;
}
.optionBox:last-of-type {
margin-bottom: 0px;
}
</style>
</head>
<body>
<h1>CHOOSE YOUR T-SHIRT</h1>
<div style="display: inline-block;">
<div><strong>Size</strong></div>
<div class="optionBox">
<select name="size">
<option value="">-</option>
<option value="small">Small</option>
<option value="medium">Medium</option>
<option value="large">Large</option>
</select>
</div>
<div><strong>Colour</strong></div>
<div class="optionBox">
<select name="colour">
<option value="">-</option>
<option value="blue">Blue</option>
<option value="red">Red</option>
<option value="green">Green</option>
</select>
</div>
<div><strong>Material</strong></div>
<div class="optionBox">
<select name="material">
<option value="">-</option>
<option value="cotton">Cotton</option>
<option value="wool">Wool</option>
<option value="flax">Flax</option>
</select>
</div>
</div>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.10.2.min.js"></script>
<script type="text/javascript">
(function($) {
var dynamicOptions = function() {
var $this = this;

$this.validMap = arguments[0];
$this.selectors = {};
$this.validOptions = {};
$this.currentVals = {};
$this.allVals = {};

$this.__construct = function() {
$.each($this.validMap, function() {
var key = arguments[0];
$this.selectors[key] = $('select[name="' + key + '"]:first');
$this.selectors[key].on('change', $this.handleChange);
$this.validOptions[key] = [];
$this.currentVals[key] = $this.selectors[key].val();
$this.allVals[key] = [];
$this.selectors[key].children().each(function() {
$this.allVals[key].push($(this).val());
});
});
$this.fetchValidOptions();
$this.applyFilters();
}

$this.handleChange = function() {
$this.currentVals[$(this).attr('name')] = $(this).val();
$this.fetchValidOptions();
$this.applyFilters();
}

$this.fetchValidOptions = function() {
$this.validOptions = $.extend(true, {}, $this.allVals);
$.each($this.validMap, function() {
var key = arguments[0];
var val = $this.currentVals[key];
if(typeof $this.validMap[key][val] == 'undefined') {
return true;
}
$.each($this.validOptions, function() {
var fKey = arguments[0];
if(fKey == key) {
return true;
}
var vals = arguments[1];

for(var i = 0; i < vals.length; i++) {
if($.inArray(vals[i], $this.validMap[key][val][fKey]) == -1) {
$this.validOptions[fKey].splice(i, 1);
i -= 1;
}
}
});
});
}

$this.applyFilters = function() {
$.each($this.selectors, function() {
var key = arguments[0];
arguments[1].children().each(function() {
var disabled = ($.inArray($(this).val(), $this.validOptions[key]) == -1);
$(this).prop('disabled', disabled);
});
});
}

$this.__construct();
};

$(document).ready(function() {
var dOpt = new dynamicOptions({
'size': { // Select we're changing
'small': { // Option we just selected
'colour': ['', 'blue', 'red'], // Valid options in other select
'material': ['', 'cotton', 'wool', 'flax']
},
'medium': {
'colour': ['', 'red', 'green'],
'material': ['', 'cotton', 'wool', 'flax']
},
'large': {
'colour': ['', 'blue', 'red', 'green'],
'material': ['', 'cotton']
}
},
'colour': {
'blue': {
'size': ['', 'small', 'large'],
'material': ['', 'cotton', 'wool', 'flax']
},
'red': {
'size': ['', 'small', 'medium', 'large'],
'material': ['', 'wool']
},
'green': {
'size': ['', 'medium', 'large'],
'material': ['', 'cotton', 'wool', 'flax']
}
},
'material': {
'cotton': {
'size': ['', 'small', 'medium', 'large'],
'colour': ['', 'blue', 'green']
},
'wool': {
'size': ['', 'small', 'medium'],
'colour': ['', 'blue', 'red', 'green']
},
'flax': {
'size': ['', 'small', 'medium'],
'colour': ['', 'blue', 'green']
}
}
});
});
})(jQuery);
</script>
</body>
</html>

jamesMP



 
Msg#: 4598786 posted 2:37 pm on Sep 23, 2013 (gmt 0)

@Readie - thank you, I've just come back to this problem. and this gives a good framework to start from.

Global Options:
 top home search open messages active posts  
 

Home / Forums Index / Code, Content, and Presentation / JavaScript and AJAX
rss feed

All trademarks and copyrights held by respective owners. Member comments are owned by the poster.
Home ¦ Free Tools ¦ Terms of Service ¦ Privacy Policy ¦ Report Problem ¦ About ¦ Library ¦ Newsletter
WebmasterWorld is a Developer Shed Community owned by Jim Boykin.
© Webmaster World 1996-2014 all rights reserved