Back to "Älykkäämpi pudotus HTMX:llä"

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

HTMX Alpine.js

Älykkäämpi pudotus HTMX:llä

Monday, 16 September 2024

Johdanto

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.

Ongelma

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.

Ratkaisu

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'));
 });
})
typeahead.js search
   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");
                });
        }
Myöhemmin, kun sivu on valittu, käsittelen koodia valitakseni sivun, napsauta linkkiä ja selvitä tulokset (lopetaksesi hakuruudun).
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.

Johtopäätöksenä

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 :)).

logo

©2024 Scott Galloway