Forum Moderators: open
var selects = Array (
document.getElementById('.....'),
document.getElementById('.....'),
);
function updateList (index) {
var select = selects[index];
for (var i=0; i<index; i++)
select.removeChild(childNodes[selects[i].selectedIndex]);
}
function update () {
var l = selects.length;
for (var i=0; i<l; i++) {
rebuildList (i);
updateList (i);
}
}
function rebuildList (index) {
var copy = select[0].cloneNode(true);
selects[index].parentNode.replaceChild(copy, selects[index]);
selects[index] = copy;
}
Edit: forgot a line
try this
<html>
<head>
<script type='text/javascript'>
var selects = null;
function init() {
selects = Array (
document.getElementById('a'),
document.getElementById('b'),
document.getElementById('c'),
document.getElementById('d')
);
update();
}
function updateList (index) {
var select = selects[index];
for (var i=0; i<index; i++)
select.removeChild(select.childNodes[selects[i].selectedIndex]);
}
function update () {
var l = selects.length;
for (var i=1; i<l; i++) {
rebuildList (i);
updateList (i);
}
}
function rebuildList (index) {
var copy = selects[0].cloneNode(true);
var blank = document.createTextNode('');
// Clean it
var l = selects[index].childNodes.length;
for (var i=0; i<l; i++) {
selects[index].replaceChild(blank, selects[index].childNodes[i]);
selects[index].removeChild(blank);
}
// Build it
l = selects[0].childNodes.length;
for (var i=0; i<l; i++) {
selects[index].appendChild(selects[0].childNodes[i].cloneNode(true), null);
}
}
</script>
</head>
<body onload='init();'>
<select id='a' onchange='update();'>
<option>Option 1</option>
<option>Option 2</option>
<option>Option 3</option>
<option>Option 4</option>
<option>Option 5</option>
<option>Option 6</option>
</select>
<select id='b' onchange='update();'></select>
<select id='c' onchange='update();'></select>
<select id='d' onchange='update();'></select>
</body>
</html>
I decided tp used onchange for simplicity (IE Event model), hence I modified the rebuildList function.
<html>
<head>
<script type='text/javascript'>
var selects = null;
function init() {
selects = Array (
document.getElementById('a'),
document.getElementById('b'),
document.getElementById('c'),
document.getElementById('d')
);
update(1);
}
function updateList (index) {
var select = selects[index];
for (var i=0; i<index; i++) {
select.removeChild(select.options[selects[i].selectedIndex]);
}
}
function update (start) {
var l = selects.length;
for (var i=start; i<l; i++) {
rebuildList (i);
updateList (i);
}
}
function rebuildList (index) {
var copy = selects[0].cloneNode(true);
var blank = document.createTextNode('');
// Clean it
while (selects[index].childNodes.length > 0) {
selects[index].replaceChild(blank, selects[index].childNodes[0]);
selects[index].removeChild(blank);
}
// Build it
var l = selects[0].childNodes.length;
for (var i=0; i<l; i++) {
selects[index].appendChild(selects[0].childNodes[i].cloneNode(true), null);
}
selects[index].selectedIndex = 0;
}
</script>
</head>
<body onload='init();'>
<select id='a' onchange='update(1);'>
<option>Option 1</option>
<option>Option 2</option>
<option>Option 3</option>
<option>Option 4</option>
<option>Option 5</option>
<option>Option 6</option>
</select>
<select id='b' onchange='update(2);'></select>
<select id='c' onchange='update(3);'></select>
<select id='d' onchange='update(4);'></select>
</body>
</html>
There you are!
[The problem with the above was that when the last one said "Remove #6", it was already down to only 5 options. There was also an issue with the SelectedIndex remaining at the high value, so it get's forced to 0 when a list is rebuilt. It would be silly to do this all the time to all the lists (user looses changes), so now update takes a starting parameter.]
Hope this answers your question!
If I read what I thought I read, you could get stuck in a nasty mess, eg:
3 options, 3 selects:
select A has 1 selected, so select B and select C cannot have 1 selected. Hence, select B has 2 selected. Hence select A and select C cannot have 2 selected. Hence, select C has 3 selected. Hence select A and select B cannot have 3 selected. Hence, there is only one answer set, and that is {1,2,3}
This is what happens if you impose the condition that not only can select C not have any elements from select B, but select B cannot have any elements from select C.
It is possible to code this, but I advise against it. In this case, it shouldn't be an issue, as if you choose {1,2,3} or {1,3,2} or {3,2,1} what difference does it make? The set contains the same elements, hence the sets are equal [the set-theory classes speak up now and say "not really, they are different!", but I silence them].
HOWEVER, if it is important:
Anyways, just be carefull not to have less options than selects. That would be VERY bad.
Personally, I like the way I did this one more (using styles), but I'm not sure about all browsers ability to hide options. Oh well, there really isn't any other way without creating spagetti code.
BTW, I found this to be an interesting question, at least in the point of what methods are there to do it. Too bad more questions here in WW/Js aren't this way.
<html>
<head>
<script type='text/javascript'>
var selects = null;
var selectSource = null;
function init() {
selects = Array (
document.getElementById('a'),
document.getElementById('b'),
document.getElementById('c'),
document.getElementById('d')
);
selectSource = document.getElementById('source');
var l = selects.length;
for (var i=0; i<l; i++)
buildList (i);
update();
}
function updateList (index) {
var select = selects[index];
var l = selects.length
for (var i=0; i<l; i++) {
if (i!= index)
select.options[selects[i].selectedIndex].style.display = "none";
}
}
function update () {
var l = selects.length;
for (var i=0; i<l; i++) {
rebuildList (i);
updateList (i);
}
}
function buildList (index) {
var blank = document.createTextNode('');
// Clean it
while (selects[index].childNodes.length > 0) {
selects[index].replaceChild(blank, selects[index].childNodes[0]);
selects[index].removeChild(blank);
}
// Build it
var l = selectSource.childNodes.length;
for (var i=0; i<l; i++) {
selects[index].appendChild(selectSource.childNodes[i].cloneNode(true), null);
}
selects[index].selectedIndex = index;
}
function rebuildList (index) {
var l = selects[index].options.length
for (var i=0; i<l; i++) {
selects[index].options[i].style.display = "block";
}
}
</script>
</head>
<body onload='init();'>
<select id='source' style='display: none;'>
<option>Option 1</option>
<option>Option 2</option>
<option>Option 3</option>
<option>Option 4</option>
<option>Option 5</option>
<option>Option 6</option>
</select>
<select id='a' onchange='update();'></select>
<select id='b' onchange='update();'></select>
<select id='c' onchange='update();'></select>
<select id='d' onchange='update();'></select>
</body>
</html>
I reply at your topic
--> your at 5.38
> yes good :)
> only .. if possible to put "----" option for free value if user change Idea?
> so If I set 3 and after set "----" 3 is enable for other selects?
> And if possible to make that if select firt select is update if not value selected?
> thks.. high value work :)
--> your at 5.52
> any select is 1 field with name=""
--> don't work in my Ie / Maxthon
Thks :D
At the least, it should give you starting points to work from...
Oh, and 5:58 I didn't expect to work with IE. Since IE still uses the Windows element for <select> rather than built it itself (it's the only one), it tends to impose limits on what you can do with it. That means setting display:none doesn't work.
The best way to get 5:58 working in IE would be to try to use removeChild on options: For each select, make a list of Options to remove. Store the list in an array. After all selects have been done, for each select go remove the options it cann't display, starting with the highest first [lowest first introduces problem that after removing #2, then #3 is really #2 so all remove 3's really mean remove 2].
That only becomes sane if you do a little OOP with it, otherwise you'll end up with arrays of arrays of arrays.
Can you use --- as an option with 5:38? Probably. You'd want to have a test:
if (option.value!="---") {
//code to remove option from others...
}
If it is the first option, and when they reset they all reset to selectedIndex=0 (which they do), then that would be the default for unselected.
I'll draft code up if you can verify this is what you want.