Back to "Alpine.js ja HTMX 'Pääselvä hakujoukkoparameteri"

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

Alpine.js ASP.NET Core HTMX Javascript

Alpine.js ja HTMX 'Pääselvä hakujoukkoparameteri

Friday, 25 April 2025

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

  1. Voidaan poistaa nimetty parametri
  2. Voidaan selvittää luettelo parametreista.
  3. Voidaan selvittää kaikki parametrit
  4. Onko se lähetetty takaisin HTMX:n kanssa
  5. 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-all ominaisuuksia ja ei x-param ominaisuuksia.
<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-param ominaisuuksia ja ei x-all ominaisuuksia.
<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-param ominaisuuksia, joilla on comma-separannettu string ja ei x-all ominaisuuksia.
<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.

logo

© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.