Как динамически обновлять значение выпадающего списка html

javascript #html

#javascript #HTML

Вопрос:

У меня есть скрипт, который может добавлять новый столбец и добавлять новую группу в таблицу html. В настоящее время только последний столбец выпадающего списка может получить последнее значение из <p> значения. Только новый добавленный столбец может получить последнее обновленное значение.

Когда я добавляю новую группу в <p> и 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> 

Комментарии:

1. Похоже, вы создаете select только при добавлении нового столбца. Если вы добавляете новую опцию в select, вам необходимо обновить все выборки во всех столбцах. Т.Е. Если вы нажмете на submit, получите все выборки и воссоздайте их параметры.

Ответ №1:

Можно легко клонировать существующий узел DOM и вызывать родительский узел для замены дочернего узла, чтобы с каждым добавленным новым столбцом таблицы можно было создавать одно новое меню, а затем клонировать — все существующие меню будут заменены — таким образом, во всех меню будут отображаться все недавно добавленные задания / профессии.

Вместо чтения textContent узла dom для создания списка заданий можно использовать скромную переменную для отслеживания заданий / профессий — эта же переменная массива обновляется каждый раз, когда добавляется новое задание с использованием входных данных.

 (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 ) amp;amp; !~_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 amp; 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> 

Комментарии:

1. Я выяснил, что если пользователь сначала добавит столбец, а затем только добавит имя группы, он все равно не сможет обновить последнее значение.