簡體   English   中英

從動態填充的表JavaScript中的特定行獲取特定單元格值

[英]Get specific cell value from specific row in dynamically populated table JavaScript

我的Web應用程序從JSON對象獲取值,並使用其值以及每行上的編輯和刪除按鈕填充表。 我希望我的腳本能夠知道哪些行編輯按鈕被按下,以及行的單元格值。

在格式化我的問題時,我在這個完全相同的問題上偶然發現了(我在決定詢問之前搜索了一個小時),但它沒有包含任何對我 有用的 解決方案: 獲取用Javascript點擊的行中的HTML單元格的值

HTML:

<div class="container">     
    <h4>Persons</h4>
    <div class="table-responsive">
        <table class="table table-striped" id="persons_table">
            <thead class="thead-dark">
                <tr>
                    <th scope="col">ID</th>
                    <th scope="col">Name</th>
                    <th scope="col">Email</th>
                    <th scope="col">Phone</th>
                    <th scope="col">Edit</th>
                    <th scope="col">Delete</th>
                </tr>
            </thead>
            <tbody>
                    //dynamically generated rows goes here
            </tbody>
        </table>
    </div>
    <button class="btn btn-sm btn-primary" id="addBtn">New person</button>
</div>

填充表格的功能:

function handlePersons(data){ //data is a response from an API (JSON)
    var table = document.getElementById('persons_table');
    data.forEach(function(object) {
        var tr = document.createElement('tr');
        tr.innerHTML = 
        '<td>' + object.ID + '</td>' +
        '<td>' + object.Info.Name + '</td>' +
        '<td>' + object.Info.Email + '</td>' +
        '<td>' + object.Info.PhoneNumber + '</td>' +
        '<td><p data-placement="top" data-toggle="tooltip" title="Edit">
        <button class="btn btn-primary btn-xs" id="editBtn" data-title="Edit" data-toggle="modal" data-target="#edit">
        <span class="fa fa-pencil"></span></button></p></td>' +
        '<td><p data-placement="top" data-toggle="tooltip" title="Delete">
        <button class="btn btn-danger btn-xs" data-title="Delete" data-toggle="modal" data-target="#delete">
        <span class="fa fa-trash"></span></button></p></td>';
        table.appendChild(tr);
        });
    }

萬一你需要它,這是我獲取JSON數據的ajax調用:

function getPersons(){
    var settings = {
            "async" : true,
            "crossDomain" : true,
            "url" : "...",
            "method" : "GET",
            "headers" : {
                "Content-Type" : "application/json",
                "Authorization": "...",
                "cache-control" : "no-cache"
            },
            "processData" : false,
            "data" : ""
        }
        return $.ajax(settings);
}

功能調用:

getPersons().done(handlePersons)

在實踐中它看起來像這樣: 在此輸入圖像描述

我的問題是,當我按下第一行的編輯按鈕時,我怎么能讓我的腳本知道它是被按下的特定行上的編輯按鈕,我怎么能以例如console.log來命名行(John) ? 這就是我嘗試過的:

$('#editBtn').on('click', () => {

    var par = $(this).parent().parent(); //to choose table row, also tried one 
                                         //and three .parent() because I don't 
                                         //quite understand this

    var namevalue = par.children("td:nth-child(2)").val(); //also tried with .text()
    console.log(namevalue); //.val = undefined and .text = empty string

});
$('#editBtn').on('click', () => { //also tried with onclick="function" 
                                  //on the button instead of
                                  //jQuery just in case

    var tr = $(this).closest('tr')
    var tdID = $(tr).find('td').eq(0).text();
    var tdName = $(tr).find('td').eq(1).text();
    var tdEmail = $(tr).find('td').eq(2).text();
    var tdPhone = $(tr).find('td').eq(3).text();

    console.log(tdName); //.text logs empty string, .val logs undefined again

});

@Cyber​​netic請求后的JSON數據。 對此進行了一些編輯,以便不顯示任何敏感信息,但仍應在我的代碼中生成相同的結果。

