首页 > 解决方案 > 如何动态更新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>

标签: javascripthtml

解决方案


可以轻松克隆现有的 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>


推荐阅读