# Панель фільтрування: поступ, вади і невеличкі перемоги

<!--category-- HTMX, ASP.NET, JavaScript -->
<datetime class="hidden">2025-11-10T14:10</datetime>

## Вступ

I've складав докупи відповідний фільтр для списку блогів: мова, діапазон дат, сорт і парування, які залишаються гарячими з HTMX.

Вона закривається зараз, але, як завжди, останні 20% - це гострий біт: дати, кеші і  далі, чи працює він локально, але не після свопінгу?[Якщо ви хочете, щоб глибинний пірнань з багатьма кодами і діаграмами, подивіться:](/blog/filterbarprogressandissues)

> / blog/ filterbarprogressand grees

[TOC]

## Пам'ятайте, що цей сайт є роботою, таке може статися, коли ви з'їсте свою догову їжу!

- TL; DR
- Нова панель фільтрування: Мова + Впорядкувати + Діапазон дат
- Частинні свопінги HTMX зберігають швидкість сторінки; назад/ forward працюють, оскільки я завжди натискаю на оновлену адресу URL`/blog/calendar-days`Виблиски календаря з' являються з крихітнихName
- кінцева точка
- Фіксовано: діапазони дат буде відкинуто під час зміни мови/ порядку
- Фіксований: календар не оновлюється після свопінгу з HTMX або змін теми

## Тепер кешування сервера змінюється всіма відповідними ключами запиту

- Що добре працює
- Поведінка першої адреси URL: всі взаємодії оновлюють адресу URL; ви можете здійснювати глибоке посилання на стан фільтрування`LinkUrl`Pagination зберігає поточні фільтри (
- встановлено на сервері)

```csharp
// Server: cache and vary for index
[ResponseCache(Duration = 300, VaryByHeader = "hx-request",
  VaryByQueryKeys = new[] { "page", "pageSize", nameof(startDate), nameof(endDate), nameof(language), nameof(orderBy), nameof(orderDir) },
  Location = ResponseCacheLocation.Any)]
[OutputCache(Duration = 3600, VaryByHeaderNames = new[] { "hx-request" },
  VaryByQueryKeys = new[] { nameof(page), nameof(pageSize), nameof(startDate), nameof(endDate), nameof(language), nameof(orderBy), nameof(orderDir) })]
public async Task<IActionResult> Index(int page = 1, int pageSize = 20, DateTime? startDate = null, DateTime? endDate = null,
  string language = MarkdownBaseService.EnglishLanguage, string orderBy = "date", string orderDir = "desc")
{
    var posts = await blogViewService.GetPagedPosts(page, pageSize, language: language, startDate: startDate, endDate: endDate);
    posts.LinkUrl = Url.Action("Index", "Blog", new { startDate, endDate, language, orderBy, orderDir });
    if (Request.IsHtmx()) return PartialView("_BlogSummaryList", posts);
    return View("Index", posts);
}
```

## Типовим діапазоном Плавчика є поточні значення запиту, якщо такі значення є, і висвітлюють дні з дописами

### Жуки, які я полагодив (і нові можливості!)

Видимість і контроль за вмістом

- **Найбільший додаток: належне керування показом дописів:**Приховані дописи`IsHidden`: Тепер дописи можна позначати як приховані (
- **flag) і не буде показано у списках**Опублікування за розкладом`ScheduledPublishDate`: У поштових скриньках може бути
- **і з' являтимуться лише після цього часу**Фіксовані дописи`IsPinned`: Дописи позначені

```csharp
// BlogService now filters appropriately
var now = DateTimeOffset.UtcNow;
postQuery = postQuery.Where(x =>
    !x.IsHidden &&
    (x.ScheduledPublishDate == null || x.ScheduledPublishDate <= now));

// Pinned posts sorted first on page 1
if (isFirstPage)
{
    postQuery = postQuery.OrderByDescending(x => x.IsPinned)
                         .ThenByDescending(x => x.PublishedDate.DateTime);
}
```

### завжди з' являтиметься першою на 1 - й сторінці (добра для оголошень)

- **Покращення діапазону дат`/blog/date-range`Створити**кінцева точка
- **: Повертає min/ max дати у всіх повідомленнях (підтримка мови) так, щоб інструмент вибору дати міг встановити розсудливі межі**Спорожнити допоміжний теґ`<clear-param>`: Додано

```cshtml
<clear-param name="startDate">Clear Date</clear-param>
<clear-param all="true" exclude="language">Clear All Filters</clear-param>
```

### помічник теґу для полегшення очищення параметрів запиту

- Виправлення вад
  - Втрата діапазону дат під час перемикання мови або порядку`new URL(window.location.href)`Фіксація: почати з

```js
langSelect.addEventListener('change', async function(){
  const u = new URL(window.location.href);
  u.searchParams.set('language', langSelect.value);
  u.searchParams.set('page','1');
  const [ob,od] = (orderSelect.value||'date_desc').split('_');
  u.searchParams.set('orderBy', ob);
  u.searchParams.set('orderDir', od);
  if(input._flatpickr && input._flatpickr.selectedDates.length===2){
    const [s,e] = input._flatpickr.selectedDates;
    u.searchParams.set('startDate', s.toISOString().substring(0,10));
    u.searchParams.set('endDate',   e.toISOString().substring(0,10));
  }
  applyNavigation(u);
});
```

- і перевизначити лише змінені параметри; якщо у Flatpicker є вибір, перезастосуйте його.
  
  - Календар не отримує освіження після свопінгу HTMX`fp.redraw()`Виправлення: Вилучити/ відтворити Flatpicker на init, а потім отримати підсвічування за видимий місяць і виклик`htmx:afterSwap`.

- ; also re-run init on
  
  - Стилі темного режиму не застосовуються до календаря`<html class>`Фіксація: спостереження`fp.redraw()`і виклик

## коли вона змінюється.

```mermaid
sequenceDiagram
  participant User
  participant JS as blog-index.js
  participant HT as HTMX
  participant S as Server

  User->>JS: Change language/order or pick a date range
  JS->>JS: Update URLSearchParams, pushState
  JS->>HT: htmx.ajax('GET', /blog?...)
  HT->>S: GET /blog
  S-->>HT: HTML partial (_BlogSummaryList)
  HT-->>User: Swap #content
```

## Як говорять ці шматочки

Виявлення запиту на виявлення сторінки HTMX`pagerequest`Панель фільтрування використовує нетиповий

```csharp
public static bool IsPageRequest(this HttpRequest request)
{
    return request.Headers.ContainsKey("pagerequest") &&
           request.Headers["pagerequest"] == "true";
}
```

заголовок, щоб допомогти серверу розрізняти між завантаженням повної сторінки і частковими свопінгами HTMX:

> **За допомогою цього пункту можна повернути лише частковий перегляд запитів HTMX і повний перегляд сторінок для безпосередньої навігації.**Примітка

## : Допоміжний додаток теґу і параметр запиту, що чіткіший за Billian.js компонент заслуговує на власну глибоку дистанцію ♪I охопить ці деталі у майбутньому пості про будівництво знову компонентів HTMX/Alpine.

- Все ще треба зробити
- Налаштування швидкої дати (Останні 7/ 30 днів, цього року)
- Зерна локального сховища для мови

Підтримка клавіатури під час захоплення діапазонів