This is a viewer only at the moment see the article on how this works.
To update the preview hit Ctrl-Alt-R (or ⌘-Alt-R on Mac) or Enter to refresh. The Save icon lets you save the markdown file to disk
This is a preview from the server running through my markdig pipeline
Альпіний.js і HTMX 'Parameter прозорих строків zapytaньM SK2sMSC3 вказівник на тег для ASP .NET Core
Friday, 25 April 2025
Введение
Просто один швидкий , У моєму проекті була потреба в здатності відокремлювати параметри URL з URL 'clear МSK2 Це корисно, коли у вас є URL із багатьма параметрами МSK4 і ви хочете видалити один або більше з них
Проблема
Мій теперішній проект використовує старі-стрічки запитів школи M SK1it' це адміністративна веб-страна, тому не потребує ' модності МSK4 гарно МSK5 urlsMSC6 Тож я закінчу з таким URL
/products?category=electronics&search=wireless+headphones&sort=price_desc&inStock=true&page=3
Тепер вони можуть змінюватися з кожним листом, так що я можу закінчити з BUNCH в URL сторінки і мені потрібно бути в змозі очистити їх, не пишучи купу котла для цього.
Ви можете зробити це як частину будь-якого управління входом, яке ви використовуєте, наприклад, поруч з кожним чекбоксом ( або у стилі фешенебельного placeholder прочистити значок ) але ви можете використовувати цю техніку і для тих, хто теж займається цим МSK2 Однак МSK3 в цьому випадку я хотів зробити дві головні речі
- В змозі очистити названий параметр
- Я можу очистити список параметрів.
- Можути очистити всі параметри
- Відповісти про це HTMX
- Використовуйте мій індикатор завантаження мій індикатор навантаження.
Рішення
У своєму проекті я вже користуюся
- HTMX
- Alpine.js
- ASP.NET Кора
- TailwindCSS
- DaisyUI
Отже, моє рішення було спрямоване на використання цих приладів для отримання гарного вигляду
Допомічник тагов
Мій TagHelper досить простий, все, що я роблю - це створити <a> ярлик з декількома атрибутами Я' пізніше перейду до Альпіського модуля і миM SK1 закінчимо
[HtmlTargetElement("clear-param")]
public class ClearParamTagHelper : TagHelper
{
[HtmlAttributeName("name")]
public string Name { get; set; }
[HtmlAttributeName("all")]
public bool All { get; set; }= false;
[HtmlAttributeName("target")]
public string Target { get; set; } = "#page-content";
public override void Process(TagHelperContext context, TagHelperOutput output)
{
output.TagName = "a";
output.Attributes.SetAttribute("x-data", "window.queryParamClearer({})");
if (All)
{
output.Attributes.SetAttribute("x-all", All);
}
else
{
output.Attributes.SetAttribute("x-param", Name);
}
output.Attributes.SetAttribute("data-target", Target);
output.Attributes.SetAttribute("x-on:click.prevent", "clearParam($event)");
output.Content.SetHtmlContent(@"
<div class='w-6 h-6 flex items-center justify-center bg-red-600 text-white rounded-full'>
<i class='bx bx-x text-lg'></i>
</div>");
}
}
Параметри
У використанні це виглядає так: , спочатку для ' розібратися з усіма параметрами МSK2 Я просто дивлюся на Context.Request.Query якщо там є якісь параметри, я відтворюю маленьку x іконка, яка дозволяє пользователю очистити всі параметри.
@if(Context.Request.Query.Any())
{
<label class="param-label">
<clear-param all="true"></clear-param>
clear all
</label>
}
</div>
Альтернативно для названих параметрів я можу зробити це
<div class="param-label">
<clear-param name="myParam"></clear-param>
<p>My Param: @Model.MyParam</p>
</div>
Це зрозуміло, що один із параметрів - .
Чи навіть
<div class="param-label">
<clear-param name="myParam1,myParam2,myParam3"></clear-param>
<p>My Param: @Model.MyParam1</p>
<p>My Param: @Model.MyParam2</p>
<p>My Param: @Model.MyParam3</p>
</div>
Таким чином, всі названі параметри відокремлені від строку.
І target властивість
У вас також є можливість пройти target атрибут, який буде використаний як hx-target атрибут. Це корисне, якщо ви хочете оновити певну частину сторінки з новим змістом
<div class="param-label">
<clear-param name="myParam" target="#my-thing"></clear-param>
<p>My Param: @Model.MyParam</p>
</div>
У моєму випадку ( тому, що я написав це ) Я за замовчанням встановив ціль для мого #page-content div.
[HtmlAttributeName("target")]
public string Target { get; set; } = "#page-content";
Результат
В результаті отримуємо ось такий HTML:
- Все:
Таким чином ми отримуємо HTML з
x-allатрибут і неx-paramатрибут.
<a x-data="window.queryParamClearer({})" x-all="True" data-target="#page-content" x-on:click.prevent="clearParam($event)">
<div class="w-6 h-6 flex items-center justify-center bg-red-600 text-white rounded-full">
<i class="bx bx-x text-lg"></i>
</div>
</a>
- Одинакова
Ми отримуємо HTML з
x-paramатрибут і неx-allатрибут.
<a x-data="window.queryParamClearer({})" x-param="myParam" data-target="#page-content" x-on:click.prevent="clearParam($event)">
<div class="w-6 h-6 flex items-center justify-center bg-red-600 text-white rounded-full">
<i class="bx bx-x text-lg"></i>
</div>
</a>
- Кілька
Ми отримуємо HTML з
x-paramатрибут із відокремленим символом і безx-allатрибут.
<a x-data="window.queryParamClearer({})" x-param="myParam1,myParam2,myParam3" data-target="#page-content" x-on:click.prevent="clearParam($event)">
<div class="w-6 h-6 flex items-center justify-center bg-red-600 text-white rounded-full">
<i class="bx bx-x text-lg"></i>
</div>
</a>
Кожна з них також має дві альпійські риси x-data і x-on:click.prevent які використовують для налаштування модуля Альпі та викликають функцію, щоб очистити параметри.
Ми подивимось, як це працює далі.
Альпійський модуль
Це, звісно ж, стало можливим, використовуючи Alpine.js для конфігурації нашого запиту і HTMX для його виконання
Як ви бачите в коді нижче, Я маю простий модуль, який бере path і потім використовує URL API для аналізу строку запиту ( ви також можете пройти в іншому з будь-якої причини :)) МSK2
Потім ми отримуємо елемент, який був натиснутий і перевіряємо, чи він має x-all атрибут; якщо ми видаляємо всі параметри з URLM SK1 інакше ми розділяємо x-param і видалити кожен із цих параметрів.
Далі ми створюємо новий URL з поновлюваним строком запиту і використовуємо HTMX, щоб запросити цей URL.
export function queryParamClearer({ path = window.location.pathname }) {
return {
clearParam(e) {
const el = e.target.closest('[x-param],[x-all]');
if (!el) return;
const url = new URL(window.location.href);
if (el.hasAttribute('x-all')) {
// → delete every single param
// we copy the keys first because deleting while iterating modifies the collection
Array.from(url.searchParams.keys())
.forEach(key => url.searchParams.delete(key));
} else {
// → delete only the named params
(el.getAttribute('x-param') || '')
.split(',')
.map(p => p.trim())
.filter(Boolean)
.forEach(key => url.searchParams.delete(key));
}
const qs = url.searchParams.toString();
const newUrl = path + (qs ? `?${qs}` : '');
showAlert(newUrl);
htmx.ajax('GET', newUrl, {
target: el.dataset.target || el.getAttribute('hx-target') || 'body',
swap: 'innerHTML',
pushUrl: true
});
}
};
}
//In your entry point / anywhere you want to register the module
import { queryParamClearer } from './param-clearer.js'; // webpackInclude: true
window.queryParamClearer = queryParamClearer;
І showAlert функція, яка використовує SweetAlert2
Ви також зауважите, що я називаю showAlert функція. Це просто простий упаковник навколо SweetAlert 2 індикатор навантаження, який я використовую в моєму проекті
Це трохи змінилося від коли ми вперше побачили це. Тож я міг витягнути showAlert і зробити його доступним для зовнішніх модулів., які дозволяютьM SK1 мені використовувати його в обох param-clearer модуля і hx-indicator модуль.
export function registerSweetAlertHxIndicator() {
document.body.addEventListener('htmx:configRequest', function (evt) {
const trigger = evt.detail.elt;
const indicatorAttrSource = getIndicatorSource(trigger);
if (!indicatorAttrSource) return;
// ✅ If this is a pageSize-triggered request, use our custom path
let path;
if (evt.detail.headers?.['HX-Trigger-Name'] === 'pageSize') {
path = getPathWithPageSize(evt.detail);
console.debug('[SweetAlert] Using custom path with updated pageSize:', path);
} else {
path = getRequestPath(evt.detail);
}
if (!path) return;
evt.detail.indicator = null;
showAlert(path);
});
}
export function showAlert(path)
{
const currentPath = sessionStorage.getItem(SWEETALERT_PATH_KEY);
// Show SweetAlert only if the current request path differs from the previous one
if (currentPath !== path) {
closeSweetAlertLoader();
sessionStorage.setItem(SWEETALERT_PATH_KEY, path);
Swal.fire({
title: 'Loading...',
allowOutsideClick: false,
allowEscapeKey: false,
showConfirmButton: false,
theme: 'dark',
didOpen: () => {
// Cancel immediately if restored from browser history
if (sessionStorage.getItem(SWEETALERT_HISTORY_RESTORED_KEY) === 'true') {
sessionStorage.removeItem(SWEETALERT_HISTORY_RESTORED_KEY);
Swal.close();
return;
}
Swal.showLoading();
document.dispatchEvent(new CustomEvent('sweetalert:opened'));
// Set timeout to auto-close if something hangs
clearTimeout(swalTimeoutHandle);
swalTimeoutHandle = setTimeout(() => {
if (Swal.isVisible()) {
console.warn('SweetAlert loading modal closed after timeout.');
closeSweetAlertLoader();
}
}, SWEETALERT_TIMEOUT_MS);
},
didClose: () => {
document.dispatchEvent(new CustomEvent('sweetalert:closed'));
sessionStorage.removeItem(SWEETALERT_PATH_KEY);
clearTimeout(swalTimeoutHandle);
swalTimeoutHandle = null;
}
});
}
}
//Register it
import { registerSweetAlertHxIndicator, showAlert } from './hx-sweetalert-indicator.js';
registerSweetAlertHxIndicator();
window.showAlert = showAlert;
Як нагадування це використовує path як ключ, щоб знати, коли приховати попередження.
HTMX
Нарешті, ми використовуємо htmx.ajax для створення запиту. Це простий запрос GET до нового URL, який ми створили з поновлюваним строком запиту
htmx.ajax('GET', newUrl, {
target: el.dataset.target || el.getAttribute('hx-target') || 'body',
swap: 'innerHTML',
pushUrl: true
});
На завершення
Це простий спосіб очистити URL-параметри, використовуючи вказівник та Альпіний.