NOTE: Apart from
(and even then it's questionable, I'm Scottish). These are machine translated in languages I don't read. If they're terrible please contact me.
You can see how this translation was done in this article.
Monday, 16 September 2024
//Less than a minute
Edellisessä viestissä näytin sinulle, kuinka luoda hakupudotus Alppien.js ja HTMX:n avulla Sitten näytin, miten voimme mahdollistaa rajat ylittävän Forgery-suojauksen AntiforgeryRequestToken
ASP.NET Core ja JavaScript HTMX:n käyttö donitsivälimuistin käyttöön...................................................................................................................................... Yksi merkittävä kysymys oli se, miten se latasi sivuja.
Ongelmana oli, että käytin HTMX AJAX:ää tehdäkseni pyydetyn sivulatauksen, kun olet valinnut pudotussivun tuloksen. Tämä vain toimi.
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'
});
});
Ongelmana oli, että vaikka tämä lataisi oikean sivun ja päivittäisi uuden URL-osoitteen, se sekoitti takanappia. Koska sivua ei ollut ladattu kunnolla historiaan.
Niin kuin minunkin viimeinen artikkeli selänpainikkeella shennangans tämä oli asia, jonka halusin korjata.
Kuten aiemminkin, ratkaisu oli antaa HTMX:n hoitaa tämä suoraan. Tätä varten päivitin mallin, jota käytän hakutuloksiin.
_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>
Huomaat, että nyt luon kunnollinen HTMX-linkit tässä koodilohkossa. Antaa meidän käyttää oikeaa HTMX-käyttäytymistä.
typeahead.js
Tämän mahdollistamiseksi backend JavaScript-koodiin lisäsin hakumenetelmääni seuraavan (näytä alla). Erytropoietiini this.$nextTick
Alpine.js rakentaa, että viivästyttää tätä, kunnes Alpine on valmis käsittelemään edellä näyttämäni mallin.
Sitten käytän htmx.process()
HTMX-ominaisuuksien toimivuuden odotetusti varmistavasta hakuelementistä.
.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
});
}
Tämä valitaan hakutuloksissa olevan linkin klikkaamalla.
<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>
Joka lataa sivun ja päivittää URL-osoitteen oikein.
Emolaatikossa on myös koodi, jonka avulla voit käyttää nuolinäppäimiä ja syöttää.
<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>
Huomaat, että tässä on kaikki tarvittava koodi, jotta voit vain osua syötteeseen ja navigoida valitulle sivulle.
Vain nopea päivitys artikkeli olemassa olevaan hakuun, joka parantaa käyttökokemusta hakua käytettäessä. Tämäkin on MINIMAL-käyttäjä, jolla on edessään muutos, mutta joka vain parantaa käyttökokemusta; joka verkkokehittäjänä on päähuolenaiheesi (palkan lisäksi :)).