I don't know why, but for some reason I am having a problem running a function based on user selection in HTML Select option...
I can get it to work when just doing one (querySelector), but when I do querySelectorAll and create a for loop, things aren't working.
Any help will be greatly appreciated!
let userLocation = document.querySelectorAll('#userLocation');
for(i=0; i < userLocation.length; i ) {
userLocation[i].addEventListener('change', function() {
if(userLocation[i].value === "North Carolina") {
alert('True');
}
}
});
<section id="users">
<div >
<div >
<h3>Frank</h3>
<label>Location:</label>
<select id="userLocation">
<option value="">Select</option>
<option value="North Carolina">North Carolina</option>
<option value="South Carolina">South Carolina</option>
<option value="Maine">Maine</option>
</select>
</div>
<div >
<h3>Dan</h3>
<label>Location:</label>
<select id="userLocation">
<option value="">Select</option>
<option value="North Carolina">North Carolina</option>
<option value="South Carolina">South Carolina</option>
<option value="Maine">Maine</option>
</select>
</div>
<div >
<h3>Jimmy</h3>
<label>Location:</label>
<select id="userLocation">
<option value="">Select</option>
<option value="North Carolina">North Carolina</option>
<option value="South Carolina">South Carolina</option>
<option value="Maine">Maine</option>
</select>
</div>
<div >
<h3>Bob</h3>
<label>Location:</label>
<select id="userLocation">
<option value="">Select</option>
<option value="North Carolina">North Carolina</option>
<option value="South Carolina">South Carolina</option>
<option value="Maine">Maine</option>
</select>
</div>
</div>
</section>
CodePudding user response:
You have two errors:
- The closing parenthesis and semicolon (
);
) for the call toaddEventListener
is placed after the closing curly brace (}
) for yourfor
loop instead of after the closing curly brace for your event handler function:
for(i=0; i < userLocation.length; i ) {
userLocation[i].addEventListener('change', function() {
if(userLocation[i].value === "North Carolina") {
alert('True');
}
} // <-- ); should be here
}); // <-- ); is here
- The indexing variable in your
for
loop uses the defaultvar
scope/definition which will cause all listeners to close around the last value (meaning all listeners will use the last listener'sselect
'svalue
. See JavaScript closure inside loops – simple practical example for more. You can fix this by usinglet i = 0
instead of justi = 0
;
Here's your code with those two things fixed:
let userLocation = document.querySelectorAll('#userLocation');
for (let i=0; i < userLocation.length; i ) {
userLocation[i].addEventListener('change', function() {
if(userLocation[i].value === "North Carolina") {
alert('True');
}
});
}
<section id="users">
<div >
<div >
<h3>Frank</h3>
<label>Location:</label>
<select id="userLocation">
<option value="">Select</option>
<option value="North Carolina">North Carolina</option>
<option value="South Carolina">South Carolina</option>
<option value="Maine">Maine</option>
</select>
</div>
<div >
<h3>Dan</h3>
<label>Location:</label>
<select id="userLocation">
<option value="">Select</option>
<option value="North Carolina">North Carolina</option>
<option value="South Carolina">South Carolina</option>
<option value="Maine">Maine</option>
</select>
</div>
<div >
<h3>Jimmy</h3>
<label>Location:</label>
<select id="userLocation">
<option value="">Select</option>
<option value="North Carolina">North Carolina</option>
<option value="South Carolina">South Carolina</option>
<option value="Maine">Maine</option>
</select>
</div>
<div >
<h3>Bob</h3>
<label>Location:</label>
<select id="userLocation">
<option value="">Select</option>
<option value="North Carolina">North Carolina</option>
<option value="South Carolina">South Carolina</option>
<option value="Maine">Maine</option>
</select>
</div>
</div>
</section>
A couple other things:
You should try to avoid duplicate
id
values in the same DOM. WhilequerySelectorAll('#userLocation')
works,id
values should be unique. You can use a class for the same purpose and classes don't have to be unique.You can avoid the
number
-based loop variable entirely by usingArray#forEach()
which allows you to close over the actual element reference instead of an index in thequerySelectorAll
collection.
Here's a sample with both adjustments:
let userLocation = document.querySelectorAll('.userLocation');
userLocation.forEach(l => {
l.addEventListener('change', function () {
if (l.value === "North Carolina") {
alert('True');
}
});
});
<section id="users">
<div >
<div >
<h3>Frank</h3>
<label>Location:</label>
<select >
<option value="">Select</option>
<option value="North Carolina">North Carolina</option>
<option value="South Carolina">South Carolina</option>
<option value="Maine">Maine</option>
</select>
</div>
<div >
<h3>Dan</h3>
<label>Location:</label>
<select >
<option value="">Select</option>
<option value="North Carolina">North Carolina</option>
<option value="South Carolina">South Carolina</option>
<option value="Maine">Maine</option>
</select>
</div>
<div >
<h3>Jimmy</h3>
<label>Location:</label>
<select >
<option value="">Select</option>
<option value="North Carolina">North Carolina</option>
<option value="South Carolina">South Carolina</option>
<option value="Maine">Maine</option>
</select>
</div>
<div >
<h3>Bob</h3>
<label>Location:</label>
<select >
<option value="">Select</option>
<option value="North Carolina">North Carolina</option>
<option value="South Carolina">South Carolina</option>
<option value="Maine">Maine</option>
</select>
</div>
</div>
</section>