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
In einem früheren Beitrag habe ich Ihnen gezeigt, wie man eine Suche Dropdown mit Alpine.js und HTMX dann habe ich gezeigt, wie wir Cross-Site Request Forgery Schutz mit dem AntiforgeryRequestToken
im ASP.NET Core mit JavaScript mit HTMX einen Donut Hole Cache implementieren......................................................................................................... Ein herausragendes Problem war, wie es Seiten geladen.
Das Problem war, dass ich HTMX AJAX benutzte, um die angeforderte Seite zu laden, sobald Sie das Ergebnis von der Dropdown-Seite ausgewählt hatten. Das hat nur KINDA funktioniert.
selectResult(result) {
htmx.ajax('get', result.url, {
target: '#contentcontainer', // The container to update
swap: 'innerHTML', // Replace the content inside the target
}).then(function() {
history.pushState(null, '', result.url);
window.scrollTo({
top: 0,
behavior: 'smooth'
});
});
Das Problem war, dass, während dies würde die richtige Seite laden und aktualisieren Sie die angezeigte URL mit der neuen, es verwüstet die Rückseite Taste. Wie die Seite war nicht wirklich in die Geschichte richtig geladen.
Wie bei meinem letzter Artikel auf der Rückseite Knopf Shennanigans Das war etwas, das ich reparieren wollte.
Wie bisher war es die Lösung, HTMX dies direkt handhaben zu lassen. Dazu habe ich meine Vorlage aktualisiert, die ich für Suchergebnisse verwende.
_typeahead.cshtml
<div x-data="window.mostlylucid.typeahead()" class="relative" id="searchelement" x-on:click.outside="results = []">
@Html.AntiForgeryToken()
<label class="input input-sm bg-neutral-500 bg-opacity-10 input-bordered flex items-center gap-2">
<input
type="text"
x-model="query"
x-on:input.debounce.200ms="search"
x-on:keydown.down.prevent="moveDown"
x-on:keydown.up.prevent="moveUp"
x-on:keydown.enter.prevent="selectHighlighted"
placeholder="Search..."
class="border-0 grow input-sm text-black dark:text-white bg-transparent w-full"/>
<i class="bx bx-search"></i>
</label>
<!-- Dropdown -->
<ul x-show="results.length > 0"
id="searchresults"
class="absolute z-100 my-2 w-full bg-white dark:bg-custom-dark-bg border border-1 text-black dark:text-white border-neutral-600 rounded-lg shadow-lg">
<template x-for="(result, index) in results" :key="result.slug">
<li :class="{
'dark:bg-blue-dark bg-blue-light': index === highlightedIndex,
'dark:hover:bg-blue-dark hover:bg-blue-light': true
}"
class="cursor-pointer text-sm p-2 m-2">
<!-- These are the key changes.-->
<a
x-on:click="selectResult(index)"
@* :href="result.url" *@
:hx-get="result.url"
hx-target="#contentcontainer"
hx-swap="innerHTML"
hx-push-url="true"
x-text="result.title"
>
</a>
<-- End of changes -->
</li>
</template>
</ul>
</div>
Du wirst sehen, dass ich jetzt generiere sachgerecht HTMX-Verbindungen in diesem Code-Block. Lassen Sie uns das richtige HTMX-Verhalten verwenden.
typeahead.js
Um dies in meinem Backend-JavaScript-Code zu aktivieren, habe ich die folgende Suchmethode hinzugefügt (siehe unten). Das this.$nextTick
ist ein Alpine.js-Konstrukt, das dies verzögert, bis Alpine die oben gezeigte Vorlage bearbeitet hat.
Dann verwende ich htmx.process()
auf dem Suchelement, das sicherstellt, dass die HTMX-Attribute wie erwartet funktionieren.
.then(data => {
this.results = data;
this.highlightedIndex = -1; // Reset index on new search
this.$nextTick(() => {
htmx.process(document.getElementById('searchresults'));
});
})
search() {
if (this.query.length < 2) {
this.results = [];
this.highlightedIndex = -1;
return;
}
let token = document.querySelector('#searchelement input[name="__RequestVerificationToken"]').value;
console.log(token);
fetch(`/api/search/${encodeURIComponent(this.query)}`, { // Fixed the backtick and closing bracket
method: 'GET', // or 'POST' depending on your needs
headers: {
'Content-Type': 'application/json',
'X-CSRF-TOKEN': token // Attach the AntiForgery token in the headers
}
})
.then(response => {
if(response.ok){
return response.json();
}
return Promise.reject(response);
})
.then(data => {
this.results = data;
this.highlightedIndex = -1; // Reset index on new search
this.$nextTick(() => {
htmx.process(document.getElementById('searchresults'));
});
})
.catch((response) => {
console.log(response.status, response.statusText);
if(response.status === 400)
{
console.log('Bad request, reloading page to try to fix it.');
window.location.reload();
}
response.json().then((json) => {
console.log(json);
})
console.log("Error fetching search results");
});
}
selectHighlighted() {
if (this.highlightedIndex >= 0 && this.highlightedIndex < this.results.length) {
this.selectResult(this.highlightedIndex);
}
},
selectResult(selectedIndex) {
let links = document.querySelectorAll('#searchresults a');
links[selectedIndex].click();
this.$nextTick(() => {
this.results = []; // Clear the results
this.highlightedIndex = -1; // Reset the highlighted index
this.query = ''; // Clear the query
});
}
Diese wird über den Klick auf den Link in den Suchergebnissen ausgewählt.
<a
x-on:click="selectResult(index)"
:hx-get="result.url"
hx-target="#contentcontainer"
hx-swap="innerHTML"
hx-push-url="true"
x-text="result.title"
>
</a>
Das wird dann die Seite laden und die URL richtig aktualisieren.
Ich habe auch Code in der Elternbox whick ermöglicht es Ihnen, die Pfeiltasten zu verwenden und eingeben.
<label class="input input-sm bg-neutral-500 bg-opacity-10 input-bordered flex items-center gap-2">
<input
type="text"
x-model="query"
x-on:input.debounce.200ms="search"
x-on:keydown.down.prevent="moveDown"
x-on:keydown.up.prevent="moveUp"
x-on:keydown.enter.prevent="selectHighlighted"
placeholder="Search..."
class="border-0 grow input-sm text-black dark:text-white bg-transparent w-full"/>
<i class="bx bx-search"></i>
</label>
Sie werden sehen, dass dies alle notwendigen Code hat, damit Sie einfach Enter drücken und zur ausgewählten Seite navigieren können.
Nur eine schnelle Aktualisierung Artikel auf die bestehende Suche Dropdown, um die Benutzererfahrung zu verbessern, wenn die Suche. Auch dies ist ein MINIMAL Benutzer gegenüber Änderung, sondern nur verbessert die Benutzererfahrung; wer als Web-Entwickler sind Ihre primäre Sorge (jenseits immer bezahlt :)).