я примерно тоже самое сейчас делаю. Только число селектов не определено. Т.е. может быть и 2, а может быть и 8.
В вашем ТЗ не хватает по крайней мере одной вводной.
Предположим, есть значения. Для простоты размышлений в кажом селекте по 2 оптиона:
Код:
select1{ param1, param2}
select2{ param3, param4}
select3{ param5, param6}
Итого 2*2*2 = 8 комбинаций могут быть максимально.
Собственно, комбинации:
Код:
param1 => param3 => param5
param1 => param3 => param6
param1 => param4 => param5
param1 => param4 => param6
<-- param2 => param3 => param5 --> --эту исключим.
param2 => param3 => param6
param2 => param4 => param5
param2 => param4 => param6
Так вот, при выборе param3 во втором селекте итоговое состояние селектов будет таким:
Код:
select1{ param1 }
select2{ param3, param4 }
select3{ param5, param6 }
или таким:
Код:
select1{ param1, param2 }
select2{ param3, param4 }
select3{ param6 }
??
То есть не ясно по какому из соседних селектов строить.
Следующее. Адекватный обход удается построить, если комбинации в многомерном массиве.
Т.е.
Код:
var array = [
['param1', 'param1', 'param1'],
['param1', 'param1', 'param2'],
... и т.д.
];
Можно использовать быстрые циклы for/while. Это прокатит, если не так много комбинаций.
Если же у вас например 5 селектов по 10 оптионов в каждом, то выходит
500 тыс. вероятных комбинаций? А если 10 селектов по 10 оптионов? 10 млрд? Я не матан, к сожалению, а практик и вынужден признать мозги вскипают. Как запилить обход объекта, как в коде выше опираясь на значение последнего по уровню ключа так и не придумал.
...И я вот что подумал. Что есть смысл строить массивы комбинаций, производить тысячи итераций, создавать временные массивы, делать туеву хучу сравнений, а потом строить. Если можно сразу начать строить? ...А соответствия писать прямо в HTMLе.
И написал вот этот код в виде плагина JQuery:
HTML:
(function($){
jQuery.fn.slipoptions = function(options){
options = $.extend({
class:false,
val:false
}, options);
var f = function(){
var enData = $(this).children('option[value="'+$(this).val()+'"]').data();
var i;
for(i in enData){
if(i in f){
$('.'+i).children('option').remove();
} else {
f[i] = $('.'+i).children('option').detach();
}
f[i].each(function(){
var str = $(this).val();
if(enData[i].indexOf(str)>-1){
$(this).clone().appendTo($('.'+i));
}
});
}
};
$(this).on('change', f);
if(options.class){
if(options.val){
$('.'+options.class).val(options.val).trigger('change');
} else {
$('.'+options.class).trigger('change');
}
}
return this;
};
})(jQuery);
То есть пишем прямо в option, что, при её выборе, будут содержать селекты. Пример:
HTML:
<select class="selone">
<option data-seltwo="size_s,param_name2,small" data-sel3="size_m,green,verysmall" value="size_xxl">Размер XXL</option>
<option data-selone="red,param_name1" data-seltwo="param_name2,small,size_s" data-sel3="green,verysmall" value="red">Красный</option>
<option data-seltwo="white,small" data-sel3="size_m,green,verysmall" value="param_name1">Name param</option>
<option data-seltwo="param_name2,white" data-sel3="verybig,green,verysmall" value="big">Большой</option>
</select>
<select class="seltwo">
<option data-selone="param_name1,big" data-sel3="verybig,green,verysmall" value="white">Белый</option>
<option data-selone="red,param_name1,big" data-sel3="size_m,green,verysmall" value="param_name2">Имя параметра 2</option>
<option data-selone="red,param_name1" data-sel3="green,verysmall" value="size_s">Размер S</option>
<option data-selone="size_xxl,red,param_name1" data-sel3="size_m,green,verysmall" value="small">Маленький</option>
</select>
<select class="sel3">
<option data-selone="size_xxl,red,param_name1" data-seltwo="white,small,size_s" value="verybig">Очень большой</option>
<option data-selone="param_name1,big" data-seltwo="white,small" value="size_m">Размер M</option>
<option data-selone="red,param_name1,big" data-seltwo="param_name2,small,size_s" value="verysmall">Очень маленький</option>
<option data-selone="red,param_name1" data-seltwo="size_s,small" value="green">Зеленый</option>
</select>
Инициализация:
Код:
$(document).ready(function(){
$('select[class^="sel"]').slipoptions();
});
Если передать:
Код:
$('select[class^="sel"]').slipoptions({
class: 'seltwo',
val: 'small'
});
то при загрузке страницы значения селектов будут построены по данным, содержащимся в option со значением small селекта с классом seltwo. Если передать только класс, то значения будут построены по текущему значению селекта с этим классом. Если не передавать этот параметр, то при загрузке страницы никакие селекты исключены не будут. Особого опыта написания плагинов для JQuery у меня нет
Тестил в Opere на вебките, в Opere на Presto, в Лисе, в ie9, Хроме, на мобильных браузерах - работает. А так же с версиями JQuery: 1.7.2, 1.8.3, 1.9.1, 1.11.3, 2.1.4, 3.0.0-alpha1
Важно усвоить, что все <option>, которые
могут быть в селекте - должны там быть изначально.