# Ein Alpine-.-Js und HTMX-Messwert-Quellabfrage-Stringparameter-Parameter-Tag-Helfer für ASP..-NET-Core

<datetime class="hidden">2025-04-25T23:00</datetime>

<!--category-- Javascript, HTMX, Alpine.js, ASP.NET Core -->
# Einleitung

Nur eine schnelle Eins-,-Ich hatte ein Bedürfnis in einem Arbeitsprojekt für die Fähigkeit, . . ' .clear .' . URL-Parameter aus einer URL ... . Dies ist nützlich, wenn Sie eine URL mit mehreren Parametern haben . und Sie möchten einen oder mehrere von ihnen entfernen . ( . zum Beispiel für einen Suchfilter .

[TOC]

# Das Problem

Mein aktuelles Projekt verwendet alte - school Query Strings, die eine Admin-Website so doesn't ' nicht brauchen, die Fanciness von ' urls.). Also ich lande mit einer URL wie diese

```http
/products?category=electronics&search=wireless+headphones&sort=price_desc&inStock=true&page=3

```

Nun können diese mit jeder Seite variieren., , so dass ich am Ende mit einem BUNCH in der Seiten-URL und ich muss in der Lage sein, sie zu löschen, ohne ein Bündel von Boilerplate zu tun

Sie KANN dies als Teil von was auch immer Eingabe-Steuerung, die Sie verwenden, also zum Beispiel neben jedem Kontrollkästchen oder einem ausgefallenen Platzhalter Stil klar Ikone.), aber und Sie können diese Technik für diejenigen zu benutzen.

1. Einen benannten Parameter löschen können
2. In der Lage sein, eine Liste von Parametern löschen
3. Alle Parameter löschen
4. Lassen Sie es zurück mit HTMX
5. Lassen Sie es meine Ladeanzeige verwenden [meine Ladeanzeige](https://www.mostlylucid.net/blog/usingsweetalertforhxindicators).

# Die Lösung

In meinem Projekt benutze ich bereits

- HTMX
- Alpen-.-js
- ASP-.-NET Kern
- RückwindCSS
- DaisyUI

So war meine Lösung rund um die Verwendung dieser konzentriert, um eine schöne aussehende ?,? funktionale Lösung mit minimalem Code erhalten ?

## Der Tag Helfer

Mein TagHelper ist ziemlich einfach. `<a>` Tag mit ein paar Attributen I'-ll später in das Alpine Modul übergeben und wir .'-re fertig ?.-

```csharp
[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>");
    }
}
```

### Parameter

Im Gebrauch sieht dies wie folgt aus: ,, zuerst für ', alle Parameter löschen, '., also schaue ich mir nur die `Context.Request.Query` wenn es irgendwelche Parameter gibt, rendern ich das wenig `x` Symbol, um den Benutzer alle Parameter löschen zu lassen

```html

@if(Context.Request.Query.Any())
{
<label class="param-label">
    <clear-param all="true"></clear-param>
    clear all
</label>
}
</div>

```

Alternativ für benannte Parameter kann ich dies tun

```html

<div class="param-label">
    <clear-param name="myParam"></clear-param>
    <p>My Param: @Model.MyParam</p>
</div>
```

Was natürlich klarstellen würde, dass ein einzelner Parameter...

Oder sogar

```html

<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>
```

Dies löscht dann alle benannten Parameter aus dem String.

### Das `target` Attribut

YOu haben auch die Möglichkeit, in einem `target` Attribut, das als das `hx-target` attribut.-Dies ist nützlich, wenn Sie einen bestimmten Teil der Seite mit dem neuen Inhalt aktualisieren möchten.

```html

<div class="param-label">
    <clear-param name="myParam" target="#my-thing"></clear-param>
    <p>My Param: @Model.MyParam</p>
</div>
```

In meinem Fall, weil ich es geschrieben habe, habe ich das Ziel auf meine `#page-content` div..-

```csharp
    [HtmlAttributeName("target")]
    public string Target { get; set; } = "#page-content";

```

### Das Ergebnis

Diese Ergebnis in der Rendering des folgenden HTML-Sticks

- INSGESAMT
  So bekommen wir HTML mit dem `x-all` Attribut und nein `x-param` Attribut „."

```html
<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>

```

- Einzeln
  Wir bekommen HTML mit dem `x-param` Attribut und nein `x-all` Attribut „."

```html
<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>
```

- Vielfach
  Wir bekommen HTML mit dem `x-param` Attribut mit Komma getrennter Zeichenfolge und nein `x-all` Attribut „."

```html
<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>
```

Jeder von ihnen hat auch die beiden alpinen Attribute `x-data` und `x-on:click.prevent` welche verwendet werden, um das Alpine Modul einzurichten und die Funktion aufzurufen, um die Parameter zu löschen.

Wir sehen, wie das als nächstes funktioniert

## Das Alpine Modul

Dies wird natürlich ermöglicht durch die Verwendung von Alpine-.-js, um unsere Anfrage und HTMX zu konfigurieren, um es durchzuführen.

Wie Sie im Code unten sehen können, habe ich ein einfaches Modul, das die `path` der aktuellen Seite und verwendet dann die `URL` API, um die Abfrage-String zu parsen Sie könnte auch in einem anderen aus welchem Grund passieren

Wir bekommen dann das Element, das geklickt wurde und überprüfen ob es die `x-all` Attribute: Wenn es funktioniert, löschen wir alle Parameter aus der URL, sonst teilen wir die `x-param` Attribut durch Kommas und löschen Sie jeden dieser Parameter

Dann erstellen wir eine neue URL mit dem aktualisierten Query String und verwenden HTMX, um eine Anfrage an diese URL zu stellen.

```javascript
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;
```

### Das `showAlert` Funktion unter Verwendung von SweetAlert-2

Sie müssen auch beachten, dass ich eine `showAlert` Funktion: Das ist nur ein einfacher Wrapper um den SweetAlert-Ladeanzeiger, den ich in meinem Projekt verwende.Sie können dies natürlich mit dem ersetzen, was immer Sie tun möchten.

Dies ist leicht von der [Letztes Mal haben wir es gesehen.](https://www.mostlylucid.net/blog/usingsweetalertforhxindicators)So konnte ich extrahieren `showAlert` Funktion und machen Sie es für externe Module zur Verfügung. `param-clearer` Modul und die `hx-indicator` Modul„."

```javascript
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;
```

Als Erinnerung nutzt dies `path` als Schlüssel zu wissen, wann der Alarm versteckt werden soll

### HTMX

Schließlich verwenden wir `htmx.ajax` , um die Anfrage zu machen Dies ist eine einfache GET-Anfrage an die neue URL, die wir mit der aktualisierten Abfrage string.

```javascript
   htmx.ajax('GET', newUrl, {
                target: el.dataset.target || el.getAttribute('hx-target') || 'body',
                swap: 'innerHTML',
                pushUrl: true
            });
```

# Schlussfolgerung

Dies ist ein einfacher Weg, um URL-Parameter mit einem Tag Helper und Alpine-..js.. zu löschen Es ermöglicht es Ihnen, alle Parameter oder nur bestimmte zu löschen.