2017-01-09 38 views
0

バニラのJavaScriptを使用して、表のセルにドロップダウン・マルチ選択メニューを作成しようとしています。どうにかして、コードを実行するとコンソールに表示される、プロセス内に重複したオプションセットを作成することができました。おそらく、私がやっていることは間違ったアプローチです。アドバイスをいただければ幸いです。javascript動的に選択するオプションを選択すると、選択肢が重複して表示される

let allrooms = ['entry', 'kitchen', 'bath', 'hall', 'bed', 'garage']; 
 
let selectedrooms = ['bath', 'kitchen', 'garage']; 
 

 
let menuHeader = document.getElementById('menu-header'); 
 
let roomcontainer = document.getElementById('menu-roomcontainer'); 
 

 
// set the menu header (also a 'td') to a comma delimited string 
 
function addRoomNamesToMenuHeader() { 
 
    menuHeader.childNodes[0].nodeValue = selectedrooms.toString(); 
 
} 
 

 
// create and append options to a 'select' from a string array 
 
(function addProjectRoomsToMenu() { 
 
    addRoomNamesToMenuHeader(); 
 
    let str = 'added elements: ' 
 
    for (let r of allrooms) { 
 
    let newroom = document.createElement('option'); 
 
    newroom.innerHTML = '<option value="' + r + '" class="devroom">' + r + '</option>'; 
 
    roomcontainer.appendChild(newroom); 
 
    if (selectedrooms.indexOf(r) > -1) { 
 
     newroom.selected = 'selected'; 
 
    } 
 
    str += (roomcontainer.children.length + ' ' + r + ' '); 
 
    } 
 
    console.log(str); 
 

 
    let list = document.querySelectorAll('option'); 
 
    str = 'NOTE DUPLICATES: option list =\n'; 
 
    for (let i = 0; i < list.length; i++) { 
 
    str += ('\t' + i + ' ' + list[i].label + ' ' + list[i].selected + ' '); 
 
    if (i & 1) { 
 
     str += '\n'; 
 
    } 
 
    } 
 
    console.log(str); 
 

 
    let selected = Array.prototype.map.apply(
 
    roomcontainer.querySelectorAll('option option[selected]'), [ 
 
     function(o) { 
 
     return o.value; 
 
     } 
 
    ] 
 
); 
 
    console.log('NOTE EMPTY QUERY FOR "option option[selected]"=' + selected); 
 
})(); 
 

 
// changes in option selections will result in a change to 
 
// 'selectedrooms' and menuheader 
 
roomcontainer.onchange = function(e) { 
 
    let selected = Array.prototype.map.apply(
 
    roomcontainer.querySelectorAll('option option[selected]'), [ 
 
     function(o) { 
 
     return o.value; 
 
     } 
 
    ] 
 
); 
 
    console.log('NOTE EMPTY LIST selected "option"=' + selected); 
 

 
    selected = Array.prototype.map.apply(
 
    roomcontainer.querySelectorAll('option'), [ 
 
     function(o) { 
 
     return o.value; 
 
     } 
 
    ] 
 
); 
 
    console.log('NOTE DUPLICATES IN LIST all "option"=' + selected); 
 

 
    // TODO: KLUDGE WORK-AROUND 
 
    selectedrooms.length = 0; 
 
    let list = document.querySelectorAll('option'); 
 
    for (let i = 0; i < list.length; i++) { 
 
    if (list[i].selected) { 
 
     selectedrooms.push(list[i].label); 
 
    } 
 
    } 
 
    addRoomNamesToMenuHeader(); 
 
} 
 

 
document.onclick = function(e) { 
 
    let target = (e && e.target) || (event && event.srcElement); 
 

 
    if (target === menuHeader && roomcontainer.style.display == "none") { 
 
    roomcontainer.style.display = "block"; 
 
    } else if (target.parentNode !== roomcontainer) { 
 
    roomcontainer.style.display = "none"; 
 
    } 
 
}
#menu-roomcontainer, 
 
#menu-header, 
 
table { 
 
    font-family: 'Open Sans', sans-serif; 
 
    font-size: 1em; 
 
    max-width: 14em; 
 
    min-width: 14em; 
 
    padding: 3px; 
 
    border: 1px solid blue; 
 
} 
 
/*prevent pushing down subsequent rows*/ 
 

 
#menu-roomcontainer { 
 
    position: absolute; 
 
} 
 
/*prevent empty cell from collapsing*/ 
 

 
tr:before { 
 
    content: '\a0'; 
 
} 
 
#menu-header { 
 
    color: blue; 
 
} 
 
option { 
 
    color: darkolivegreen; 
 
} 
 
option:hover { 
 
    background: lightgray; 
 
} 
 
option:checked { 
 
    background: lightseagreen; 
 
} 
 
option, 
 
#menu-header:hover { 
 
    cursor: pointer; 
 
} 
 
option, 
 
td { 
 
    margin: 0; 
 
}
<table> 
 
    <tr> 
 
    <td id='menu-header'> 
 
     <select multiple id='menu-roomcontainer' style='display: none;'></select> 
 
    </td> 
 
    </tr> 
 
    <tr> 
 
    <td>Row 1</td> 
 
    </tr> 
 
    <tr> 
 
    <td>Row 2</td> 
 
    </tr> 
 
    <tr> 
 
    <td>Row 3</td> 
 
    </tr> 
 
    <tr> 
 
    <td>Row 4</td> 
 
    </tr> 
 
    <tr> 
 
    <td>Row 5</td> 
 
    </tr> 
 
</table>

+0

あなたは問題があるだけセグメントにあなたのコードを削減した場合、それが参考になります。 –

答えて

0

これは間違っている:あなたは無効であるオプション、内部オプションを作成しているので、

