Back to "مُخفِز مُنْزِل البحث مع HTMX"

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

Alpine.js HTMX

مُخفِز مُنْزِل البحث مع HTMX

Monday, 16 September 2024

أولاً

في وظيفة سابقة عرضت عليك كيفية إنشاء إسقاطات بحثية باستخدام Albin.js و HTMX ثم عرضت كيف يمكننا أن نُمكّن من توفير حماية طلب طلب عبر الموقع AntiforgeryRequestToken SPSP.net confr with JAAScript استخدام HTMX لتنفيذ a مُخبأ/ / / / وإحدى المسائل المعلقة هي كيفية تحميلها للصفحات.

المشكلة

المسألة هي أنني كنت أستخدم HTMX AJAX للقيام بصفحة التحميل المطلوبة بمجرد أن كنت قد اخترت النتيجة من أسفل الصفحة. هذه فقط ليندا عملت.

  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'
                });
            });

المسألة كانت أنه في حين أن هذا سيحمّل الصفحة اليمنى ويُحدّث الURL المعروض مع الـ الجديد، فإنه يفسد زر الخلف. كما أن الصفحة لم تكن محملة في التاريخ بشكل صحيح.

بما في ذلك ما يتعلق بما يلي: مقالة الأخيرة على زر الرجوع هذا كان شيئاً أردت أن أصلحه

الإحلال

وكما هو الحال في السابق كان الحل هو السماح HTMX التعامل مع هذا مباشرة. للقيام بذلك قمت بتحديث نموذجي الذي أستخدمه من أجل نتائج البحث.

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

سوف ترى أنني الآن توليد (بآلاف دولارات الولايات المتحدة) وصلات HTMX في هذا العنصر الكود. السماح لنا باستخدام السلوك الصحيح HTMX.

typeahead.js

إلى تمكين بوصة خلفي جافاسكربت رمز أنا إضافة التالي إلى بحث طريقة. الـ this.$nextTick Alpins.js هو عبارة عن إنشاءات الألب.js التي تؤخر هذا إلى أن تنتهي الألبين من معالجة القالب الذي عرضته أعلاه.

ثم استخدم htmx.process() على عنصر البحث الذي سيضمن عمل خصائص HTMX كما هو متوقع.


.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");
                });
        }
في وقت لاحق عند اختيار صفحة، أعالج الرمز لاختيار الصفحة، انقر على الوصلة، اوضح النتائج (لإغلاق مربع البحث).
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
            });
        }

هذا مُنتقى من يعمل انقر من وصلة بوصة ابحث نتائج.

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

أيهما سيحمّل بعد ذلك الصفحة ويقوم بتحديث URL على النحو الصحيح.

لدي أيضاً شفرة في صندوق الأب تسمح لك باستخدام المفاتيح السهمية و الدخول

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

سترى أن هذا يحتوي على كل الشفرة الضرورية لتمكينكم من مجرد ضرب الدخول والإبحار إلى الصفحة المختارة.

في الإستنتاج

مجرد مقالة تحديث سريعة لإسقاطات البحث الحالية لتعزيز تجربة المستخدم عند استخدام البحث. مرة أخرى هذا هو مستخدم MinIMAL يواجه التغيير ولكن مجرد تحسين تجربة المستخدم؛ الذين كمطور الويب هم اهتمامك الرئيسي (بعد الحصول على أجر:)).

logo

©2024 Scott Galloway