Problems with HTML and javascript dynamic table

后端 未结 1 945
天命终不由人
天命终不由人 2021-01-26 11:31

I am facing problems in: 1) the function saveRow does not save the row. I get this error: Uncaught TypeError: Cannot set property name of undefined at at saveRow at HTMLIn

相关标签:
1条回答
  • 2021-01-26 11:52

    I refactored a bit your code and created a new jsfiddle. You can refactor it more and more, and if possible to insert jQuery in your project, you will simply it a lot more.

    So few notes:

    1) Keep you model up to date with your UI changes. In the before sample you were manipulating HTML but you were not updating the array model

    2) Try to keep your common code in functions, in order to avoid repetitions. For example I moved the logic for creating row inside a function, and just calling that function every time that you need to create a new row (for displaying at the beginning and when clicking add row)

    3) When you call your functions in the row, pass also the current HTML element. You can pass it in order to know which current HTML element has been clicked, so that you can easily manipulate that row.

    4) Use two tbodies. One for the data and another one for the actions. It makes easier to distinct data from actions, avoiding to repeat every time also that row for actions

    And few other things that you can check alone with the code.

    You have to manage just the logic of disabling the buttons in the right operations, in order to avoid for example to click edit again when editing, but it would be a good exercise to do it yourself :)

    Here the sample:

    var myArray = [{
      "name": "aaa",
      "level": "A"
    }, {
      "name": "bbb",
      "level": "B"
    }, {
      "name": "ccc",
      "level": "C"
    }];
    
    function createDataRow(el, ind) {
      var row = document.createElement('tr');
      row.id = 'row-' + ind;
      var cell1Content = `
      	<div class="name-content">${el.name}</div>
        <input class="name-edit" type="text" id="name-text-${ind}" value="${el.name}" style="display:none;">
      `;
      
      var cell2Content = `
      	<div class="level-content">${el.level}</div>
      	<select class="level-edit" id="levels-list-${ind}" style="display:none;">
          <option value="A">A</option>\
          <option value="B">B</option>\
          <option value="C">C</option>\
        </select>
      `;
      
      var cell3Content = `
        <input type="button" id='edit_button" + i + "' value="Edit" class="edit" onclick="editRow(this, ${ind})">
        <input type="button" id='save_button" + i + "' value="Save" class="save" onclick="saveRow(this, ${ind})">
        <input type="button" value="Delete" class="delete" onclick="deleteRow(this, ${ind})">
      `;
      var cell1 = row.insertCell(0);
      var cell2 = row.insertCell(1);
      var cell3 = row.insertCell(2);
      
      cell1.innerHTML = cell1Content;
      cell2.innerHTML = cell2Content;
      cell3.innerHTML = cell3Content;
      
      document.getElementById('table-data').appendChild(row);
    }
    
    function displayData() {
      myArray.forEach(function(el, ind) {
      	createDataRow(el,ind);
      });
    }
    
    function deleteRow(el, ind) {
    	el.parentElement.parentElement.parentElement.removeChild(el.parentElement.parentElement); 
      myArray.splice(ind, 1);
    }
    
    function addRow(){
      event.preventDefault();
      var newEl = {
      	"name": document.getElementById("name-text").value,
        "level": document.getElementById("levels-list").value
      };
      myArray.push(newEl);
      createDataRow(newEl, myArray.length - 1);
      document.getElementById("name-text").value = '';
      document.getElementById("levels-list").value = 'A';
    }//end addRow
    
    function editRow(el, ind)
    {
    	var currentRow = el.parentElement.parentElement;
      
      currentRow.cells[0].getElementsByClassName("name-content")[0].style.display = 'none';
      currentRow.cells[0].getElementsByClassName("name-edit")[0].style.display = 'block';
      
      currentRow.cells[1].getElementsByClassName("level-content")[0].style.display = 'none';
      currentRow.cells[1].getElementsByClassName("level-edit")[0].value = myArray[ind].level;
      currentRow.cells[1].getElementsByClassName("level-edit")[0].style.display = 'block';
    }
     //end deleteRow
    
    function saveRow(el, ind)
    {
    	var currentRow = el.parentElement.parentElement;
      
      var nameContent = currentRow.cells[0].getElementsByClassName("name-content")[0];
      var nameEdit = currentRow.cells[0].getElementsByClassName("name-edit")[0];
      nameContent.innerHTML = nameEdit.value;
      nameContent.style.display = 'block';
      nameEdit.style.display = 'none';
      
      var levelContent = currentRow.cells[1].getElementsByClassName("level-content")[0];
      var levelEdit = currentRow.cells[1].getElementsByClassName("level-edit")[0];
      levelContent.innerHTML = levelEdit.value;
      levelContent.style.display = 'block';
      levelEdit.style.display = 'none';
      
      myArray[ind].name = nameEdit.value;
      myArray[ind].level = levelEdit.value;
    }//end saveRow
    
    var addButton=document.getElementById("add-button");
    addButton.addEventListener('click', addRow, false);
    displayData();
    <body>
      <div id="wrapper">
        <table align='center' cellspacing=2 cellpadding=5 id="data_table" border=1>
          <thead>
            <tr>
              <th>Name</th>
              <th>Level</th>
              <th>Action</th>
            </tr>
          </thead>
          <tbody id="table-data">
          </tbody>
          <tbody id="table-rows">
            <tr>
              <td><input type="text" id="name-text"></td>
              <td>
                <select name="levels-list" id="levels-list">
                  <option value="A" id="option-1">A</option>
                  <option value="B" id="option-2">B</option>
                  <option value="C" id="option-3">C</option>
                </select>
              </td>
              <td><input type="button" class="add" value="Add Row" id="add-button"></td>
            </tr>
          </tbody>
        </table>
      </div>
    </body>

    And here the jsfiddle (this time saved :D ):

    https://jsfiddle.net/u0865zaa/8/

    I hope it helps. For any queries let me know.

    0 讨论(0)
提交回复
热议问题