|
|
@@ -0,0 +1,126 @@
|
|
|
+<div class="dropdown-menu" style="width: 300px;" aria-labelledby="{{$id}}">
|
|
|
+ <div class="px-1">
|
|
|
+ <div class="d-flex mb-2 {{ $isSort ? '' : 'd-none' }}">
|
|
|
+ <div class="me-3">Сортировка</div>
|
|
|
+ <div class="d-flex w-75">
|
|
|
+ <button type="button" class="btn btn-outline-secondary btn-sm w-100" id="sort-by-asc-{{$id}}"><i class="bi bi-arrow-up"></i>ASC</button>
|
|
|
+ <button type="button" class="btn btn-outline-secondary btn-sm w-100" id="sort-by-desc-{{$id}}"><i class="bi bi-arrow-down"></i>DESC</button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <form class="dropdown-filter_{{$id}} mb-2">
|
|
|
+ <input class="form-control mb-3" id="search_{{$id}}" placeholder="Поиск">
|
|
|
+ <div class="ps-1" id="filter-list-{{$id}}" style="max-height: 200px; overflow-y: scroll;">
|
|
|
+ </div>
|
|
|
+ </form>
|
|
|
+ <div class="modal-footer d-flex justify-content-between" id="modal-footer_{{$id}}">
|
|
|
+ <button type="button" class="btn btn-outline-secondary reset-filters_{{$id}} btn-sm w-50 border-0" id="reset-filters_{{$id}}">Отмена</button>
|
|
|
+ <button type="button" class="btn btn-primary accept-filter_{{$id}} btn-sm w-50" id="accept-filter_{{$id}}">Применить</button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+</div>
|
|
|
+
|
|
|
+@push('scripts')
|
|
|
+ <script type="module">
|
|
|
+ function escapeHtml(str) {
|
|
|
+ return str.toString()
|
|
|
+ .replace(/&/g, "&")
|
|
|
+ .replace(/"/g, """)
|
|
|
+ .replace(/</g, "<")
|
|
|
+ .replace(/>/g, ">");
|
|
|
+ }
|
|
|
+
|
|
|
+ $(document).ready(async function () {
|
|
|
+ const $container = $("#filter-list-{{$id}}");
|
|
|
+ const $searchInput = $("#search_{{$id}}");
|
|
|
+ const urlParams = new URL(document.location.href);
|
|
|
+ const existingFilter = urlParams.searchParams.get(`filters[{{$id}}]`);
|
|
|
+ const selectedValues = existingFilter ? existingFilter.split("||") : [];
|
|
|
+
|
|
|
+ try {
|
|
|
+ const response = await fetch(`http://localhost:8090/get-filters?column={{$id}}&table={{$table}}`);
|
|
|
+ const data = await response.json();
|
|
|
+
|
|
|
+ if (Array.isArray(data) && data.length && data[0] !== null) {
|
|
|
+ const html = data.map(item => `
|
|
|
+ <div class="form-check">
|
|
|
+ <input class="form-check-input" type="checkbox" value="${escapeHtml(item)}" id="flexCheckDefault_${escapeHtml(item)}">
|
|
|
+ <label class="form-check-label" for="flexCheckDefault_${escapeHtml(item)}">
|
|
|
+ ${escapeHtml(item)}
|
|
|
+ </label>
|
|
|
+ </div>
|
|
|
+ `).join('');
|
|
|
+ $container.html(html);
|
|
|
+
|
|
|
+ selectedValues.forEach(value => {
|
|
|
+ $container.find(`.form-check-input[value="${$.escapeSelector(value)}"]`).prop("checked", true);
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ $("#search_{{$id}}").hide();
|
|
|
+ $("#modal-footer_{{$id}}").hide();
|
|
|
+ $container.html('<div class="text-muted">Нет данных</div>');
|
|
|
+ }
|
|
|
+
|
|
|
+ } catch (error) {
|
|
|
+ console.error("Ошибка при загрузке фильтров:", error);
|
|
|
+ $container.html('<div class="text-danger">Ошибка загрузки</div>');
|
|
|
+ }
|
|
|
+
|
|
|
+ $("#accept-filter_{{$id}}").on("click", function () {
|
|
|
+ const checkedValues = $container.find(".form-check-input:checked")
|
|
|
+ .map(function () {
|
|
|
+ return $(this).val();
|
|
|
+ })
|
|
|
+ .get();
|
|
|
+
|
|
|
+ let currentUrl = new URL(document.location.href);
|
|
|
+ if(!checkedValues.join('||')) {
|
|
|
+ currentUrl.searchParams.delete('filters[{{$id}}]');
|
|
|
+ } else {
|
|
|
+ currentUrl.searchParams.set('filters[{{$id}}]', checkedValues.join('||'));
|
|
|
+ }
|
|
|
+
|
|
|
+ currentUrl.searchParams.delete('page');
|
|
|
+ document.location.href = currentUrl.href;
|
|
|
+ });
|
|
|
+
|
|
|
+ $("#reset-filters_{{$id}}").on("click", function () {
|
|
|
+ let currentUrl = new URL(document.location.href);
|
|
|
+ currentUrl.searchParams.delete('filters[{{$id}}]');
|
|
|
+ document.location.href = currentUrl.href;
|
|
|
+ });
|
|
|
+
|
|
|
+ $searchInput.on("input", function () {
|
|
|
+ const query = $(this).val().toLowerCase();
|
|
|
+
|
|
|
+ $container.find(".form-check").each(function () {
|
|
|
+ const labelText = $(this).find("label").text().toLowerCase();
|
|
|
+
|
|
|
+ if (labelText.includes(query)) {
|
|
|
+ $(this).show();
|
|
|
+ } else {
|
|
|
+ $(this).hide();
|
|
|
+ $(this).find(".form-check-input").prop("checked", false);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ $('#sort-by-asc-{{$id}}').on('click', function () {
|
|
|
+ let columnName = '{{$id}}';
|
|
|
+ let currentUrl = new URL(document.location.href);
|
|
|
+ currentUrl.searchParams.set('sortBy', columnName);
|
|
|
+ if(currentUrl.searchParams.get('order') === 'desc') {
|
|
|
+ currentUrl.searchParams.delete('order');
|
|
|
+ }
|
|
|
+ document.location.href = currentUrl.href;
|
|
|
+ });
|
|
|
+
|
|
|
+ $('#sort-by-desc-{{$id}}').on('click', function () {
|
|
|
+ let columnName = '{{$id}}';
|
|
|
+ let currentUrl = new URL(document.location.href);
|
|
|
+ currentUrl.searchParams.set('sortBy', columnName);
|
|
|
+ currentUrl.searchParams.set('order', 'desc');
|
|
|
+ document.location.href = currentUrl.href;
|
|
|
+ });
|
|
|
+ });
|
|
|
+ </script>
|
|
|
+@endpush
|