مُخفِز مُنْزِل البحث مع HTMX (العربية (Arabic))

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

Comments

NOTE: Apart from English (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

//

4 minute read

أولاً

في وظيفة سابقة عرضت عليك كيفية إنشاء إسقاطات بحثية باستخدام 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