| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170 |
- <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">
- <div class="d-flex align-items-center mb-2">
- <input class="form-control me-2" id="search_{{$id}}" placeholder="Поиск">
- <button type="button" class="btn btn-outline-secondary btn-sm" id="sort-filter-{{$id}}" title="А-Я / Я-А">
- <i class="bi bi-sort-alpha-down" id="sort-filter-icon-{{$id}}"></i>
- </button>
- </div>
- <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, ">");
- }
- // Ждём загрузки jQuery через Vite
- function waitForJQuery(callback) {
- if (typeof window.$ !== 'undefined') {
- callback();
- } else {
- setTimeout(() => waitForJQuery(callback), 50);
- }
- }
- waitForJQuery(async function () {
- const $container = $("#filter-list-{{$id}}");
- const $searchInput = $("#search_{{$id}}");
- const $sortBtn = $("#sort-filter-{{$id}}");
- const $sortIcon = $("#sort-filter-icon-{{$id}}");
- const urlParams = new URL(document.location.href);
- const existingFilter = urlParams.searchParams.get(`filters[{{$id}}]`);
- const selectedValues = existingFilter ? existingFilter.split("||") : [];
- let filterData = [];
- let sortAsc = true;
- function renderFilterList(data) {
- const html = data.map(item => `
- <div class="form-check">
- <input class="form-check-input" type="checkbox" value="${escapeHtml(item)}" id="flexCheckDefault_{{$id}}_${escapeHtml(item)}">
- <label class="form-check-label" for="flexCheckDefault_{{$id}}_${escapeHtml(item)}">
- ${escapeHtml(item)}
- </label>
- </div>
- `).join('');
- $container.html(html);
- selectedValues.forEach(value => {
- $container.find(`.form-check-input[value="${$.escapeSelector(value)}"]`).prop("checked", true);
- });
- }
- function sortData(asc) {
- const collator = new Intl.Collator('ru', { sensitivity: 'base', numeric: true });
- return [...filterData].sort((a, b) => {
- if (a === '-пусто-') return -1;
- if (b === '-пусто-') return 1;
- return asc ? collator.compare(a, b) : collator.compare(b, a);
- });
- }
- try {
- const response = await fetch(`{!! route('getFilters', ['column' => $id, 'table' => $table]) !!}`);
- const data = await response.json();
- if (Array.isArray(data) && data.length) {
- if(data[0] === null) data[0] = '-пусто-';
- filterData = data;
- const sortedData = sortData(sortAsc);
- renderFilterList(sortedData);
- } else {
- $("#search_{{$id}}").parent().hide();
- $("#modal-footer_{{$id}}").hide();
- $container.html('<div class="text-muted">Нет данных</div>');
- }
- } catch (error) {
- console.error("Ошибка при загрузке фильтров:", error);
- $container.html('<div class="text-danger">Ошибка загрузки</div>');
- }
- $sortBtn.on("click", function (e) {
- e.preventDefault();
- sortAsc = !sortAsc;
- $sortIcon.removeClass("bi-sort-alpha-down bi-sort-alpha-up")
- .addClass(sortAsc ? "bi-sort-alpha-down" : "bi-sort-alpha-up");
- const sortedData = sortData(sortAsc);
- renderFilterList(sortedData);
- });
- $("#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
|