尝试在 DataTable Bootstrap 中的每一行下显示按钮,但只能在特定列而不是整行下显示它们

Posted

技术标签:

【中文标题】尝试在 DataTable Bootstrap 中的每一行下显示按钮,但只能在特定列而不是整行下显示它们【英文标题】:Trying to show buttons under every row in DataTable Bootstrap but can only display them under a specific column instead of whole row 【发布时间】:2021-10-28 19:46:53 【问题描述】:

我正在创建一个管理活动费用的系统。

在这个系统中,一个事件可以有多个分期付款的单次付款。我要做的是在用户将鼠标悬停在表中的事件上时显示这些分期付款。 (每一行代表一个事件)

这些分期付款可以从一个到多个不等,这意味着所有活动的分期数都不相同。

所以,我所做的基本上就是这样,

所以,如果你能看到,基本上绿色按钮代表已付分期付款,黄色警告按钮代表未付分期付款。

但问题是,它们显示在单个列下。我希望这些在该行下水平分布,而不是显示在单个列下。

这是我用来显示此数据表的代码,(仅包括相关代码)

<style type="text/css">
  #events-table tr .links 
  
    display:none;
  
  #events-table tr:hover .links 
  
    display:block;   
  
 </style>   
            <!-- Begin Page Content -->
            <div class="container-fluid">

                <!-- Page Heading -->
                <h1 class="h3 mb-4 text-gray-800">Events</h1>

                <div class = "container mb-3 mt-3" id = "events_table">

                </div>

jQuery 代码

$(document).ready(function()
        function getEvents() 
            $.ajax (
                url: "action.php",
                type: "POST", 
                data: action: "get_events",
                success: function(response) 
                    $("#events_table").html(response);
                    table = $("table").DataTable(
                        pagingType: 'full_numbers',
                        filter: true, 
                    );
                
            )
        

        getEvents(); 
    );

这是 action.php 文件,这是我为这个表编写所有语法的地方。

if (isset($_POST['action']) && $_POST['action'] == "get_events")

    $output = ''; 
    $data = $db->get_all_events(); 
    $output .= '


    <table id = "events-table" class = "table table-striped table-bordered ">
              <thead>
                <tr>
                  <th data-field="id" data-sortable = "true">ID</th>
                  <th data-field="event_name" data-sortable = "true">Event Name</th>
                  <th data-field="date" data-sortable = "true">Date</th>
                  <th data-field="payment" data-sortable = "true">Total Payment</th>
                  <th data-field="expense" data-sortable = "true">Expenses</th>
                  <th data-field="profit" data-sortable = "true">Profit</th>
                  <th data-field="actions" data-sortable = "false">Actions</th>
                </tr>
              </thead>
              <tbody>';
      $number = 1; 
    foreach($data as $row)
    
        $expense = $row['discount']+$row['photo']+$row['video']; 
        $profit = $row['payment'] - $expense; 
        $date = $row['day'].'-'.$row['month'].'-'.$row['year'];
        $output .= '<tr class ="text-center text-secondary">
        <td>'.$number.'</td>
        <td>'.$row['e_name'].'';

        $payments = $db->get_payments($row['c_id']);
        foreach ($payments as $payment)
        
          if ($payment['p_status'] == 'pending')
          
            $output .= '<div class="links" style = "margin-right: 50%; margin-top: 10px;">
            <a id="do_payment" data-id1= '.$payment['p_id'].' class="btn btn-warning btn-icon-split"> <span class="icon text-white-50"> <i class="fas fa-exclamation-triangle"></i> </span> <span class="text">'.$payment['p_amount'].'</span></div>';
          
          else 
          
            $output .= '<div class="links" style = "margin-right: 50%; margin-top: 10px;">
            <a id="remove_payment" data-id1= '.$payment['p_id'].' class="btn btn-success btn-icon-split"> <span class="icon text-white-50"> <i class="fas fa-check"></i> </span> <span class="text">'.$payment['p_amount'].'</span></div>';
          
        
        $output .='</td>
        <td>'.$date.'</td>
        <td>'.$row['payment'].'</td>
        <td style="color: red">'.$expense.'</td>
        <td style="color: green">'.$profit.'</td>
        <td><a id="view_event" data-id1 = '.$row['c_id'].' class="btn btn-outline-info btn-sm" href="">View</a>
        <a id="update_event" data-id1 = '.$row['c_id'].' class="btn btn-outline-secondary btn-sm" href="">Update</a>
        <a id="delete_event" data-id1 = '.$row['c_id'].' class="btn btn-outline-danger btn-sm" href="">Delete</a></td>
        </tr>';

        $number++;  
    
    $output .= '</tbody></table>';
    echo $output;
  

您会注意到,目前我的按钮设置在“事件名称”字段下。我想让这些按钮分布在整行上。任何帮助将不胜感激。

另外,谁能告诉我如何对齐表格顶部的显示条目搜索栏?谢谢。

编辑:我尝试通过在表格中创建一个新行来使用 colspan 属性并将我的按钮放入其中(如建议的那样在 cmets 中)但它对我没有用。相反,它显示了一些非常不受欢迎的结果。

首先,按钮确实与“一”列分开,因此该问题确实得到了解决,但在这种情况下,现在所有相似的按钮仍在同一列中。例如,绿色按钮相互堆叠,而黄色按钮是分开但相互堆叠的。

另外,更大的问题是现在按钮只会在我“悬停”在“事件”行下的行上时显示。它在每行下方创建了一条非常小的白线来表示按钮行,并且仅当我将鼠标悬停在该白线上时才会显示按钮,而当我将鼠标悬停在实际的事件行上时什么都不会显示。

新的action.php的修改代码如下,

if (isset($_POST['action']) && $_POST['action'] == "get_events")

    $output = ''; 
    $data = $db->get_all_events(); 
    $output .= '


    <table id = "events-table" class = "table table-striped table-bordered ">
              <thead>
                <tr>
                  <th data-field="id" data-sortable = "true">ID</th>
                  <th data-field="event_name" data-sortable = "true">Event Name</th>
                  <th data-field="date" data-sortable = "true">Date</th>
                  <th data-field="payment" data-sortable = "true">Total Payment</th>
                  <th data-field="expense" data-sortable = "true">Expenses</th>
                  <th data-field="profit" data-sortable = "true">Profit</th>
                  <th data-field="actions" data-sortable = "false">Actions</th>
                </tr>
              </thead>
              <tbody>';
      $number = 1; 
    foreach($data as $row)
    
        $expense = $row['discount']+$row['photo']+$row['video']; 
        $profit = $row['payment'] - $expense; 
        $date = $row['day'].'-'.$row['month'].'-'.$row['year'];
        $output .= '<tr class ="text-center text-secondary">
        <td>'.$number.'</td>
        <td>'.$row['e_name'].'';

        
        $output .='</td>
        <td>'.$date.'</td>
        <td>'.$row['payment'].'</td>
        <td style="color: red">Rs. '.$expense.'</td>
        <td style="color: green">Rs. '.$profit.'</td>
        <td><a id="view_event" data-id1 = '.$row['c_id'].' class="btn btn-outline-info btn-sm" href="">View</a>
        <a id="update_event" data-id1 = '.$row['c_id'].' class="btn btn-outline-secondary btn-sm" href="">Update</a>
        <a id="delete_event" data-id1 = '.$row['c_id'].' class="btn btn-outline-danger btn-sm" href="">Delete</a></td>
        </tr>
        <tr><td colspan="5">';
        $payments = $db->get_payments($row['c_id']);
        $output .= '<div class="links">';
        foreach ($payments as $payment)
        
          if ($payment['p_status'] == 'pending')
          
            
            $output .='<a id="do_payment" data-id1= '.$payment['p_id'].' class="btn btn-warning btn-icon-split"> <span class="icon text-white-50"> <i class="fas fa-exclamation-triangle"></i> </span> <span class="text">'.$payment['p_amount'].'</span></div>';
          
          else 
          
            $output .='<a id="remove_payment" data-id1= '.$payment['p_id'].' class="btn btn-success btn-icon-split"> <span class="icon text-white-50"> <i class="fas fa-check"></i> </span> <span class="text">'.$payment['p_amount'].'</span></div>';
          
        
        $output .='</td></tr>';

        $number++;  
    
    $output .= '</tbody></table>';
    echo $output;
  

【问题讨论】:

我认为问题是列中没有足够的水平空间。您需要使列更宽或在列上设置一个溢出-y(但随后某些按钮将被切断/隐藏,直到用户将它们滚动到视图中)。 @weltschmerz 是的,确实,该列上没有足够的空间。但我不希望所有按钮都位于单个列下,我希望它们分布在整行上(并且它们可能需要尽可能多的列)。另外,如何在列上设置溢出?在那种情况下,为什么有些按钮会被切断?如果可能,请告诉。感谢您的回复顺便说一句 在这种情况下,渲染单个 td 并将 colspan 属性设置为您要填充的列数。您可能需要将按钮放在单独的行中才能使用。 不幸的是,对于 DataTables,表格主体中没有对 colspan 的内置支持。请参阅here:“虽然 DataTables 在表格的页眉和页脚中支持 colspanrowspan,但它们在表格的 tbody 中不受支持且不得存在 @weltschmerz 我尝试自己学习 colspan。据我了解,我试图在我的数据表中实现它,但不幸的是它对我没有用。我已经在帖子的编辑部分分享了我修改过的代码和上面的结果 【参考方案1】:

