当搜索输入与数据表中折叠<tr>中的内容匹配时,如何过滤和显示行?

问题描述 投票:0回答:1

我正在使用 DataTables 来管理一个表,其中某些内容位于可折叠的

<tr>
元素中。最初,这些
<tr>
是隐藏的(显示:无),只有当按下相应的按钮 (
Details
) 时它们才变得可见。

使用 DataTables 搜索过滤器时,我希望表格显示包含隐藏

<tr>
元素中的匹配内容的主行,而不要求用户先单击“
Details
”按钮。

这是我当前的设置:

每个可折叠行都有一个唯一的 ID,我将每行的内容存储在具有以下结构的字典中: { 'id_of_row': ['内容1', '内容2', '内容3', ...] } 目标是当用户在搜索框中键入内容时在字典中进行搜索,如果在任何字典元素中找到匹配项,则会使用 id_of_row 并应显示具有该 id 的相应主行。

示例问题:

如果我搜索术语“requ”,则不会显示任何内容,因为相应的内容位于折叠的

<tr>
内。但是,如果我通过单击“详细信息”按钮手动展开
<tr>
并使该内容可见,并且如果该内容内存在匹配项,它将显示出来。

我尝试过的:

我使用字典将主行的 ID 映射到该行的内容数组。当搜索输入与字典中的元素匹配时,我希望显示相应的主行,即使它的内容位于当前隐藏的元素内。 但是,我似乎无法让它按预期工作。当其内容与搜索词匹配时,该行不会显示,除非手动展开。

这是我当前代码的简化版本:

@using Newtonsoft.Json
@{
// Sample machine names
var MachineNames = new List<string> { "Machine A", "Machine B", "Machine C" };

// Sample requests using anonymous objects
var requests = new[]
{
new { Id = 1, ContactName = "Client A", CompanyName = "Machine A", Status = "Pending", Msg = "Request 1" },
new { Id = 2, ContactName = "Client B", CompanyName = "Machine B", Status = "In Progress", Msg = "Request 2" },
new { Id = 3, ContactName = "Client C", CompanyName = "Machine C", Status = "Completed", Msg = "Request 3" }
};

// Sample dictionary data for matching the behavior of your original example
var requestDictionary = new Dictionary<int, string[]>
{
{ 1, new[] { "client a", "machine a", "pending", "request 1" } },
{ 2, new[] { "client b", "machine b", "in progress", "request 2" } },
{ 3, new[] { "client c", "machine c", "completed", "request 3" } }
};
}

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Collapsible Table with Custom Filter</title>

    <!-- Include jQuery -->
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>

    <!-- Include DataTables CSS & JS -->
    <link rel="stylesheet" href="https://cdn.datatables.net/1.10.21/css/jquery.dataTables.min.css">
    <script src="https://cdn.datatables.net/1.10.5/js/jquery.dataTables.min.js"></script>

    <style>
        table {
            width: 100%;
            border-collapse: collapse;
        }

        th, td {
            padding: 8px;
            text-align: left;
            border-bottom: 1px solid #ddd;
        }

        .show {
            display: table-row;
        }

        .dataTables_filter label {
            font-weight: bold;
            font-size: 1.2em;
        }

        .dataTables_filter input {
            margin-left: 10px;
            padding: 5px;
            border-radius: 5px;
            border: 1px solid #ccc;
        }

        #search-container {
            width: auto;
            padding: 5px;
            margin-bottom: 10px;
        }
    </style>
</head>

<body>
<h1>Collapsible Table with Custom Search Filter</h1>

<!-- Search filter -->
<div id="search-container"></div>

<!-- The table with collapsible rows -->
<table id="myTable" class="display table-flexible">
    <thead>
    <tr>
        <th>Request ID</th>
        <th>Client</th>
        <th>Machine</th>
        <th>Status</th>
        <th>Description</th>
    </tr>
    </thead>
    <tbody>
    @foreach (var request in requests)
    {
    <tr>
        <td>@request.Id</td>
        <td>@request.ContactName</td>
        <td data-id="@request.CompanyName">@request.CompanyName</td>
        <td>@request.Status</td>
        <td>
            <button class="btn btn-info btn-sm toggle-btn" data-target="#[email protected]">Details</button>
        </td>
    </tr>

    <tr id="[email protected]" class="details-row" style="display: none;">
        <td colspan="6">
            <div class="card custom-card-body details-card">
                <div class="detail-item">
                    <strong>Message:</strong>
                    <p class="tw-font-bold">@request.Msg</p>
                </div>
            </div>
        </td>
    </tr>
    }
    </tbody>
