2017-05-26 51 views
0

我遇到了以下問題:1)saveRow函數不保存行。我得到這個錯誤:Uncaught TypeError: Cannot set property name of undefined at at saveRow at HTMLInputElement.onclick。 2)deleteRow不起作用。我收到類似的錯誤:Uncaught TypeError: Cannot set property 'innerHTML' of null。 3)在editRow中,我的字段變得可編輯,但使用之前保存的默認值。例如,列表總是A,B,C,這不是我想要的。我希望列表的初始值是之前選擇的值。 我正在做的事情應該是錯的。下面是代碼:HTML和JavaScript動態表的問題

HTML:

<html> 

<head> 
</head> 

<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-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> 
<script src="get-text.js"></script> 
</body> 

</html> 

腳本:

var myArray = [{ 
    "name": "aaa", 
    "level": "A" 
}, { 
    "name": "bbb", 
    "level": "B" 
}, { 
    "name": "ccc", 
    "level": "C" 
}]; 


display(); 

function display() { 
    var length = myArray.length; 
    var htmlText = ""; 

    for (var i = 0; i < length; i++) { 
    htmlText += 
     "<tr id='row" + i + "'>\ 
       <td>" + myArray[i].name + "</td>\ 
       <td>" + myArray[i].level + "</td>\ 
       <td>\ 
        <input type='button' id='edit_button" + i + "' value='Edit' class='edit' onclick='editRow("+i+")'> \ 
        <input type='button' id='save_button" + i + "' value='Save' class='save' onclick='save_row(" + i + ")'> \ 
        <input type='button' value='Delete' class='delete' onclick='delete_row(" + i + ")'>\ 
       </td>\ 
      </tr>"; 
    }//end loop 
    htmlText+= 
    "<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>"; 

    document.getElementById("table-rows").innerHTML = htmlText; 
}//end display 

var addButton=document.getElementById("add-button"); 
addButton.addEventListener('click', addRow, false); 

function addRow(){ 
    event.preventDefault(); 
    var newData= document.getElementById("name-text").value; 
    var newLevel = document.getElementById("levels-list").value; 

    var table = document.getElementById("data_table"); 
    var tableLength = (table.rows.length)-1; 
// console.log(tableLength); 
    var row = table.insertRow(tableLength).innerHTML= 
    "<tr id= 'row"+tableLength+"'>\ 
     <td id='name-text"+tableLength+"'>"+newData+"</td>\ 
     <td id='levels-list"+tableLength+"'>"+newLevel+"</td>\ 
     <td><input type='button' id='edit-button"+tableLength+"' value='Edit' class='edit' onclick='editRow("+tableLength+")'> \ 
      <input type='button' id='save-button"+tableLength+"' value='Save' class='save' onclick='saveRow("+tableLength+")'> \ 
      <input type='button' id= 'delete-button"+tableLength+"' value='Delete' class='delete' onclick='deleteRow("+tableLength+")'>\ 
     </td>\ 
    </tr>"; 

    document.getElementById("name-text").value=""; 
}//end addRow 

function editRow(no) 
{ 
    document.getElementById("edit-button"+no).disabled=true; 
    //document.getElementById("save-button"+no).style.display="block"; 

    var name=document.getElementById("name-text"+no); 
    var level=document.getElementById("levels-list"+no); 

    var nameData=name.innerHTML; 
    var levelData=level.innerHTML; 

    name.innerHTML="<input type='text' id='name_text"+no+"' value='"+nameData+"'>"; 
    level.innerHTML='<select id="levels-list'+no+'">\ 
         <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>' ; 

    document.getElementById("levels-list"+no).value = levelData; 
} 

function deleteRow(no) { 
    myArray.splice(no, 1); 
    document.getElementById("row"+no).innerHTML=""; 
    //display(); 
} //end deleteRow 

function saveRow(no) 
{ 
    myArray[no].name = document.getElementById("name-text"+no).value; 
    myArray[no].level = document.getElementById("levels-list"+no).value; 

    document.getElementById("row"+no).innerHTML = 
    "<tr id= 'row"+no+"'>\ 
    <td id='name-text"+no+"'>"+myArray[no].name+"</td>\ 
    <td id='levels-list"+no+"'>"+myArray[no].level+"</td>\ 
    <td><input type='button' id='edit-button"+no+"' value='Edit' class='edit' onclick='editRow("+no+")'> \ 
     <input type='button' value='Delete' class='delete' onclick='deleteRow("+no+")'>\ 
    </td>\ 
    </tr>"; 
}//end saveRow 

回答

0

我重構了一下你的代碼,並創建了一個新的jsfiddle。你可以對它進行更多的重構,並且如果可能的話在你的項目中插入jQuery,你會更加簡單。

這麼幾個注意事項:

1)保持你的模型最新的與你的用戶界面的變化。在之前的示例中,您正在操縱HTML,但未更新陣列模型

2)儘量讓您的通用代碼保留在函數中,以避免重複。 例如,我移動了在函數內部創建行的邏輯,並且每次需要創建一個新行時調用該函數(用於在開始時顯示並單擊添加行時)

3)當您致電你的行中的函數,也傳遞當前的HTML元素。您可以通過它來了解當前哪個HTML元素已被點擊,以便您可以輕鬆操作該行。

4)使用兩個tbodies。一個用於數據,另一個用於行動。它更容易從行動中區分出不同的數據,避免每次重複該行時的動作。

還有其他一些可以單獨使用代碼進行檢查的事情。

必須管理禁止在正確的操作按鈕的只是邏輯,以避免例如編輯時要再次單擊編輯,但是這將是一個很好的鍛鍊自己做:)

這裏的樣本:

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 = ` 
 
    \t <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 = ` 
 
    \t <div class="level-content">${el.level}</div> 
 
    \t <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) { 
 
    \t createDataRow(el,ind); 
 
    }); 
 
} 
 

 
function deleteRow(el, ind) { 
 
\t el.parentElement.parentElement.parentElement.removeChild(el.parentElement.parentElement); 
 
    myArray.splice(ind, 1); 
 
} 
 

 
function addRow(){ 
 
    event.preventDefault(); 
 
    var newEl = { 
 
    \t "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) 
 
{ 
 
\t 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) 
 
{ 
 
\t 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>

而這裏的jsfiddle(此時保存:d):

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

我希望它有幫助。對於任何疑問,請讓我知道。

+0

謝謝。但是,你所說的沒有任何真正的效果。您發佈的修改與我發佈的內容沒有什麼不同,並且不能解決問題。您提供的代碼鏈接不會運行。 – user7945230

+0

好的。編輯現在工作。但是你的鏈接中的代碼不是。沒有任何按鈕(保存,編輯,刪除)正在執行該功能。 – user7945230

+0

我沒有保存jsfiddle更新URL上的最新版本-.- – quirimmo