繁体   English   中英

在 Bootstrap/DataTable 中正确重新加载表

[英]Correctly reload Table in Bootstrap/DataTable

我有一个带有 Bootstrap 和 DataTable 样式的简单表。 感谢编辑/删除/添加按钮,我能够与之交互。 例如,这是编辑一行的 JS 代码:

    function editRow(){
        var catProg = document.getElementById('editCatProg_Input').value;
        var catUser = document.getElementById('editCatUser_Input').value;
        var catPass = document.getElementById('editCatPass_Input').value;
        var catInUso = document.getElementById('editCatInUso_Input').value;
        var catDesc = document.getElementById('editCatDesc_Input').value;
        var catUltimo = document.getElementById('editCatUltimo_Input').value;
        var catDat = document.getElementById('editCatDat_Input').value;

        $.ajax({
            url: 'UpdateRow.php',
            type: 'POST',
            data: { 
                CatProg: catProg,
                CatUser: catUser,
                CatPass: catPass,
                CatInUso: catInUso,
                CatDesc: catDesc,
                CatUltimo: catUltimo,
                CatDat: catDat
            },
            dataType: "text",
            success: function(result){
                // relaod (fetch db again)
                window.location.replace(window.location.pathname + window.location.search + window.location.hash);
            },
            error: function(){
                alert("Request did not succeed. Reload and try again.");
            }
        });
    }

如您所见,我被迫重新加载整个页面以更新表格。 这带来了两个主要问题:

  1. 如果我在 X 页上编辑一行,重新加载会再次将我带到第 1 页。我希望它留在 X 页上,并带有重新加载的表格;
  2. 页面的刷新在视觉上并不令人愉悦。

有没有办法做到这一点? 我试过这样:

  1. 在 JavaScript 函数中,通过 Ajax 调用从 Php 脚本中获取新表,并将其替换为旧表;
  2. ajax.reload()刷新表格,但恐怕我不明白如何正确使用它。

谁能给我任何想法和/或我可能实现的代码片段? 先感谢您。

您可以将表示成功更新的数据记录的 JSON 对象从服务器发送回 DataTables。 您可以使用 DataTables API 获取该响应 JSON,并使用它来更新基础 DataTable 中特定行的数据。

我将假设您正在使用表中的输入字段,因为这是更复杂的情况。 但是,如果您使用的是模态对话框(或类似的东西) ,那么该方法将是此方法的简化版本。

我用于测试的源数据是:

{
  "data": [
    {
      "name": "Tiger Nixon",
      "position": "System Architect",
      "salary": "$320,800"
    },
    {
      "name": "Garrett Winters",
      "position": "Accountant",
      "salary": "$170,750"
    },
    ...
  ]
}

“salary”列包含可编辑的数据:

在此处输入图像描述


创建表和处理更新的脚本如下:

$(document).ready(function() {

  // src is the button which was clicked:
  function editRow(src) {
    let row = $(src).closest("tr");
    // the data fields for the updated row:
    let name = row.find(".name").text();
    let position = row.find(".posn").text();
    let salary = row.find(".sal").val();

    // fields converted to JSON:
    let rowData = { 
      name: name,
      position: position,
      salary: salary
    };
    
    // We will need this to do an in-place update of the edited row.
    // It is the internal DataTables row index number for the edited row:
    let rowIndex = table.cell( $(src).closest("td") ).index().row;

    $.ajax({
      url: '[your URL goes here]',
      type: 'POST',
      contentType: 'text', // type of data sent to the server
      data: JSON.stringify(rowData), // the data we send to the server
      dataType: 'json', // type of data returned from the server
      success: function(data, status, xhr) {
        // {order:'index'} uses the index based on the original data load order,
        // otherwise it would use the current sort/filter order.
        // invalidate() causes the DataTables cache to be re-populated. 
        // Using 'dom' means the data is reloaded from user-provided DOM values.
        // The draw( false ) call ensures the table does not reset to page 1:
        table.rows( rowIndex, {order:'index'} ).invalidate( 'dom' ).draw( false );
        
      },
      error: function(xhr, status, error){
        console.log( error );
      }
    });

  }

  var table = $('#example').DataTable( {
    ajax: {
      method: "GET",
      url: "[your URL goes here]"
    },
    columns: [
      { title: "Name", data: "name", className: "name" },
      { title: "Position", data: "position", className: "posn" },
      { 
        title: "Salary", 
        data: "salary",
        render: function ( data, type, row, meta ) {
          if ( type === 'display' ) {
            // render the display value first, so there is an input control:
            return '<input class="sal" value="' + data + '">';
          } else {
            // get the value from the input control and use just the value
            // for sorting and filtering:
            let api = $( '#example' ).DataTable();
            let td = api.cell({row: meta.row, column: meta.col}).node();
            let inputData = $('select, input', td).val();
            return inputData; // the value used for sorting and filtering
          }
        } 
      },
      { defaultContent: '<button class="upd" type="button">Update</button>' }
    ]

  } );
  
  // attach a click event to visible and not-yet-visible buttons:
  $( "#example" ).on( "click", ".upd", function() {
    editRow( this );
  });
  

} );

当用户单击更新按钮时,相关函数会检索行数据值。 就我而言,这是 2 个静态值和一个用户提供的值(薪水)。

如果您使用的是模态对话框,那么这部分对您来说可能更简单 - 更像您问题中的代码。

提交给服务器的是一段字符串化的 JSON - 例如:

{"name":"Airi Satou","position":"Accountant","salary":"$162,701"}

返回的内容(成功保存操作后)基本上是相同的信息,但作为 JSON 对象。

注意 - 这可能与发送的内容不同,如果(例如)您正在处理可能更改的其他字段(例如“最后更新”时间戳等)。 在我的简单示例中,返回的数据与发送的数据相同。

我们获取这个返回的数据,并更新底层的 DataTable(到目前为止)不知道用户在薪水输入字段中输入了什么。 用户键入的内容仅存在于 DOM(HTML)中,但尚不存在于 DataTables 中。

处理这个问题的行是:

table.rows( rowIndex, {order:'index'} ).invalidate( 'dom' ).draw( false );

但也请注意下面提到的row().data( your_json_here )函数。

invalidate()函数处理对缓存的更改。 draw( false )函数确保刷新所有数据,但不会将表重置到第 1 页 - 这就是false参数的作用。

如果您返回的数据与发送的数据不同(上述“最后更新”点),那么您也可以使用row().data( your_json_here )函数,在缓存数据无效后设置更新的行数据.


那里发生了很多事情。 但它通过 Ajax 调用绘制更新的数据,因此不会刷新整个页面。 我在代码中添加了更多注释,以进一步澄清。

学分

我从这个老问题中获得了一些灵感: Search within dropdowns search all the dropdown options instead of selected option

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM