Reputation: 67
I am making a calendar page where users can select any day of the week but the options must not duplicate what is already selected in other ones.
Check below to see what I mean:
var elementOption = ["--", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"]
function update(element) {
//do something, IDK
}
<h4>How can we prevent selected option in A from showing in options B and C, and vice versa?</h4>
<div>
<h5> A </h5>
<select name="day_select" onchange="update(this)">
<option value="--">--</option>
<option value="monday">Monday</option>
<option value="tuesday">Tuesday</option>
<option value="wednesday">Wednesday</option>
<option value="thursday">Thursday</option>
<option value="friday">Friday</option>
<option value="saturday">Saturday</option>
<option value="sunday">Sunday</option>
</select>
</div>
<div>
<h5> B </h5>
<select name="day_select" onchange="update(this)">
<option value="--">--</option>
<option value="monday">Monday</option>
<option value="tuesday">Tuesday</option>
<option value="wednesday">Wednesday</option>
<option value="thursday">Thursday</option>
<option value="friday">Friday</option>
<option value="saturday">Saturday</option>
<option value="sunday">Sunday</option>
</select>
</div>
<h5> C </h5>
<select name="day_select" onchange="update(this)">
<option value="--">--</option>
<option value="monday">Monday</option>
<option value="tuesday">Tuesday</option>
<option value="wednesday">Wednesday</option>
<option value="thursday">Thursday</option>
<option value="friday">Friday</option>
<option value="saturday">Saturday</option>
<option value="sunday">Sunday</option>
</select>
</div>
My question: How can we do it without using Jquery or many nested For loops (as performance is key here too). Thank you
Upvotes: 1
Views: 51
Reputation: 50
Here is a rough solution showing the dynamics in VanillaJS
https://jsfiddle.net/e5zhymwL/17/
const options = [
"--",
"monday",
"tuesday",
"wednesday",
"thursday",
"friday",
"saturday",
"sunday",
]
const daysSelected = []
const selectedListBox = document.getElementById('selected')
function update(elem, targetId) {
const selected = elem.value
if (selected === '--') return
daysSelected.push(selected)
// print out already selected days
const otherSelector = document.getElementById(targetId)
// replace the targeted selector with available options
otherSelector.innerHTML = ''
otherSelector.insertAdjacentHTML(
'beforeend',
options
.filter(option => daysSelected.indexOf(option) === -1)
.map(option => `<option value="${option}">${option}</option>`)
)
selectedListBox.innerHTML = daysSelected
}
const reset = () => {
daysSelected.length = 0;
[document.getElementById('selector1'),
document.getElementById('selector2')].forEach(elem => {
elem.innerHTML = ''
elem.insertAdjacentHTML(
'beforeend',
options
.filter(option => daysSelected.indexOf(option) === -1)
.map(option => `<option value="${option}">${option}</option>`)
)
})
selectedListBox.innerHTML = ''
}
<h4>Non-duplicating for each of these</h4>
<select name="day_select_1" id="selector1" onchange="update(this,'selector2')">
<option value="--">--</option>
<option value="monday">Monday</option>
<option value="tuesday">Tuesday</option>
<option value="wednesday">Wednesday</option>
<option value="thursday">Thursday</option>
<option value="friday">Friday</option>
<option value="saturday">Saturday</option>
<option value="sunday">Sunday</option>
</select>
<select name="day_select_2" id="selector2" onchange="update(this,'selector1')">
<option value="--">--</option>
<option value="monday">Monday</option>
<option value="tuesday">Tuesday</option>
<option value="wednesday">Wednesday</option>
<option value="thursday">Thursday</option>
<option value="friday">Friday</option>
<option value="saturday">Saturday</option>
<option value="sunday">Sunday</option>
</select>
<p>Selected days: <span id="selected"></span></p>
<button onclick="reset()">Reset</button>
You will need to refactor and clean up a little the code (global scoping and duplications). However, following this you should be able to improve it a little and generate dynamically more days selectors. Hope it could help!
UPDATE
New jsfiddle => https://jsfiddle.net/knopfy/vqnrtzdf/33/
const options = [
"--",
"monday",
"tuesday",
"wednesday",
"thursday",
"friday",
"saturday",
"sunday",
]
const selectors = {
A: document.getElementById('A'),
B: document.getElementById('B'),
C: document.getElementById('C'),
}
const daysSelected = {}
function update(elem) {
const selector = elem.id
const selected = elem.value
if (selected === '--') {
return
}
daysSelected[selector] = selected
for (const key in selectors) {
if (key !== selector) {
for (const option of selectors[key].options) {
option.disabled = daysSelected[key] !== option.value
&& Object.values(daysSelected).indexOf(option.value) !== -1
}
}
}
}
<select name="A" id="A" onchange="update(this)">
<option value="--">--</option>
<option value="monday">Monday</option>
<option value="tuesday">Tuesday</option>
<option value="wednesday">Wednesday</option>
<option value="thursday">Thursday</option>
<option value="friday">Friday</option>
<option value="saturday">Saturday</option>
<option value="sunday">Sunday</option>
</select>
<select name="B" id="B" onchange="update(this)">
<option value="--">--</option>
<option value="monday">Monday</option>
<option value="tuesday">Tuesday</option>
<option value="wednesday">Wednesday</option>
<option value="thursday">Thursday</option>
<option value="friday">Friday</option>
<option value="saturday">Saturday</option>
<option value="sunday">Sunday</option>
</select>
<select name="C" id="C" onchange="update(this)">
<option value="--">--</option>
<option value="monday">Monday</option>
<option value="tuesday">Tuesday</option>
<option value="wednesday">Wednesday</option>
<option value="thursday">Thursday</option>
<option value="friday">Friday</option>
<option value="saturday">Saturday</option>
<option value="sunday">Sunday</option>
</select>
Upvotes: 1