Alpine.js ja HTMX 'Pääselvä hakujoukkoparameteri
Esitys
Tämä on hyödyllistä, kun URL: ssa on useita parametreja, ja jos haluat poistaa yhden tai useamman niistä.
Ongelma
Nykyisessä hankkeessani käytetään vanhoja-koulua koskevat kysymykseen liittyvät stringit (itM SK2 on hallinnollinen sivusto, joten ei' tarvita fanciness-läheyttä.
/products?category=electronics&search=wireless+headphones&sort=price_desc&inStock=true&page=3
Nyt ne voivat vaihdella kussakin sivussa,, joten voin päätyä siihen, että sivun URL: ssä on BUNCH ja minun on pystyttävä poistamaan ne kirjoittamatta mitään boilerplatea sen tekemiseksi.
Voitte tehdä tämän osana riippumatta siitä, mitä input-valvontaa olette käyttämässä, joten esimerkiksi jokaisen tarkistuskäsitteen läheisyydessä ( tai fancy placeholder style clear icon) mutta ja voitte käyttää tätä tekniikkaa myös niille . Joka tapauksessaM SK3 tässä tapauksessa halusin tehdä kaksi pääasiallista asiaa
- Voidaan poistaa nimetty parametri
- Voidaan selvittää luettelo parametreista.
- Voidaan selvittää kaikki parametrit
- Onko se lähetetty takaisin HTMX:n kanssa
- Onko se käyttänyt lastausindikaattoriani? lastausindikaattorini.
Ratkaisu
Omassa hankkeessani käytän jo
- HTMX
- Alpine.js
- ASP.NET Core
- TailwindCSS
- DaisyUI
Näin ollen ratkaisuni keskityi näiden käyttämiseen saadakseni mukavan lookallisen käytännöllisen ratkaisun vähimmäiskoodilla
Tagin avustaja
Minun TagHelper on varsin yksinkertainen, kaikki, mitä teen, on luoda <a> merkintö, jossa on joitakin ominaispiirteitä I' siirtyy myöhemmin alppimuunttiin ja teemme sen
[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>");
}
}
Parametrit
Käytössä tämä näyttää olevan seuraavaa, ensin 'selvi kaikki parametritM SK2 joten katson vain Context.Request.Query jos siellä on '-parametereja, esitän pienet x icon, jonka avulla käyttäjä voi poistaa kaikki parametrit.
@if(Context.Request.Query.Any())
{
<label class="param-label">
<clear-param all="true"></clear-param>
clear all
</label>
}
</div>
Vaihtoehtoisesti nimettyjen parametrien osalta voin tehdä tämän
<div class="param-label">
<clear-param name="myParam"></clear-param>
<p>My Param: @Model.MyParam</p>
</div>
Tämä selventäisi luonnollisesti sitä, että yksi ainoa parametri.
Tai jopa
<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>
Tämän jälkeen kaikki nimetut parametrit selvitetään string.:sta.
Euroopan unionin target luonne
Teillä on myös mahdollisuus päästä läpi target ominaisuuksia, joita käytetään hx-target attribute. Tämä on hyödyllinen, jos haluatte ajanmukaistaa tiettyä sivun osaa uudella sisällöllä.
<div class="param-label">
<clear-param name="myParam" target="#my-thing"></clear-param>
<p>My Param: @Model.MyParam</p>
</div>
Omassa tapauksessani (, koska kirjoitin sen ). #page-content Div.
[HtmlAttributeName("target")]
public string Target { get; set; } = "#page-content";
Tulos
Näiden tulosten perusteella voidaan esittää seuraava HTML:
- Kaikki:
Saamme siis HTML:n
x-allominaisuuksia ja eix-paramominaisuuksia.
<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>
- Yksittäinen
Saamme HTML:n
x-paramominaisuuksia ja eix-allominaisuuksia.
<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>
- Useat
Saamme HTML:n
x-paramominaisuuksia, joilla on comma-separannettu string ja eix-allominaisuuksia.
<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>
Kaikilla niillä on myös kaksi alppimaisen ominaisuutta. x-data ja x-on:click.prevent , joita käytetään Alpine-muunnoksen perustamiseen ja kutsutaan toiminnaksi, jotta parametrit selvitetään.
Katsomme seuraavaksi, miten se toimii.
Alppimuudelma
Tämä on tietenkin mahdollista Alpine.js:n avulla, jotta voimme konfiguroida pyynnön ja HTMX:n voida toteuttaa sen.
Kuten näette jäljempänä olevassa koodissa, minulla on yksinkertainen moduuli, joka path ja käyttää sen jälkeen URL API, jolla analysoidaan kysymyksen stringi ( voitte myös siirtää toisesta syystä
Saamme sitten elementin, joka oli klikattu ja tarkistaa, onko sillä x-all attribute; jos se poistaa kaikki parametrit URL:stä, muilta osin jaamme x-param ja poistaa kukin näistä parametreista.
Sen jälkeen luomme uuden URL:n, jossa on ajantasaistettu kysymyksen string ja käytämme HTMX:tä, jotta voimme esittää pyynnön kyseiselle URL:lle.
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;
Euroopan unionin showAlert SweetAlert-operaatio
Huomaatte myös, että minä kutsun showAlert function. Tämä on vain yksinkertainen wrapper SweetAlertin ympärille.
Tämä on hieman mukautettu viime kerralla nähimme sen. Voisin siis extrahoida showAlert ja tehdä siitä saatavilla ulkoisia moduuleja., jotka antavat's minulle käyttää sitä molemmissa param-clearer Moduli ja hx-indicator moduuli.
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;
Muistutuksena käytetään path avain, jonka avulla voidaan tietää, milloin varoittaa hälytys
HTMX
Lopuksi käytämme htmx.ajax to make the request. Tämä on yksinkertainen GET-pyynnös uudelle URL:lle, jonka olemme luoneet ajantasaistetut kysymyksensa stringin kanssa
htmx.ajax('GET', newUrl, {
target: el.dataset.target || el.getAttribute('hx-target') || 'body',
swap: 'innerHTML',
pushUrl: true
});
Päätelmissä
Tämä on yksinkertainen tapa selviytyä URL-parametereista käyttämällä tag helperia ja Alpinea.