newroom.innerHTML = '<option value="' + r + '" class="devroom">' + r + '</option>'; 

newroomは、すでに<option>要素です。それは次のようになります。

newroom.value = r; 
newroom.className = 'devroom'; 
newroom.innerHTML = r; 

let allrooms = ['entry', 'kitchen', 'bath', 'hall', 'bed', 'garage']; 
 
let selectedrooms = ['bath', 'kitchen', 'garage']; 
 

 
let menuHeader = document.getElementById('menu-header'); 
 
let roomcontainer = document.getElementById('menu-roomcontainer'); 
 

 
// set the menu header (also a 'td') to a comma delimited string 
 
function addRoomNamesToMenuHeader() { 
 
    menuHeader.childNodes[0].nodeValue = selectedrooms.toString(); 
 
} 
 

 
// create and append options to a 'select' from a string array 
 
(function addProjectRoomsToMenu() { 
 
    addRoomNamesToMenuHeader(); 
 
    let str = 'added elements: ' 
 
    for (let r of allrooms) { 
 
    let newroom = document.createElement('option'); 
 
    newroom.value = r; 
 
    newroom.className = 'devroom'; 
 
    newroom.innerHTML = r; 
 
    roomcontainer.appendChild(newroom); 
 
    if (selectedrooms.indexOf(r) > -1) { 
 
     newroom.selected = 'selected'; 
 
    } 
 
    str += (roomcontainer.children.length + ' ' + r + ' '); 
 
    } 
 
    console.log(str); 
 

 
    let list = document.querySelectorAll('option'); 
 
    str = 'NOTE DUPLICATES: option list =\n'; 
 
    for (let i = 0; i < list.length; i++) { 
 
    str += ('\t' + i + ' ' + list[i].label + ' ' + list[i].selected + ' '); 
 
    if (i & 1) { 
 
     str += '\n'; 
 
    } 
 
    } 
 
    console.log(str); 
 

 
    let selected = Array.prototype.map.apply(
 
    roomcontainer.querySelectorAll('option option[selected]'), [ 
 
     function(o) { 
 
     return o.value; 
 
     } 
 
    ] 
 
); 
 
    console.log('NOTE EMPTY QUERY FOR "option option[selected]"=' + selected); 
 
})(); 
 

 
// changes in option selections will result in a change to 
 
// 'selectedrooms' and menuheader 
 
roomcontainer.onchange = function(e) { 
 
    let selected = Array.prototype.map.apply(
 
    roomcontainer.querySelectorAll('option option[selected]'), [ 
 
     function(o) { 
 
     return o.value; 
 
     } 
 
    ] 
 
); 
 
    console.log('NOTE EMPTY LIST selected "option"=' + selected); 
 

 
    selected = Array.prototype.map.apply(
 
    roomcontainer.querySelectorAll('option'), [ 
 
     function(o) { 
 
     return o.value; 
 
     } 
 
    ] 
 
); 
 
    console.log('NOTE DUPLICATES IN LIST all "option"=' + selected); 
 

 
    // TODO: KLUDGE WORK-AROUND 
 
    selectedrooms.length = 0; 
 
    let list = document.querySelectorAll('option'); 
 
    for (let i = 0; i < list.length; i++) { 
 
    if (list[i].selected) { 
 
     selectedrooms.push(list[i].label); 
 
    } 
 
    } 
 
    addRoomNamesToMenuHeader(); 
 
} 
 

 
document.onclick = function(e) { 
 
    let target = (e && e.target) || (event && event.srcElement); 
 

 
    if (target === menuHeader && roomcontainer.style.display == "none") { 
 
    roomcontainer.style.display = "block"; 
 
    } else if (target.parentNode !== roomcontainer) { 
 
    roomcontainer.style.display = "none"; 
 
    } 
 
}
#menu-roomcontainer, 
 
#menu-header, 
 
table { 
 
    font-family: 'Open Sans', sans-serif; 
 
    font-size: 1em; 
 
    max-width: 14em; 
 
    min-width: 14em; 
 
    padding: 3px; 
 
    border: 1px solid blue; 
 
} 
 
/*prevent pushing down subsequent rows*/ 
 

 
#menu-roomcontainer { 
 
    position: absolute; 
 
} 
 
/*prevent empty cell from collapsing*/ 
 

 
tr:before { 
 
    content: '\a0'; 
 
} 
 
#menu-header { 
 
    color: blue; 
 
} 
 
option { 
 
    color: darkolivegreen; 
 
} 
 
option:hover { 
 
    background: lightgray; 
 
} 
 
option:checked { 
 
    background: lightseagreen; 
 
} 
 
option, 
 
#menu-header:hover { 
 
    cursor: pointer; 
 
} 
 
option, 
 
td { 
 
    margin: 0; 
 
}
<table> 
 
    <tr> 
 
    <td id='menu-header'> 
 
     <select multiple id='menu-roomcontainer' style='display: none;'></select> 
 
    </td> 
 
    </tr> 
 
    <tr> 
 
    <td>Row 1</td> 
 
    </tr> 
 
    <tr> 
 
    <td>Row 2</td> 
 
    </tr> 
 
    <tr> 
 
    <td>Row 3</td> 
 
    </tr> 
 
    <tr> 
 
    <td>Row 4</td> 
 
    </tr> 
 
    <tr> 
 
    <td>Row 5</td> 
 
    </tr> 
 
</table>

+0

ありがとうございます。ごめんなさい。私は私の普通の電子メールアドレスで電子メール通知を受け取ると思った。また、私はそれ以来、これは、SELECTの代わりにULを使用する方がコントロールキー/シフトキーがモバイルの使用を妨げるので、 –

関連する問題