[
    {
        "CustomValues": {},
        "Comment": "Here is John",
        "Deleted": false,
        "ID": 1,
        "InfoID": 4,
        "Role": null,
        "StatusCode": null,
        "UpdatedAt": null,
        "UpdatedBy": null,
        "Info": {            
            "DefaultEmailID": 1,
            "DefaultPhoneID": 2,
            "Deleted": false,
            "ID": 3,
            "Name": "John",
            "PhoneNumber": "123-123-123",
            "Email": "john@mail.com"                      
        }
    },
    {
        "CustomValues": {},
        "Comment": "Here is Mike",
        "Deleted": false,
        "ID": 2,
        "InfoID": 6,
        "Role": null,
        "StatusCode": null,
        "UpdatedAt": null,
        "UpdatedBy": null,
        "Info": {            
            "DefaultEmailID": 3,
            "DefaultPhoneID": 4,
            "Deleted": false,
            "ID": 6,
            "Name": "Mike",
            "PhoneNumber": "321-321-321",
            "Email": "mike@mail.com"                      
        }
    }   
]

首先,您為多個元素提供相同的id #editBtn。 這是不正確的,id在HTML文檔的范圍內必須是唯一的。

其次,我假設您只將editBtn的click事件放在頁面加載上。 但是由於您使用AJAX生成這些元素,因此click事件不會綁定在它們上面。 您需要在AJAX數據的成功/完成時調用$('#editBtn')。on('click',function())事件。

第三,這個:

var par = $(this).parent().parent();

不管用。 editBtn在ap內,所以$('#editBtn')。parent()。parent()是td,而不是tr。 您需要再添加一個父級,盡管嘗試檢索數據,以這種方式遍歷DOM是一種不好的做法,可能會導致代碼中斷和維護更加困難。 最好使用特定的ID或數據屬性。

謝謝你的數據。

只需將數據添加到每個動態生成的行 (tr元素):

function handlePersons(data){ 
    var table = document.getElementById('persons_table');
    data.forEach(function(object) {
        var tr = document.createElement('tr');
        tr.setAttribute('data-id', object.ID) // adding data
        tr.setAttribute('data-name', object.Info.Name) // adding data
        tr.setAttribute('data-email', object.Info.Email) // adding data
        tr.setAttribute('data-phone', object.Info.PhoneNumber) // adding data
        tr.innerHTML = 
        '<td>' + object.ID + '</td>' +
        '<td>' + object.Info.Name + '</td>' +
        '<td>' + object.Info.Email + '</td>' +
        '<td>' + object.Info.PhoneNumber + '</td>' +
        `<td><p data-placement="top" data-toggle="tooltip" title="Edit">
        <button class="btn btn-primary btn-xs" id="editBtn" data-title="Edit" data-toggle="modal" data-target="#edit">
        <span class="fa fa-pencil"></span></button></p></td>' +
        '<td><p data-placement="top" data-toggle="tooltip" title="Delete">
        <button class="btn btn-danger btn-xs" data-title="Delete" data-toggle="modal" data-target="#delete">
        <span class="fa fa-trash"></span></button></p></td>`;
        table.appendChild(tr);
        });
    }

...然后使用編輯按鈕在表格中的位置來定位其父行並根據需要讀取其數據

$('.btn-xs').click(function() {
    $(this).parents('tr').css('background', 'pink')
    id = $(this).parents('tr').data('id')
    name = $(this).parents('tr').data('name')
    email = $(this).parents('tr').data('email')
    phone = $(this).parents('tr').data('phone')
    alert(id + '\n' + name + '\n' + email + '\n' + phone)
})

結果

在此輸入圖像描述

這是小提琴

由於使用了jQuery,因此您應該遵循兩個未記錄的規則:

  1. 除非需要(例如Bootstrap data-屬性),否則不要使用id,使用class。 注意:下面的演示演示了我們如何獨家使用類,不再依賴於id。

  2. 不要使用事件屬性<button 的onclick = “FNC()” >

第一個規則適用於演示,第二個規則與剛剛添加的完整性無關。 此外,ID必須是唯一的 - 提供的OP代碼生成重復button#editBtn

動態添加的元素不能綁定到事件,因此任何將“click”事件添加到編輯/刪除按鈕的嘗試都將失敗。 只有在加載時存在的元素才能注冊到事件,因此可以將<tbody>document任何祖先元素注冊到click事件,然后可以將事件委派給編輯/刪除按鈕。 一般而言,委托事件涉及用於具體確定哪些元素對事件做出反應以及哪些元素忽略此類事件的編程模式。

jQuery事件方法通過提供名為eventData的第一個( .on() )參數,使事件委托變得容易。 eventData是選擇器字符串格式的可選參數(與$( ... )通常的相同)。 這將成為函數的上下文 - $(this)$(event.target) - 基本上是單擊的按鈕。
祖先 eventData
⇩⇩

 $(document).on('click', '.edit', function(e) {... 

詳情在演示中評論

 /* A: jQuery .append() is not destructive like .innerHTML Template literal is easier and cleaner than literal strings. */ function handleContacts(data) { data.forEach(function(object) { $('.contacts').append(`<tr> <td class='content'>${object.ID}</td> <td class='content'>${object.Info.Name}</td> <td class='content'>${object.Info.Email}</td> <td class='content'>${object.Info.PhoneNumber}</td> <td><button class="btn btn-primary btn-xs edit"><i class="fas fa-pen"></i></button></p></td> <td><button class="btn btn-danger btn-xs delete"><i class="fas fa-trash"></i></button></td></tr>`); //A }); } var data = [{ "CustomValues": {}, "Comment": "Here is John", "Deleted": false, "ID": 1, "InfoID": 4, "Role": null, "StatusCode": null, "UpdatedAt": null, "UpdatedBy": null, "Info": { "DefaultEmailID": 1, "DefaultPhoneID": 2, "Deleted": false, "ID": 3, "Name": "John", "PhoneNumber": "123-123-1231", "Email": "john@mail.com" } }, { "CustomValues": {}, "Comment": "Here is Mike", "Deleted": false, "ID": 2, "InfoID": 6, "Role": null, "StatusCode": null, "UpdatedAt": null, "UpdatedBy": null, "Info": { "DefaultEmailID": 3, "DefaultPhoneID": 4, "Deleted": false, "ID": 6, "Name": "Mike", "PhoneNumber": "321-321-3213", "Email": "mike@mail.com" } } ]; // button.add is clicked -- handleContacts() is called $('.add').on('click', function(e) { handleContacts(data); }); /* Delegate click event to document $(this) or $(e.target) is button.delete Get the .closest() <tr> and remove() it. */ $(document).on('click', '.delete', function(e) { $(e.target).closest('tr').remove(); }); /* Delegate click event to document Note: Any dynamically added elements cannot be bound to events. Events must be bound to an element that existed at load time. $(this) or $(e.target) is button.edit */ /* B: Get the .closest() <tr> C: In this <tr> find() .each() td.content and toggle the [contenteditable] attribute true/false D: In this <tr> find() td[contenteditable] and .focus() on the first one .eq(0). Note: $(this)[0] is a dereferenced "this" because jQuery will not recognize the JavaScript method .toggleAttribute() */ $(document).on('click', '.edit', function(e) { var row = $(e.target).closest('tr'); //B row.find('.content').each(function() { $(this)[0].toggleAttribute('contenteditable'); }); //C row.find('[contenteditable]').eq(0).focus(); //D }); 
 <link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet"> <link href="https://use.fontawesome.com/releases/v5.7.2/css/all.css" rel="stylesheet" crossorigin="anonymous"> <div class="container"> <div class="table-responsive"> <table class="table table-striped contacts"> <caption style='caption-side:top'><h4>Contacts</h4></caption> <thead class="thead-dark"> <tr> <th scope="col">ID</th> <th scope="col">Name</th> <th scope="col">Email</th> <th scope="col">Phone</th> <th scope="col">Edit</th> <th scope="col">Delete</th> </tr> </thead> <tbody> </tbody> </table> </div> <button class="btn btn-sm btn-primary add">Add Contacts</button> </div> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.3.1/js/bootstrap.min.js"></script> 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM