javascript - 如何动态更新html下拉列表值
问题描述
我有一个能够添加新列并将新组添加到 html 表的脚本。目前只有下拉列表的最新列能够从值中获取最新<p>
值。只有新添加的列才能获得最新的更新值。
当我向<p>
and添加一个新组时add column
,下拉列表能够获取该值test1
。
当我添加另一个组名test2
并添加新列时,最新列Group2
能够获得最新值(test2)
但是,当我单击时Group1
,下拉列表没有最新值test2
,仅显示test1
。那么如何让所有下拉列表从
function createSelectEl(values) {
var select = document.createElement("select");
select.name = "group1";
select.id = "groupId"
// 1st option
var option = document.createElement("option");
option.text = 'Select One';
select.appendChild(option);
for (const val of values) {
var option = document.createElement("option");
option.value = val;
option.text = val;
select.appendChild(option);
}
return select;
}
let groupNum = 1;
const tableEl = document.getElementById('member_table');
// append column to the HTML table
function appendColumn() {
// open loop for each row and append cell
for (let i = 0; i < tableEl.rows.length; i++) {
const values = ["IT", "Cleaning", "Accountant"];
const myP = document.querySelector('p#myP');
var categories = myP.innerText.split(',');
for (let j = 0; j < categories.length; j++) {
values.push(categories[j]);
}
createCell(tableEl.rows[i].insertCell(tableEl.rows[i].cells.length), createSelectEl(values), 'col');
// createCell(tableEl.rows[i].insertCell(tableEl.rows[i].cells.length), i, 'col');
}
tableEl.rows[0].querySelector('td:last-child').textContent = 'Group' + groupNum;
groupNum++;
}
// create DIV element and append to the table cell
function createCell(cell, text, style) {
var div = document.createElement('div'); // create DIV element
//txt = document.createTextNode(text); // create text node
// div.appendChild(txt); // append text node to the DIV
div.appendChild(text);
div.setAttribute('class', style); // set DIV class attribute
div.setAttribute('className', style); // set DIV class attribute for IE (?!)
cell.appendChild(div); // append DIV to the table cell
}
const submit = document.querySelector('button');
const input = document.querySelector('input');
const select = document.querySelector('select');
const myP = document.querySelector('p#myP');
submit.addEventListener('click', function(e) {
const values = input.value.split(',');
if (myP.innerText == '') {
myP.innerText = values;
} else {
myP.innerText += ', ' + values;
}
});
table {
font-family: arial, sans-serif;
border-collapse: collapse;
width: 100%;
}
td,
th {
border: 1px solid #dddddd;
text-align: left;
padding: 8px;
}
tr:nth-child(even) {
background-color: #dddddd;
}
<h2>HTML Table</h2>
<h2>HTML Table</h2>
<table id="member_table">
<tr>
<th>Company</th>
<th>Contact</th>
<th>Country</th>
</tr>
<tr>
<td>Alfreds Futterkiste</td>
<td>Maria Anders</td>
<td>Germany</td>
</tr>
<tr>
<td>Centro comercial Moctezuma</td>
<td>Francisco Chang</td>
<td>Mexico</td>
</tr>
<tr>
<td>Ernst Handel</td>
<td>Roland Mendel</td>
<td>Austria</td>
</tr>
<tr>
<td>Island Trading</td>
<td>Helen Bennett</td>
<td>UK</td>
</tr>
<tr>
<td>Laughing Bacchus Winecellars</td>
<td>Yoshi Tannamuri</td>
<td>Canada</td>
</tr>
<tr>
<td>Magazzini Alimentari Riuniti</td>
<td>Giovanni Rovelli</td>
<td>Italy</td>
</tr>
</table>
<h1>Existing Group</h1>
<p>IT, Cleaning, Accountant</p>
<h1>Add New Group</h1>
<p id="myP"></p>
<input type="tel" id="group" name="group" placeholder="enter group name">
<br><br>
<button type="button" class="btn btn-primary btn-sm">Submit</button>
<button onclick="javascript:appendColumn()">Add column</button>
解决方案
可以轻松克隆现有的 DOM 节点并调用父节点来替换子节点,因此对于添加的每个新表列,可以创建一个新菜单,然后克隆 - 任何现有菜单都将被替换 - 因此所有菜单将显示任何新增加的工作/专业。
与其读取 dom 节点的 textContent 来生成工作列表,不如使用一个不起眼的变量来跟踪工作/职业——然后每次使用输入添加新工作时都会更新这个相同的数组变量。
(function(){
const d=document;
const q=(e,n=d)=>n.querySelector(e);
const qa=(e,n=d)=>n.querySelectorAll(e);
const professions=[ 'IT', 'Cleaning', 'Accountant','Ferret Fumbler', 'Mouse Mauler' ];
const tbl=q('#member_table');
const form=d.forms.add;
const group=form.group;
const bttnsub=form.sub;
const bttnaddcol=form.addcol;
const bttnaddrow=form.addcom;
/*
utility to add new DOM elements
t: type ~ the DOM node type/tag - defaault:div
a: attributes ~ the attributes to apply to the new node
p: parent ~ the DOM node to which this new node will be appended - default:null
*/
const create=function(t,a={},p=null){
let el = ( typeof( t )=='undefined' || t==null ) ? d.createElement( 'div' ) : d.createElement( t );
let _arr=['innerHTML','innerText','html','text'];
for( let x in a ) if( a.hasOwnProperty( x ) && !~_arr.indexOf( x ) ) el.setAttribute( x, a[ x ] );
if( a.hasOwnProperty('innerHTML') || a.hasOwnProperty('html') ) el.innerHTML=a.innerHTML || a.html;
if( a.hasOwnProperty('innerText') || a.hasOwnProperty('text') ) el.innerText=a.innerText || a.text;
if( p!=null ) typeof( p )=='object' ? p.appendChild( el ) : d.getElementById( p ).appendChild( el );
return el;
};
const createSelect=( name, values )=>{
let select=create('select',{name:name},null);
// create the 1st hidden & selected option
let opt=new Option('Please select','');
opt.setAttribute('hidden',true);
opt.setAttribute('disabled',true);
opt.setAttribute('selected',true);
// all the `options` will be appended in one hit
let options=[];
options.push( opt );
// add new options to the array
values.forEach( v=>{
options.push( new Option(v,v) );
});
// splat - add all the options
select.append( ...options );
return select;
};
const appendColumn=(e)=>{
let sel=createSelect('profession',professions);
let cell;
// replace existing menus with newly generated menu containing ALL professions.
qa('select',tbl).forEach(select=>{
select.parentNode.replaceChild( sel.cloneNode( true ), select );
});
// create the new cell and add new menu into each row.
qa('tr',tbl).forEach(tr=>{
let b=tr.classList.contains('headers');
let content=b ? 'Profession' : sel.cloneNode( true );
let node=b ? create('th',{},tr) : create('td',{},tr);
createCell( node, content, 'col' );
});
};
const appendRow=(e)=>{
let row=q('tr:last-of-type',tbl).cloneNode(true);
q('td:nth-of-type(1)',row).textContent=form.company.value;
q('td:nth-of-type(2)',row).textContent=form.contact.value;
q('td:nth-of-type(3)',row).textContent=form.country.value;
tbl.appendChild( row );
};
const createCell=(parent,content,style)=>{
let div=create('div',{'class':style},parent);
div.append(content);
return div;
};
const addprofession=()=>{
professions.push( group.value );
displayprofessions();
let sel=createSelect('profession',professions);
qa('select',tbl).forEach(select=>{
select.parentNode.replaceChild( sel.cloneNode( true ), select );
});
group.value='';
group.focus();
};
const displayprofessions=()=>{
q('section#existing p').textContent=professions.join(', ');
};
// add existing professions to displayed data
displayprofessions();
// add the event listeners
bttnaddcol.addEventListener('click',appendColumn);
bttnaddrow.addEventListener('click',appendRow);
bttnsub.addEventListener('click',addprofession);
})();
table {
font-family: monospace, arial, sans-serif;
border-collapse: collapse;
width: 100%;
}
td,
th {
border: 1px solid #dddddd;
text-align: left;
padding: 8px;
}
tr:nth-child(even) {
background-color: #dddddd;
}
input[type='text']{
display:block;
margin:0.25rem;
}
.bttns{
margin:1rem auto;
}
button{
margin:0.25rem 0 0.25rem 0.5rem;
}
<h2>HTML Table</h2>
<table id="member_table">
<tr class='headers'>
<th>Company</th>
<th>Contact</th>
<th>Country</th>
</tr>
<tr>
<td>Alfreds Futterkiste</td>
<td>Maria Anders</td>
<td>Germany</td>
</tr>
<tr>
<td>Centro comercial Moctezuma</td>
<td>Francisco Chang</td>
<td>Mexico</td>
</tr>
<tr>
<td>Ernst Handel</td>
<td>Roland Mendel</td>
<td>Austria</td>
</tr>
<tr>
<td>Island Trading</td>
<td>Helen Bennett</td>
<td>UK</td>
</tr>
<tr>
<td>Laughing Bacchus Winecellars</td>
<td>Yoshi Tannamuri</td>
<td>Canada</td>
</tr>
<tr>
<td>Magazzini Alimentari Riuniti</td>
<td>Giovanni Rovelli</td>
<td>Italy</td>
</tr>
</table>
<form name='add' method='post'>
<section id='existing'>
<h1>Existing Groups</h1>
<p></p>
</section>
<section id='new'>
<h1>Add New Group</h1>
<p></p>
</section>
<section class='bttns'>
<input type="text" name="group" placeholder="enter group name" />
<button type='button' name='sub' class='btn btn-primary btn-sm'>Save</button>
<button type='button' name='addcol'>Add column</button>
</section>
<section class='bttns'>
<input type="text" name="company" placeholder="enter Company name" value='Acme Inc' />
<input type="text" name="contact" placeholder="enter Contact name" value='Joe Blow' />
<input type="text" name="country" placeholder="enter Country name" value='UK' />
<button type='button' name='addcom'>Add Row</button>
</section>
</form>
推荐阅读
- node.js - 如果偏移量在文件范围内,为什么 Node.js 会抱怨 ERR_OUT_OF_RANGE?
- amazon-web-services - 如何优雅地关闭 Amazon ECS Fargate 任务?
- scala - 不使用var,在Scala中使静态值无效并稍后将其再次设置为新值的方法是什么
- haskell - Haskell - 如何将 Either 返回到我的自定义类型?
- reactjs - 使用 useEffect() 反应子级未在父状态更改时更新
- ruby - Ruby 错误:调用私有方法“执行”
- python-3.x - Tensorflow 2.3 -TypeError:获取参数 None 的类型无效
当使用 .get_session().run(tf.compat.v1.variables_initializer - selenium - 测试流媒体服务(如 selenium)
- java - Lucene 8 巴西葡萄牙语分析器中的奇怪标记化
- html - 有人可以帮助我或给我一些提示以使此页面具有响应性吗?