Reputation: 175
I have this simple bit of code. When the user chooses Others, an <input type=text>
should appear.
But it only works when there is only one value selected.
Users can randomly add in the same select
type, so the code can't be changed. For what I know, in javascript need to use foreach
.
So my question is, how to let each of the <input type=text>
appear in EACH of the select
elements instead of it only appearing in the first one.
function Pack(val){
var element=document.getElementById('otherpack');
if(val=='others')
element.style.display='block';
else
element.style.display='none';
}
<select name="Type[]" onchange='Pack(this.value);' required>
<option value="Orange">Orange</option>
<option value="Apple">Apple</option>
<option value="others">Others</option>
<input type="text" name="othermethod[]" id="otherpack" style="display:none"/>
</select>
<select name="Type[]" onchange='Pack(this.value);' required>
<option value="Orange">Orange</option>
<option value="Apple">Apple</option>
<option value="others">Others</option>
<input type="text" name="othermethod[]" id="otherpack" style="display:none"/>
</select>
<select name="Type[]" onchange='Pack(this.value);' required>
<option value="Orange">Orange</option>
<option value="Apple">Apple</option>
<option value="others">Others</option>
<input type="text" name="othermethod[]" id="otherpack" style="display:none"/>
</select>
Upvotes: 0
Views: 93
Reputation: 9084
I would prefer to make change
events into javascript side instead of making it in HTML
..
As suggested it is not good to use input
inside select
so make input outside of select box..
const selectBoxes = document.querySelectorAll('select');
function Pack(select) {
const selectedInput = select.nextElementSibling;
if(select.value === 'others')
selectedInput.style.display='block';
else
selectedInput.style.display='none';
}
selectBoxes.forEach(select => {
select.addEventListener('change', Pack.bind(this, select))
})
<select name="Type[]" required>
<option value="Orange">Orange</option>
<option value="Apple">Apple</option>
<option value="others">Others</option>
</select>
<input type="text" name="othermethod[]" id="otherpack" style="display:none"/>
<br>
<br>
<select name="Type[]" required>
<option value="Orange">Orange</option>
<option value="Apple">Apple</option>
<option value="others">Others</option>
</select>
<input type="text" name="othermethod[]" id="otherpack" style="display:none"/>
<br>
<br>
<select name="Type[]" required>
<option value="Orange">Orange</option>
<option value="Apple">Apple</option>
<option value="others">Others</option>
</select>
<input type="text" name="othermethod[]" id="otherpack" style="display:none"/>
Upvotes: 1
Reputation: 71
Have you tried giving them unique id
s? if you wanna have the same identifier in different elements, maybe use the class attribute instead.
Hope it helps, good luck !
edit: actually, now I see you're calling them with an id
that isn't unique. Give each of the text-inputs their own id
and it should work
id
s are meant to be unique in the code, so whenever you call your function it assumes that there is only one element with that id
Upvotes: 0
Reputation: 350147
id
attributes should have unique values, so your selector will always select the first match.
Secondly, input
elements are not allowed to be children of select
elements. select
elements can only have optgroup
or option
elements as children
It is also best practice to attach listeners via JavaScript code instead of onchange
attributes. You can listen at the document level ("event delegation") to avoid repeating several listeners (one per select
element).
Here is how it could work:
function Pack(e){
let select = e.target;
if (select.name !== "Type[]") return;
let element = select.nextElementSibling; // this finds the INPUT element
element.style.display = select.value === "others" ? "block" : "none";
}
document.addEventListener("change", Pack);
<select name="Type[]" required>
<option value="Orange">Orange</option>
<option value="Apple">Apple</option>
<option value="others">Others</option>
</select>
<input type="text" name="othermethod[]" style="display:none"/>
<br>
<select name="Type[]" required>
<option value="Orange">Orange</option>
<option value="Apple">Apple</option>
<option value="others">Others</option>
</select>
<input type="text" name="othermethod[]" style="display:none"/>
<br>
<select name="Type[]" required>
<option value="Orange">Orange</option>
<option value="Apple">Apple</option>
<option value="others">Others</option>
</select>
<input type="text" name="othermethod[]" style="display:none"/>
Upvotes: 0
Reputation: 3844
Here is my solution:
function Pack(v) {
var inputBox=v.nextSibling;
var selectedValue=v.options[v.selectedIndex].value;
if (selectedValue=="others") {
inputBox.style.display='block';
} else {
inputBox.style.display='none';
}
}
This should be the most stable solution.
Upvotes: 1