Проблема с фильтром JavaScript со сворачиваемыми строками в шаблоне блейда Laravel

Я относительно новичок в веб-разработке и столкнулся с проблемой с моим js-кодом. Я реализовал на своем веб-сайте функцию фильтра с использованием js, но, похоже, она помешала функции свертывания и заставила ее перестать работать должным образом. но функция свертывания снова работает при очистке фильтров. Я просмотрел сайт, у которого могла быть та же проблема, что и у меня, но я не могу заставить их работать с моим кодом.

вот моя установка:

  • у меня есть таблица, в которой каждую строку можно свернуть, чтобы просмотреть дополнительную информацию
  • я добавил фильтрацию js для фильтрации строк на основе определенных столбцов
  • фильтр работает нормально, но когда фильтр активен, я не могу открыть свернутые строки, чтобы просмотреть детали
  • у меня есть app.blade.php в каталоге макетов, и я храню там скрипты и стили, которые обычно использую

Вот мой код:

@extends('layouts.app')

@section('content')
    <div class = "container">

        <button class = "btn btn-success mb-3" id = "toggleFilterForm">
            <i class = "fas fa-filter"></i> Hide Filter
        </button> 

        <div id = "filterForm">
            <div class = "row mb-3">
                <div class = "col">
                    <input type = "text" id = "col1" class = "form-control" placeholder = "Engineer Code">
                </div>
                <div class = "col">
                    <input type = "text" id = "col2" class = "form-control" placeholder = "Live">
                </div>
                <div class = "col">
                    <input type = "text" id = "col3" class = "form-control" placeholder = "Status">
                </div>
                <div class = "col">
                    <input type = "date" id = "col4" class = "form-control">
                </div>
                <div class = "col">
                    <button id = "applyFilters" class = "btn btn-primary">
                        <i class = "fas fa-search"></i> Filter
                    </button>
                </div>
                <div class = "col">
                    <button id = "clearFilters" class = "btn btn-secondary">
                        <i class = "fas fa-times-circle"></i> Clear Filters
                    </button>
                </div>
            </div>
        </div>

        <div class = "table-responsive">
            <table class = "table table-striped" id = "dataTable">
                <thead>
                    <tr>
                        <th>Col 1</th>
                        <th>Col 2</th>
                        <th>Col 3</th>
                        <th>Col 4</th>
                        <th>Date Time</th>
                    </tr>
                </thead>
                <tbody id = "tableBody">
                @foreach($fileData as $fileIndex => $file)
                    <tr data-bs-toggle = "collapse" data-bs-target = "#collapse{{ $fileIndex }}" aria-expanded = "false" aria-controls = "collapse{{ $fileIndex }}">
                        <td>{{ $file['content']['col1'] }}</td>
                        <td>{{ $file['content']['col2'] }}</td>
                        <td>{{ $file['content']['col3'] }}</td>
                        <td>{{ $file['content']['col4']) }}</td>
                        <td>{{ date('Y-m-d H:i:s', $file['content']['col5']) }}</td>
                    </tr>
                    @if (!empty($file['content']['data']))
                    <tr>
                        <td colspan = "5" class = "p-0">
                            <div class = "collapse" id = "collapse{{ $fileIndex }}">
                                <div class = "card card-body">
                                    <table class = "table table-bordered">
                                        <thead>
                                            <tr>
                                                <th>
                                                    <button class = "btn btn-danger" onclick = "toggleCollapse('collapse{{ $fileIndex }}')"><i class = "fas fa-times"></i> Close</button>
                                                </th>
                                            </tr>
                                        </thead>
                                        <tbody>
                                                <tr>
                                                    <td data-bs-toggle = "collapse" data-bs-target = "#collapse{{ $fileIndex }}-{{ $subKeyIndex }}" aria-expanded = "false" aria-controls = "collapse{{ $fileIndex }}-{{ $subKeyIndex }}">{{ $subKeyIndex }}</td>
                                                    <td colspan = "5">{{ count($subKey) }} Record(s)</td>
                                                </tr>
                                        </tbody>
                                    </table>
                                </div>
                            </div>
                        </td>
                    </tr>
                    @endif
                @endforeach
                </tbody>
            </table>
        </div>
    </div>

    <script>
        document.addEventListener('DOMContentLoaded', function() {

            document.getElementById('applyFilters').addEventListener('click', function() {
                const col1 = document.getElementById('col1').value.toLowerCase();
                const col2 = document.getElementById('col2').value.toLowerCase();
                const col3 = document.getElementById('col3').value.toLowerCase();
                const col4 = document.getElementById('col4').value;

                const topLevelRows = document.querySelectorAll('#tableBody > tr');

                topLevelRows.forEach(row => {
                    const cols = row.getElementsByTagName('td');

                    const col1Text = cols[0] ? cols[0].innerText.toLowerCase() : '';
                    const col2Text = cols[1] ? cols[1].innerText.toLowerCase() : '';
                    const col3Text = cols[2] ? cols[2].innerText.toLowerCase() : '';
                    const col4Text = cols[4] ? cols[4].innerText.split(' ')[0] : '';

                    let match = true;
                    if (col1 && !col1Text.includes(col1)) match = false;
                    if (col2 && !col2Text.includes(col2)) match = false;
                    if (col3 && !col3Text.includes(col3)) match = false;
                    if (col4 && col4Text !== col4) match = false;

                    if (match) {
                        row.style.display = '';
                    } else {
                        row.style.display = 'none';
                    }
                });
            });

            document.getElementById('clearFilters').addEventListener('click', function() {
                document.getElementById('col1').value = '';
                document.getElementById('col2').value = '';
                document.getElementById('col3').value = '';
                document.getElementById('col4').value = '';

                const rows = document.querySelectorAll('#tableBody > tr');
                rows.forEach(row => row.style.display = '');

            });

            document.getElementById('toggleFilterForm').addEventListener('click', function() {
                const filterForm = document.getElementById('filterForm');
                if (filterForm.style.display === 'none') {
                    filterForm.style.display = 'block';
                    this.innerHTML = '<i class = "fas fa-filter"></i> Hide Filter';
                } else {
                    filterForm.style.display = 'none';
                    this.innerHTML = '<i class = "fas fa-filter"></i> Show Filter';
                }
            });
    </script>

@endsection

Я ожидаю, что смогу открывать строки для просмотра их информации, пока фильтр активен, но это не работает.

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
0
67
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ваша фильтрация устанавливает row.style.display = 'none'; для всех строк, которые не соответствуют критериям фильтра. Сюда входят все строки $file['content']['data'], поэтому переключение статуса свертывания внутреннего элемента div ничего не дает.

Вы можете добавить определенный класс в основные строки и использовать его в своем выборе topLevelRows.

<tr class = "filterable" data-bs-toggle = "collapse" data-bs-target = "#collapse{{ $fileIndex }}" aria-expanded = "false" aria-controls = "collapse{{ $fileIndex }}">
const topLevelRows = document.querySelectorAll('#tableBody > tr.filterable');

И затем, чтобы убедиться, что соответствующие складные элементы не отображаются:

row.style.display = 'none';
document.querySelectorAll(row.dataset.bsTarget).forEach(t => t.classList.remove('show'));

Или, если вы хотите сохранить статус отображения/скрытия любых отфильтрованных строк, вы можете:

if (match) {
    row.style.display = '';
    document.querySelectorAll(row.dataset.bsTarget).forEach(t => t.parentElement.parentElement.style.display = '');
} else {
    row.style.display = 'none';
    document.querySelectorAll(row.dataset.bsTarget).forEach(t => t.parentElement.parentElement.style.display = 'none');
}

о, так все мои остальные строки фильтруются по тому, когда я их использую const topLevelRows = document.querySelectorAll('#tableBody > tr');, поэтому, когда я открываю что-либо во время фильтрации таблицы, а затем удаляю фильтр, оно откроется, и в следующий раз придется быть осторожным. спасибо, это сработало!

Sotg 22.05.2024 03:21

Другие вопросы по теме