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
Sólo una rápida, tenía una necesidad en un proyecto de trabajo para la capacidad de 'limpiar' los parámetros de URL de una URL. Esto es útil cuando tienes una URL con múltiples parámetros, y quieres eliminar uno o más de ellos (por ejemplo, para un filtro de búsqueda).
Mi proyecto actual utiliza cadenas de consulta de la vieja escuela (es un sitio de administración por lo que no necesita la fantasía de 'agradable' urls). Así que termino con una URL como esta:
/products?category=electronics&search=wireless+headphones&sort=price_desc&inStock=true&page=3
Ahora estos pueden variar con cada página, así que puedo terminar con un BUNCH en la URL de la página y necesito ser capaz de borrarlos sin escribir un montón de placa de caldera para hacerlo.
Puede hacer esto como parte de cualquier control de entrada que utilice, por ejemplo, junto a cada casilla de verificación (o un icono claro de estilo de marcador de posición de lujo) pero puede utilizar esta técnica para ellos también. Sin embargo, en este caso quería hacer dos cosas principales:
En mi proyecto ya utilizo
Así que mi solución se centró en el uso de estos para obtener una solución bonita y funcional con un código mínimo.
Mi TagHelper es bastante simple, todo lo que hago es crear un <a>
más tarde pasaré al módulo alpino y habremos terminado.
[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>");
}
}
En uso esto se ve así, primero para 'limpiar todos los parámetros'. Así que sólo miro el Context.Request.Query
si hay algún parámetro allí renderizo el pequeño x
para que el usuario limpie todos los parámetros.
@if(Context.Request.Query.Any())
{
<label class="param-label">
<clear-param all="true"></clear-param>
clear all
</label>
}
</div>
Alternativamente para parámetros nombrados puedo hacer esto
<div class="param-label">
<clear-param name="myParam"></clear-param>
<p>My Param: @Model.MyParam</p>
</div>
Lo que, por supuesto, aclararía ese parámetro único.
O incluso
<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>
Esto borra todos los parámetros nombrados de la cadena.
target
atributoYou también tiene la opción de pasar en un target
atributo que se utilizará como la hx-target
atributo. Esto es útil si desea actualizar una parte específica de la página con el nuevo contenido.
<div class="param-label">
<clear-param name="myParam" target="#my-thing"></clear-param>
<p>My Param: @Model.MyParam</p>
</div>
En mi caso (porque lo escribí) por defecto el objetivo a mi #page-content
div.
[HtmlAttributeName("target")]
public string Target { get; set; } = "#page-content";
Estos resultados en la representación del siguiente HTML:
x-all
atributo y no x-param
atributo.<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>
x-param
atributo y no x-all
atributo.<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>
x-param
atributo con una cadena separada por coma y no x-all
atributo.<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>
Cada uno de ellos también tiene los dos atributos alpinos x-data
y x-on:click.prevent
que se utilizan para configurar el módulo alpino y llamar a la función para limpiar los parámetros.
Veremos cómo funciona a continuación...
Esto es, por supuesto, posible a través del uso de Alpine.js para configurar nuestra solicitud y HTMX para realizarla.
Como se puede ver en el código de abajo, tengo un módulo simple que toma la path
de la página actual y luego utiliza el URL
API para analizar la cadena de consulta (también puede pasar en una diferente por cualquier razón :)).
A continuación, obtenemos el elemento que se hizo clic y comprobar si tiene el x-all
atributo; si lo hace eliminamos todos los parámetros de la URL, de lo contrario dividimos la x-param
Atribuir por comas y eliminar cada uno de esos parámetros.
Luego creamos una nueva URL con la cadena de consulta actualizada y usamos HTMX para hacer una solicitud a esa 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
función usando SweetAlert2También notarás que llamo a un showAlert
función. Esto es sólo un envoltorio simple alrededor del indicador de carga SweetAlert2 que utilizo en mi proyecto. Por supuesto, puedes reemplazar esto con lo que quieras hacer.
Esto está ligeramente ajustado de la La última vez que lo vimos. Para poder extraer el showAlert
funcionar y ponerlo a disposición de los módulos externos. Que vamos a utilizar en ambos la param-clearer
módulo y el hx-indicator
módulo.
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;
Como recordatorio, se utiliza el path
como la clave para saber cuándo ocultar la alerta.
Por último, utilizamos htmx.ajax
para hacer la petición. Se trata de una simple petición GET a la nueva URL que creamos con la cadena de consulta actualizada.
htmx.ajax('GET', newUrl, {
target: el.dataset.target || el.getAttribute('hx-target') || 'body',
swap: 'innerHTML',
pushUrl: true
});
Esta es una forma sencilla de borrar los parámetros de URL usando un ayudante de etiquetas y Alpine.js. Le permite borrar todos los parámetros, o sólo los específicos, con un código mínimo.