</table>

@section Scripts {
<script src="https://cdn.datatables.net/1.10.5/js/jquery.dataTables.min.js"></script>
<script>
    $(document).ready(function () {
       
        var requestDictionary = @Html.Raw(JsonConvert.SerializeObject(requestDictionary));

        console.log(requestDictionary); // Debugging purposes
        
        // Initialize DataTable
        var table = $('#myTable').DataTable({
            columnDefs: [{
                "defaultContent": "-",
                "targets": "_all"
            }],
            paging: false,
            ordering: false,
            info: false,
            dom: 'ft'
        });

        // Move search box to custom container
        $('#search-container').html($('.dataTables_filter'));

        // Custom search functionality using the requestDictionary
        function filterTable(searchTerm) {
            var rows = table.rows().nodes(); // Fetch all rows
            $(rows).each(function () {
                var $row = $(this); // The `tr` element

                // Extract requestId from the first column (adjust if necessary)
                var requestId = $row.find('td').first().text().trim();

                // Ensure requestId is a valid number
                requestId = parseInt(requestId, 10);
                if (isNaN(requestId)) {
                    return; // Skip rows without a valid requestId
                }

                // Check if requestId exists in the dictionary
                if (!requestDictionary.hasOwnProperty(requestId)) {
                    return;
                }

                var requestDetails = requestDictionary[requestId];
                console.log(requestDetails); // Debugging purposes

                // Check if any of the details contain the search term
                var match = requestDetails.some(function (detail) {
                    return detail.toLowerCase().includes(searchTerm.toLowerCase());
                });

                // Show or hide the row based on the search match
                if (match) {
                    console.log("HIT - Showing row for requestId:", requestId);
                    $row.css("display", "table-row");  // Set display to table-row
                } else {
                    console.log("MISS - Hiding row for requestId:", requestId);
                    $row.css("display", "none");  // Hide row
                }
            });
        }

        // Handle search input
        $('.dataTables_filter input[type="search"]').on('input', function () {
            var searchTerm = $(this).val().trim();
            filterTable(searchTerm);
        });

        // Attach event listeners for toggling rows
        $('.toggle-btn').on('click', function () {
            var target = $(this).data('target');
            $(target).fadeToggle(500);
        });
    });
</script>
}
</body>



感谢您的时间和关注!

javascript html asp.net-mvc datatables
1个回答
0
投票

我认为问题出在你的函数内部。 您正在做的是,找到匹配项后,您正在对当前正在循环内部处理的同一行进行操作。 相反,您需要使用当前请求 ID 查找详细信息行并显示该行。

这是您可以尝试的可能解决方案之一。

function filterTable(searchTerm) {
    // First hide all the details row
    $('.details-row').css('display', 'none');

    var rows = table.rows().nodes(); // Fetch all rows
    $(rows).each(function() {
      var $row = $(this); // The `tr` element

      // Extract requestId from the first column (adjust if necessary)
      var requestId = $row.find('td').first().text().trim();

      // Ensure requestId is a valid number
      requestId = parseInt(requestId, 10);
      if (isNaN(requestId)) {
        return; // Skip rows without a valid requestId
      }

      // Check if requestId exists in the dictionary
      if (!requestDictionary.hasOwnProperty(requestId)) {
        return;
      }

      var requestDetails = requestDictionary[requestId];
      //      console.log(requestDetails); // Debugging purposes

      // Check if any of the details contain the search term
      var match = requestDetails.some(function(detail) {
        return detail.toLowerCase().includes(searchTerm.toLowerCase());
      });

      // Show the details row based on the search match
      if (match) {
        $('#detailsCollapse_' + requestId).css('display', 'table-row');
      }
    });
  }
© www.soinside.com 2019 - 2024. All rights reserved.