I need dynamic script which detects radio button by name and replace it with select element.
These radio buttons can be anywhere in the DOM. I need to distinguish using names and replace it with relevant select-box.
For example input :
<tr>
<td>
Car Type
</td>
<td>
<input type="radio" name="Type"> Old
<input type="radio" name="Type"> New
</td>
</tr>
Required output :
<tr>
<td>
Car Type
</td>
<td>
<select name="Type">
<option value="Old">Old</option>
<option value="New">New</option>
</select>
</td>
</tr>
I tried something, but no success (My Script)
//removing all radio
var radios = document.getElementsByName(name);
for (var i = 0; i < radios.length; i++) {
radios[i].parentNode.removeChild(radios[i]);
}
//replaceing wih select
var selectList = document.createElement("select");
selectList.name = name;
radios[0].parentNode.appendChild(selectList);
//Create and append the options
for (var i = 0; i < data.length; i++) {
var option = document.createElement("option");
option.value = data[i];
option.text = data[i];
selectList.appendChild(option);
}
Plunker full example
I changed a bit your code to make it clearer and functionnal.
I changed document.getElementsByName to document.querySelectorAll in order to have a static NodeList, otherwise you would have to use a while since the collection will reflect changes made when a radio button is removed. You could also remove them later but it would be multiplying for-loops for no reason. Moreover querySelectorAll('input[type="radio"]... focus only on radio buttons, avoiding errors.
I got the label text using .nextSibling to affect it to the option and used trim to remove useless white space and line breaks.
I used remove to remove the radios and labels from the DOM.
As a side note, radio buttons are meant to have a value. You shouldn't rely on the label IMO.
function replaceRadiosBySelect(name) {
var selectList = document.createElement('select'),
radios = document.querySelectorAll('input[type="radio"][name="' + name + '"]');
if (radios.length > 0) {
selectList.name = name;
radios[0].parentNode.appendChild(selectList);
for (var i = 0; i < radios.length; i++) {
var label = radios[i].nextSibling,
option = document.createElement('option');
option.value = option.text = label.data.trim();
selectList.appendChild(option);
radios[i].remove();
label.remove();
}
}
}
replaceRadiosBySelect('Type');
<tr>
<td>
Car Type
</td>
<td>
<input type="radio" name="Type"> Old
<input type="radio" name="Type"> New
</td>
</tr>
Related
I am trying to change 3 text inputs to selects and append options underneath, but the input stays the same.
Here is my js code
let inputSelect=['protons2', 'atomic2', 'neutrons'];
for(let i = 0; i < inputSelect; i++){
document.getElementById(inputSelect[i]).setAttribute("type","select")
const opt = document.createElement("option");
opt.textContent = "orbit";
document.getElementById(inputSelect[i]).appendChild(opt)
}
here is my html code
<label id="pro2" for = "protons2"></label>
<input type = "text" id = "protons2" class='input' autocomplete="off" placeholder="Answer">
<label id="at2" for = "atomic2"></label>
<input type = "text" id = "atomic2" class='input' autocomplete="off" placeholder="Answer">
<label id="new" for = "neutrons"></label>
<input type = "text" id = "neutrons" class='input' autocomplete="off" placeholder="Answer">
The input type does change according to the css selector input[type=text], as none of the styles of that selector is applied once the text input changes to a select input.
It still stays a text input though.
1 - You have to use the length value in the array to use it in the for.
2 - You can't convert an input text into a select. You have to replace the element.
let inputSelect = ['protons2', 'atomic2', 'neutrons'];
for (let i = 0; i < inputSelect.length; i++) {
select_aux = document.createElement("select");
select_aux.id = inputSelect[i];
document.getElementById(inputSelect[i]).replaceWith(select_aux);
const opt = document.createElement("option");
opt.textContent = "orbit";
document.getElementById(inputSelect[i]).appendChild(opt);
}
<input type="text" id="protons2">
<input type="text" id="atomic2">
<input type="text" id="neutrons">
There is no type attribute that is select, instead you need to make a select element.
Note: You forgot to add .length to inputSelect in your loop.
<select>
<option>Option 1</option>
</select>
Creating a select with JS
document.insertAdjacentHTML('beforeend', '<select>
<option>Option 1</option>
</select>')
let inputSelect=['protons2', 'atomic2', 'neutrons'];
for(let i = 0; i < inputSelect.length; i++){
const opt = document.createElement("option");
opt.textContent = "orbit";
document.getElementById(inputSelect[i]).appendChild(opt)
}
<select id="protons2">
</select>
<select id="atomic2">
</select>
<select id="neutrons">
</select>
I'm trying to learn how to dynamically add n select elements with options to an HTML form using vanilla JS. There are a few related Stack Overflow questions but these focus on instances where you know how many select elements there will be 1 2. I don't know exactly how many select elements will need to be generated; I need to generate them dynamically. I started simpler by learning how to dynamically generate regular text fields:
for (let i = 0; i < res[0].length; i++) {
container.appendChild(document.createTextNode(res[0][i]));
var input = document.createElement("input");
input.type = res[1][i];
input.name = res[0][i];
input.classList.add("input");
container.appendChild(input);
}
where
var res = [["textfield 1","text field 2"],["text","text"],[["none"],["none"]]];
That works fine for regular text fields so then I started working on select elements:
for (let i = 0; i < res[0].length; i++) {
var select = document.getElementById("mySelect");
var options = res[2][i];
for(var j = 0; j < options.length; j++) {
var optn = options[j];
var elmnt = document.createElement("option");
elmnt.name = res[0][i];
elmnt.classList.add("input")
elmnt.text = optn;
elmnt.value = optn;
select.id = res[0][i];
select.add(elmnt);
}
}
where
var res = [["country","language"],["li","li"],[["Canada","Mexico","United States"],["English","Spanish","English"]]];
I thought that using select.id = res[0][i]; would accomplish what I want but I think that's just creating separate sets of options and not actually creating separate select elements. Right now, this yields the first select with countries but the second select for languages doesn't appear.
Here's the HTML:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<form name="myTest" id="myTest_frm">
<div id="container"/>
<select multiple = true id="mySelect">
<option>Select an option</option>
</select>
</div>
<br><input type="button" value="Submit" onClick="test()">
</form>
I know that I can modify the HTML to include multiple select tags to make this work as shown below but that requires that I pre-know how many select elements I'll need. Again, I don't pre-know how many select elements there will be, i.e. res[0].length could be two as shown in the examples or it could be any other length.
Working but not dynamic:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<form name="myTest" id="myTest_frm">
<div id="container"/>
<select multiple = true id="mySelect">
<option>Select an option</option>
</select>
<select multiple = true id="mySelect">
<option>Select an option</option>
</select>
</div>
<br><input type="button" value="Submit" onClick="test()">
</form>
First you need establish the format of your dynamic data.
var res = [["country","language"],["li","li"],[["Canada","Mexico","United States"],["English","Spanish","English"]]]
This is a difficult to work with format, as it's "hard-coded" position of the list in the array (what's the li are for?)
For your purpose you probably should go with an object which contains list of options (array).
This way, you can use object's key for select name:
var res = {
country: ["Mexico" /*default*/, "Canada","Mexico","United States"],
language: ["French" /*default*/, "English","Spanish","French"]
}
const container = document.getElementById("container");
for(let i in res)
{
const select = document.createElement("select");
select.value = res[i].shift(); //select default item, by removing first item from the array
container.appendChild(select);
for(let o = 0; o < res[i].length; o++)
{
const option = document.createElement("option");
option.textContent = res[i][o];
option.value = res[i][o];
select.appendChild(option);
};
}
<form name="myTest" id="myTest_frm">
<div id="container"></div>
<br><input type="button" value="Submit" onClick="test()">
</form>
Hello to everyone i need get the number which someone can write in input and than show the option with the same number
var btn = document.getElementById("myBtn");
btn.addEventListener("click", funct);
function funct(){
var input = document.getElementById("myInput");
var select = document.getElementById("mySelect");
var options = select.options;
for( var i = 0; i < options.length; i++ ){
options[i].selected = input.value;
}
}
<select id="mySelect">
<option>one</option>
<option>second</option>
<option>third</option>
</select> <br> <br>
<input type="text" id="myInput"> <br> <br>
<button id="myBtn">Button</button>
All you need to do is clear out any selected attributes that may have previously been set and set selected on the option with an index that is supplied by the user as long as that input is a valid index for the select.
And, since indexes are always numbers, it makes sense to use input type='number' so that only numeric data can be entered in the first place.
// Get your DOM references just once, not every time the button is clicked:
var input = document.getElementById("myInput");
var select = document.getElementById("mySelect");
var btn = document.getElementById("myBtn");
btn.addEventListener("click", funct);
function funct(){
// If the user's input is within the range of select indexes
if(input.value >= 0 && input.value < select.options.length){
// Loop over all the options and remove any previously selected ones
for( var i = 0; i < select.options.length; i++ ){
select.options[i].selected = false;
}
// Select the option that matches the user's input for an index
select.options[input.value].selected = true;
}
}
<select id="mySelect">
<option value="">Make a Selection</option>
<option>one</option>
<option>second</option>
<option>third</option>
</select> <br> <br>
<input type="number" min="0" id="myInput"> <br> <br>
<button id="myBtn">Button</button>
When people selected the dropdown and then the checkbox will be auto checked if the selected value of dropdown is not empty. But I met "sel[i] is undefined" error.
Javascript part:
var chk = document.getElementsByTagName("input");
var sel = document.getElementsByTagName("select");
for (var i=0; i< sel.length; i++) {
sel[i].onchange = function(){
if (sel[i].value !== ''){
chk[i].checked = true;
}
else{
chk[i].checked = false;
}
};
}
HTML part:
<form name="form1">
<div class="container">
<input id='checkbox_id1' name='checkbox_id1' type='checkbox' value='1' /></label>
Select
<label>
<select id="select_id1" name="select">
<option value=""></option>
<option value="111">111</option>
<option value="222">222</option>
</select>
</label>
<hr>
<input id='checkbox_id2' name='checkbox_id1' type='checkbox' value='1' /></label>
Select
<label>
<select id="select_id2" name="select">
<option value=""></option>
<option value="111">111</option>
<option value="222">222</option>
</select>
</label>
</div>
jsfiddle: http://jsfiddle.net/planetoid/GwEuu/
Your value of i is not what you think it is because the for loop has run to completion before any of the event handlers are actually called, thus i is the value at the end of the forloop.
To capture the appropriate value of i for each event handler, you can use a self executing function like this that captures it in a closure for each specific event handler:
var chk = document.getElementsByTagName("input");
var sel = document.getElementsByTagName("select");
for (var i = 0; i < sel.length; i++) {
(function(i) {
sel[i].onchange = function(){
chk[i].checked = sel[i].value !== '';
}
})(i);
}
Working demo: http://jsfiddle.net/jfriend00/yds6w/
FYI, I've also simplified the .checked assignment code.
But, after looking at your code a bit, I believe this may be a better way of implementing it that doesn't need the self executing function. Rather than rely on perfectly parallel arrays of checkboxes and input tags, this just converts the ID of the select to the ID of the corresponding checkbox and uses this to reference the select element. So, i is not used in the event handler.
var sel = document.getElementsByTagName("select");
for (var i = 0; i < sel.length; i++) {
sel[i].onchange = function(){
var checkboxId = this.id.replace("select_", "checkbox_");
document.getElementById(checkboxId).checked = this.value !== '';
}
}
Working demo: http://jsfiddle.net/jfriend00/g3UQG/
I see jfriend00 beat me to it, but you can also use this syntax to achieve the same effect (I also shortened the inner code):
var chk = document.getElementsByTagName("input"),
sel = document.getElementsByTagName("select");
for (var i=0; i< sel.length; i++) {
sel[i].onchange = (function (i) {
return function(){
chk[i].checked = sel[i].value !== '';
};
}(i));
}
I have 2 listboxes and when a button is pressed I need to move an option from one to another.
I did this:
HTML
<table border="1" cellpadding="5">
<tr>
<td> Un-Selected <br />
<select multiple="multiple" id="selectBoxOne" size="5" class="selectListBox">
<option value="0" id="multiple0">Option 0</option>
<option value="1" id="multiple1">Option 1</option>
<option value="2" id="multiple2">Option 2</option>
<option value="3" id="multiple3">Option 3</option>
<option value="4" id="multiple4">Option 4</option>
<option value="5" id="multiple5">Option 5</option>
</select>
<br />
<input type="checkbox" id="selectAllFirst" />Select All or Ctrl+Click
</td>
<td>
<div onclick="move('left');">
<< </div>
<div onclick="move('right');"> >></div>
</td>
<td> Selected <br />
<select name="policyCode" multiple="multiple" id="selectBoxSecond" size="5" class="selectListBox"></select>
<br />
<input type="checkbox" id="selectAllSecond" />Select All or Ctrl+Click
</td>
</tr>
</table>
javascript:
// Declare elements
var selectOptions = Array();
selectOptions[0] = "Option 0";
selectOptions[1] = "Option 1";
selectOptions[2] = "Option 2";
selectOptions[3] = "Option 3";
selectOptions[4] = "Option 4";
selectOptions[5] = "Option 5";
// function to move an element from a box to the other
function move(sens)
{
if (sens == "right")
{
var selObj = document.getElementById('selectBoxOne');
var chkAll = document.getElementById("selectAllFirst")
var destination = document.getElementById("selectBoxSecond");
}
else
{
var selObj = document.getElementById('selectBoxSecond');
var chkAll = document.getElementById("selectAllSecond")
var destination = document.getElementById("selectBoxOne");
}
var selectedArray = new Array();
var i;
var count = 0;
if (chkAll.checked == 1)
{
for (i = 0; i<selectOptions.length; i++)
{
selectedArray[i] = i;
}
}
else
{
for (i=0; i<selObj.options.length; i++) {
if (selObj.options[i].selected) {
selectedArray[count] = selObj.options[i].value;
count++;
}
}
}
for (i = 0; i < selectedArray.length; i++)
{
var optionTag = document.createElement("option");
id = selectedArray[i];
optionTag.innerHTML = selectOptions[id];
optionTag.value = id;
optionTag.id = "multiple"+id;
destination.appendChild(optionTag);
var rmv = document.getElementById("multiple"+id);
rmv.parentNode.removeChild(rmv);
}
}
Now: The script works great from moving from left box to the right box. But when I try the other way around it kind of crashes. No error returned but I know for sure is the removal part (if I comment it it works fine... except that it generates duplicates since there is no removal of the moved option).
To be more specific, this 2 lines:
var rmv = document.getElementById("multiple"+id);
rmv.parentNode.removeChild(rmv);
Since there is no error returned, I don't know how to fix this.
That's a very long winded way of doing things! :-)
You can move an option from one select to another simply by assigning it as a child of the other select, e.g.
function move(sens) {
var i, sourceSel, targetSel;
if (sens == 'right') {
sourceSel = document.getElementById('selectBoxOne');
targetSel = document.getElementById('selectBoxSecond');
} else {
sourceSel = document.getElementById('selectBoxSecond');
targetSel = document.getElementById('selectBoxOne');
}
i = sourceSel.options.length;
while (i--) {
if (sourceSel.options[i].selected) {
targetSel.appendChild(sourceSel.options[i]);
}
}
}
will move all the selected options from one to the other. Note that the while loop goes backwards because the options collection is a live NodeList, so as you remove options is shortens the collection. If you go forwards through it you need to update the index and length as you go (so going backward is simpler).
You may want to include some kind of ordering or sorting (e.g. by value or text).
I guess if the selectAll checkbox is checked you'll just move them all, or (preferably) you could use a click listener to select/deselect all the appropriate optoins when it's clicked independent of the move function.
An id has to be unique, or it won't work properly. As you add the new option before removing the original, you get two options with the same id, and you won't find the original option when you want to remove it.
Just swap these three lines around, so that you remove the option before adding the new one. From this:
destination.appendChild(optionTag);
var rmv = document.getElementById("multiple"+id);
rmv.parentNode.removeChild(rmv);
to this:
var rmv = document.getElementById("multiple"+id);
rmv.parentNode.removeChild(rmv);
destination.appendChild(optionTag);