您可以使用 DataTables 的“子行”功能 - 请参阅示例 here。

这些子行的好处是它们跨越表格的整个宽度,但只包含一个单元格。

在你的情况下,你需要做一些调整:

    确保始终显示每个子行。正如您在上面链接的演示中看到的那样,默认情况下它们都是隐藏的。

    隐藏通常包含每个子行的“显示/隐藏”按钮的列。

下面是一些代码,展示了我的简单演示:

// this function controls what is displayed in each child row. It has access to all the parent row's data
function format ( rowData ) 
    // `rowData` is the data object (or array) for the row
    return '<span>Put whatever you want in here, for example: "<b>' + rowData.name + '"</b>. It spans all the columns.</span>';


$(document).ready(function() 

  var dataSet = [
    
      "id": "123",
      "name": "Tiger Nixon",
      "position": "System Architect",
      "salary": "$320,800",
      "start_date": "2011/04/25",
      "office": "Edinburgh",
      "extn": "5421"
    ,
    
      "id": "456",
      "name": "Donna Snider",
      "position": "Customer Support",
      "salary": "$112,000",
      "start_date": "2011/01/25",
      "office": "New York",
      "extn": "4226"
    ,
    
      "id": "567",
      "name": "Cedric Kelly",
      "position": "Senior javascript Developer",
      "salary": "$433,060",
      "start_date": "2012/03/29",
      "office": "Edinburgh",
      "extn": "6224"
    ,
    
      "id": "432",
      "name": "Airi Satou",
      "position": "Accountant",
      "salary": "$162,700",
      "start_date": "2008/11/28",
      "office": "Tokyo",
      "extn": "5407"
    ,
    
      "id": "987",
      "name": "Brielle Williamson",
      "position": "Integration Specialist",
      "salary": "$372,000",
      "start_date": "2012/12/02",
      "office": "New York",
      "extn": "4804"
    
  ];


  var table = $('#example').DataTable( 
    data: dataSet,
    columns: [
      
        "className": 'details-control',
        "orderable": false,
        "data": null,
        "visible": false, // do not show the open/close column
        "defaultContent": ''
      ,
       "data": "name" ,
       "data": "position" ,
       "data": "office" ,
       "data": "salary" 
    ],
    "order": [[1, 'asc']]
   );

  // force each child row to be displayed:
  $("#example").DataTable().rows().every( function () 
    this.child( format(this.data()) ).show();
    $( this.node() ).addClass('shown');
  );


 );
<!doctype html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Demo</title>
  <script src="https://code.jquery.com/jquery-3.5.1.js"></script>
  <script src="https://cdn.datatables.net/1.10.22/js/jquery.dataTables.js"></script>
  <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.22/css/jquery.dataTables.css">
  <link rel="stylesheet" type="text/css" href="https://datatables.net/media/css/site-examples.css">

</head>

<body>

<div style="margin: 20px;">

    <table id="example" class="display dataTable cell-border" style="width:100%">
    <thead>
            <tr>
                <th></th>
                <th>Name</th>
                <th>Position</th>
                <th>Office</th>
                <th>Salary</th>
            </tr>
        </thead>
        <tfoot>
            <tr>
                <th></th>
                <th>Name</th>
                <th>Position</th>
                <th>Office</th>
                <th>Salary</th>
            </tr>
        </tfoot>
    </table>

</div>

</body>
</html>

在上面的例子中,具体看format ( rowData )函数。

在我的演示中,该函数只是将一些非常基本的 HTML 组合成一个字符串。该 HTML 显示为子行的内容。

在您的情况下,您可以构建更复杂的 HTML,表示要在每行下方显示的水平对齐的按钮行。

【讨论】:

以上是关于尝试在 DataTable Bootstrap 中的每一行下显示按钮,但只能在特定列而不是整行下显示它们的主要内容,如果未能解决你的问题,请参考以下文章

bootstrap datatable项目封装支持单选多选

如何修改bootstrap中 datatable 表格的样式?

bootstrap d-flex中的Jquery Datatable在Internet Explorer中溢出父级

怎么说设置datatable bootstrap-table-fixed-columns,css

bootstrap-dataTable

如何使用bootStrap中的dataTable插件