مساعِد تأشير أساسي (الجزء 1 البكر - بونز) (العربية (Arabic))

مساعِد تأشير أساسي (الجزء 1 البكر - بونز)

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.

Tuesday, 11 March 2025

//

Less than a minute

أولاً

وقد استلزم مشروع عمل في اليوم الآخر تنفيذ نتائج استمارة الاستدعاء. دائماً ما كان مساعدي دائماً مُرفق مُلْخَزَجَجَزًا مُحَدَّد المُسَلِف كما كتبت عن هنا هنا لأي سبب من الأسباب أنه فقط متوقف عن العمل من أجلي من أجلي فبدلاً من محاولة فهم ما يبدو كمشروع مهجور في هذه المرحلة قررت أن أبني واحداً بنفسي.

كالعادة يمكنك الحصول على المصدر لهذا على حسابي

لدي موقع عينة لهذا المشروع يستضيف هنا

هذا يحتوي على عينات من مخرجات مثل هذا:

أنشئ مع مع مع مع منفذ

لهذا مساعد بطاقة كان لدي بعض المتطلبات:

  1. ينبغي أن تعمل جنباً إلى جنب مع ثنياط وقد عقد مؤتمراً بشأن رابعاً - الديزيأُطري المفضّلة لـ CSS.
  2. يجب أن تعمل مع HTMX دون التسبب في أي مشاكل.
  3. يجب أن يكون لديك قطرة على الصفحات التي تستخدم HTMX لتقلب (حتى إذا لم تستخدم HTMX فإنه لا يزال يعمل ولكن تحتاج إلى إضافة زر).
  4. من السهل إعداده واستخدامه
    1. يقبل a نموذج لذا هو بسيط إلى استخدام بوصة a رزّر صفحة
    2. يجب أن يكون قادراً على أن تكون مجهزة مع عدد قليل من
  5. يجب أن تكون حزمة نوتات حتى تتمكن كل الناس العظماء من اللعب بها.
  6. ينبغي أن يكون معاً مكوناً في الرؤية وعامل تأشير بحيث يمكن استخدامه في كل من صفحات و وجهات النظر؛ مع وضع ذلك في الاعتبار ينبغي أن يكون له أيضاً قابل للإزاحة Dafault.cshtml وجهة نظر.
  7. يعمل مع a بسيط ابحث الدالة.

في المستقبل سأضيف القدرة إلى:

  1. أضف مخصص CSS لتجنب أن تكون مرتبطة إلى DieseUI و Tailwind ~ لقد أضفت هذه القدرة الأمم المتحدة: https://ts://taghelfersample.soadlysliuscid.net/Home/PlainView
  2. المعاينة إلى تحديد حجم الصفحة
  3. القدرة على إضافة دعوة مُخصصة إلى حجم الصفحة نزولاً (للسماح لك بعدم استخدام HTMX).
  4. استخدم الألپ لجعل جهاز التصفح أكثر نشاطا وتجاوبا (كما فعلت في بلدي) (أ) كان).

عدد أفراد

الـ شارة هو a جديد nuget حزمة IF الإيطالية مع التالي أمر:

dotnet add package mostlylucid.pagingtaghelper

ثم تقوم بعد ذلك بإضافة مساعد بطاقة إلى _ViewImports.cshtml ملفّ مثل:

@addTagHelper *, mostlylucid.pagingtaghelper

ثم يمكنك فقط البدء باستخدامه، انا اوفر بعض فئات المساعدين التي يمكنك استخدامها لضبطها مثل

IPagingModel

هذه هي "الأشياء الأساسية" التي تحتاجها للبدء. إنّها واجهة بسيطة يمكنك تنفيذها على نموذجك لتُشغّل النشوء. ملاحظة ملاحظة ViewType هو اختياري هنا هو افتراضي إلى TailwindANdDaisy « ولكن يمكنك أن تجعلها » أي خلقها « إلى صرها » أي خلقها. Custom, Plain أو Bootstrap إذا كنت تريد استخدام وجهة نظر مختلفة.

public enum ViewType
{
TailwindANdDaisy,
Custom,
Plain,
Bootstrap
}

لا يمكنك ذلك في هذه الحالة تحديد مخصص مُرفق باستخدام مُعلام use-local-view (أ) أو الممتلكات الخاصة بها.

namespace mostlylucid.pagingtaghelper.Models;

public interface IPagingModel
{
    public int Page { get; set; }
    public int TotalItems { get; set; }
    public int PageSize { get; set; }

    public ViewType ViewType { get; set; }
    
    public string LinkUrl { get; set; }
}
namespace mostlylucid.pagingtaghelper.Models;

public interface IPagingSearchModel : IPagingModel
{
    public string? SearchTerm { get; set; }
}

وقد نفذت أيضاً هذه في المشروع لتوفير خط أساس:

public abstract class BasePagerModel : IPagingModel
{
    public int Page { get; set; } = 1;
    public int TotalItems { get; set; } = 0;
    public int PageSize { get; set; } = 10;
    public ViewType ViewType { get; set; } = ViewType.TailwindANdDaisy;

    public string LinkUrl { get; set; } = "";

}
public abstract class BasePagerSearchMdodel : BasePagerModel, IPagingSearchModel
{
    public string? SearchTerm { get; set; }
}

سأغطي وظيفة البحث في مقال مستقبلي

الـ مُجل المُلْف

بعد ذلك عملت على ما أريد أن يبدو الـ Tagfilder كما لو كان مستخدماً:

<paging
    x-ref="pager"
    hx-boost="true"
    hx-indicator="#loading-modal"
    hx-target="#user-list "
    hx-swap="show:none"
    model="Model"
    pages-to-display="10"
    hx-headers='{"pagerequest": "true"}'>
</paging>

هنا يمكنك أن ترى أنا تعيين عدد قليل من بارامترات HTMX والنموذج إلى استخدام لـ. وأنا أيضاً أضع عدد الصفحات التي يجب عرضها والترويسات التي يجب إرسالها مع الطلب (هذا يسمح لي باستخدام HTMX لاستبدال الصفحة).

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

<paging css-class=""
        first-last-navigation=""
        first-page-text=""
        next-page-aria-label=""
        next-page-text=""
        page=""
        pages-to-display=""
        page-size=""
        previous-page-text=""
        search-term=""
        skip-forward-back-navigation=""
        skip-back-text=""
        skip-forward-text="true"
        total-items=""
        link-url=""
        last-page-text=""
        show-pagesize=""
        use-htmx=""
        use-local-view=""
        view-type="Bootstrap"
        htmx-target=""
        id=""
></paging>

الـ مُوازِل هذا هو بسيط جداً لكن لديه مجموعة من الخصائص التي تمكّن المستخدم من تخصيص هذا السلوك (يُمْكِنك أن ترى هذا أسفله في الـ الرأي بعيداً عن الخصائص (التي لن ألصقها هنا للإيجاز) الشفرة واضحة إلى حد ما:

    /// <summary>
    /// Processes the tag helper to generate the pagination component.
    /// </summary>

    /// <param name="context">The tag helper context.</param>
    /// <param name="output">The tag helper output.</param>
    public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
    {
   
        output.TagName = "div";
        
        //Remove all the properties that are not needed for the rendered content.
        output.Attributes.RemoveAll("page");
        output.Attributes.RemoveAll("link-url");
        output.Attributes.RemoveAll("page-size");
        output.Attributes.RemoveAll("total-items");
        output.Attributes.RemoveAll("pages-to-display");
        output.Attributes.RemoveAll("css-class");
        output.Attributes.RemoveAll("first-page-text");
        output.Attributes.RemoveAll("previous-page-text");
        output.Attributes.RemoveAll("skip-back-text");
        output.Attributes.RemoveAll("skip-forward-text");
        output.Attributes.RemoveAll("next-page-text");
        output.Attributes.RemoveAll("next-page-aria-label");
        output.Attributes.RemoveAll("last-page-text");
        output.Attributes.RemoveAll("first-last-navigation");
        output.Attributes.RemoveAll("skip-forward-back-navigation");
        output.Attributes.RemoveAll("model");
        output.Attributes.RemoveAll("show-pagesize");
        output.Attributes.RemoveAll("pagingmodel");
        output.Attributes.RemoveAll("use-local-view");
        
        var pagerId =  PagerId ?? $"pager-{Guid.NewGuid():N}";
        var linkUrl = LinkUrl ?? ViewContext.HttpContext.Request.Path;
        PageSize = Model?.PageSize ?? PageSize ?? 10;
        Page = Model?.Page ?? Page ?? 1;
        ViewType = Model?.ViewType ?? ViewType;
        TotalItems = Model?.TotalItems ?? TotalItems ?? 0;
        if(Model is IPagingSearchModel searchModel)
            SearchTerm = searchModel?.SearchTerm ?? SearchTerm ?? "";
        output.Attributes.SetAttribute("id", pagerId);
        var viewComponentHelper = (IViewComponentHelper)ViewContext.HttpContext.RequestServices.GetService(typeof(IViewComponentHelper))!;
        ((IViewContextAware)viewComponentHelper).Contextualize(ViewContext);

        var pagerModel = PagerModel ?? new PagerViewModel()
        {
            
            ViewType = ViewType,
            UseLocalView = UseLocalView,
            UseHtmx = UseHtmx,
            PagerId = pagerId,
            SearchTerm = SearchTerm,
            ShowPageSize = ShowPageSize,
            Model = Model,
            LinkUrl = linkUrl,
            Page = Page,
            PageSize = PageSize,
            TotalItems = TotalItems,
            PagesToDisplay = PagesToDisplay,
            CssClass = CssClass,
            FirstPageText = FirstPageText,
            PreviousPageText = PreviousPageText,
            SkipBackText = SkipBackText,
            SkipForwardText = SkipForwardText,
            NextPageText = NextPageText,
            NextPageAriaLabel = NextPageAriaLabel,
            LastPageText = LastPageText,
            FirstLastNavigation = FirstLastNavigation,
            SkipForwardBackNavigation = SkipForwardBackNavigation,
            HtmxTarget = HtmxTarget,
            
        };

        var result = await viewComponentHelper.InvokeAsync("Pager", pagerModel);
        output.Content.SetHtmlContent(result);
    }

وتشمل هذه الخطوات ما يلي:

  1. divهذه هي الحاوية للجهاز.
  2. احذف الكل خصائص ليس مطلوب لـ محتوى لكن ترك مستخدم مزوّد واحد هذا لـ بسيط مخصّص.
  3. ضبط إلى a عشوائيّ IF هذا هو مُستخدَم لـ مُعَدّ، أنت يمكن تحديد معرف أو فقط دع هذا الكود يعتني به.
  4. اضبط الدالة unitle underlow to the title that this unitle to under this IF إلى استخدام a مختلف URL.
  5. ضبط صفحةSize, page, viewType, talumems and profile or or profile to the profile IF أو افتراضي if not. هذا يمكّننا من أن نمر فقط في IPagingModel و يعمل جهاز الاستدعاء مع عدم وجود تشكيلات أخرى.
  6. اضبط معرف إلى المُشَغِّل.
  7. احصل على مساعد عنصر العرض من الحاوية DI ووضعه في سياق مع الحالي procon contract.
  8. إنشاء PagerViewModel مع خصائص set إلى القيم لدينا أو افتراضي IF ليس.
  9. في حالة تَرْفِق Pager مع PagerViewModel ضبط مخرجات المحتوى إلى النتيجة.

مرة أخرى كل شيء بسيط جدا.

مُرفق

وجهة النظر لمكون العرض بسيطة جداً، انها مجرد حلقة من خلال الصفحات و القليل من الوصلات للصفحات الأولى والأخيرة والتالية والسابقة.

Complete source code for the Default TailwindUI & Daisy view
@model mostlylucid.pagingtaghelper.Components.PagerViewModel
@{
    var totalPages = (int)Math.Ceiling((double)Model.TotalItems! / (double)Model.PageSize!);
    var pageSizes = new List<int>();
    if (Model.ShowPageSize)
    {
        // Build a dynamic list of page sizes.

        // Fixed steps as a starting point.
        int[] fixedSteps = { 10, 25, 50, 75, 100, 125, 150, 200, 250, 500, 1000 };

        // Add only those fixed steps that are less than or equal to TotalItems.
        foreach (var step in fixedSteps)
        {
            if (step <= Model.TotalItems)
            {
                pageSizes.Add(step);
            }
        }

        // If TotalItems is greater than the largest fixed step,
        // add additional steps by doubling until reaching TotalItems.
        if (Model.TotalItems > fixedSteps.Last())
        {
            int next = fixedSteps.Last();
            while (next < Model.TotalItems)
            {
                next *= 2;
                // Only add if it doesn't exceed TotalItems.
                if (next < Model.TotalItems)
                {
                    pageSizes.Add(next);
                }
            }

            // Always include the actual TotalItems as the maximum option.
            if (!pageSizes.Contains(Model.TotalItems.Value))
            {
                pageSizes.Add(Model.TotalItems.Value);
            }
        }
    }
}
@if (totalPages > 1)
{
    <div class="@Model.CssClass flex items-center justify-center" id="pager-container">
        @if (Model.ShowPageSize)
        {
            var pagerId = Model.PagerId;
            var htmxAttributes = Model.UseHtmx
                ? $"hx-get=\"{Model.LinkUrl}\" hx-trigger=\"change\" hx-include=\"#{pagerId} [name='page'], #{pagerId} [name='search']\" hx-push-url=\"true\""
                : "";


            <!-- Preserve current page -->
            <input type="hidden" name="page" value="@Model.Page"/>
            <input type="hidden" name="search" value="@Model.SearchTerm"/>
            <input type="hidden" class="useHtmx" value="@Model.UseHtmx.ToString().ToLowerInvariant()"/>
            if (!Model.UseHtmx)
            {
                <input type="hidden" class="linkUrl" value="@Model.LinkUrl"/>
            }

            <!-- Page size select with label -->
            <div class="flex items-center mr-8">
                <label for="pageSize-@pagerId" class="text-sm text-gray-600 mr-2">Page size:</label>
                <select id="pageSize-@pagerId"
                        name="pageSize"
                        class="border rounded select select-primary select-sm pt-0 mt-0 min-w-[80px] pr-4"
                        @Html.Raw(htmxAttributes)>
                    @foreach (var option in pageSizes.ToList())
                    {
                        var optionString = option.ToString();
                        if (option == Model.PageSize)
                        {
                            <option value="@optionString" selected="selected">@optionString</option>
                        }
                        else
                        {
                            <option value="@optionString">@optionString</option>
                        }
                    }
                </select>
            </div>
        }

        @* "First" page link *@
        @if (Model.FirstLastNavigation && Model.Page > 1)
        {
            var href = $"{Model.LinkUrl}?page=1&pageSize={Model.PageSize}";
            if (!string.IsNullOrEmpty(Model.SearchTerm))
            {
                href += $"&search={Model.SearchTerm}";
            }

            <a class="btn btn-sm"
               href="@href">
                @Model.FirstPageText
            </a>
        }

        @* "Previous" page link *@
        @if (Model.Page > 1)
        {
            var href = $"{Model.LinkUrl}?page={Model.Page - 1}&pageSize={Model.PageSize}";
            if (!string.IsNullOrEmpty(Model.SearchTerm))
            {
                href += $"&search={Model.SearchTerm}";
            }

            <a class="btn btn-sm"
               href="@href">
                @Model.PreviousPageText
            </a>
        }

        @* Optional skip back indicator *@
        @if (Model.SkipForwardBackNavigation && Model.Page > Model.PagesToDisplay)
        {
            <a class="btn btn-sm btn-disabled">
                @Model.SkipBackText
            </a>
        }

        @* Determine visible page range *@
        @{
            int halfDisplay = Model.PagesToDisplay / 2;
            int startPage = Math.Max(1, Model.Page.Value - halfDisplay);
            int endPage = Math.Min(totalPages, startPage + Model.PagesToDisplay - 1);
            startPage = Math.Max(1, endPage - Model.PagesToDisplay + 1);
        }
        @for (int i = startPage; i <= endPage; i++)
        {
            var href = $"{Model.LinkUrl}?page={i}&pageSize={Model.PageSize}";
            if (!string.IsNullOrEmpty(Model.SearchTerm))
            {
                href += $"&search={Model.SearchTerm}";
            }

            <a data-page="@i" class="btn btn-sm mr-2 @(i == Model.Page ? "btn-active" : "")"
               href="@href">
                @i
            </a>
        }

        @* Optional skip forward indicator *@
        @if (Model.SkipForwardBackNavigation && Model.Page < totalPages - Model.PagesToDisplay + 1)
        {
            <a class="btn btn-sm btn-disabled mr-2">
                @Model.SkipForwardText
            </a>
        }

        @* "Next" page link *@
        @if (Model.Page < totalPages)
        {
            var href = $"{Model.LinkUrl}?page={Model.Page + 1}&pageSize={Model.PageSize}";
            if (!string.IsNullOrEmpty(Model.SearchTerm))
            {
                href += $"&search={Model.SearchTerm}";
            }

            <a class="btn btn-sm mr-2"
               href="@href"
               aria-label="@Model.NextPageAriaLabel">
                @Model.NextPageText
            </a>
        }

        @* "Last" page link *@
        @if (Model.FirstLastNavigation && Model.Page < totalPages)
        {
            var href = $"{Model.LinkUrl}?page={totalPages}&pageSize={Model.PageSize}";
            if (!string.IsNullOrEmpty(Model.SearchTerm))
            {
                href += $"&search={Model.SearchTerm}";
            }

            <a class="btn btn-sm"
               href="@href">
                @Model.LastPageText
            </a>
        }

        <!-- Page info text with left margin for separation -->
        <div class="text-sm text-neutral-500 ml-8">
            Page @Model.Page of @totalPages (Total items: @Model.TotalItems)
        </div>
    </div>
}
هذا مقسم إلى عدة أقسام:
  1. حجم الصفحة المخفضة
  2. الأول، الأخير، التالي، السابق
  3. التجاوز إلى الخلف و التجاوز إلى الأمام وصلات
  4. الـ صفحة وصلات
  5. الـ صفحة info نص

حجم الصفحة

شيء واحد كنت في عداد المفقودين من مساعدة العلامة الأصلية كان انخفاض حجم الصفحة. هذه قائمة مُنتف بسيطة، يمكنك أن ترى أنني سأبدأ أولاً بـ fixedSteps التي هي مجرد بضع خطوات ثابتة أريد استخدامها للهبوط. ثم ادور من خلال هذه واضيفها الى القائمة عادة لدي دائماً هي أن يكون لدي خيار 'كل' لذا أضيف مجموع العناصر إلى القائمة إذا لم تكن موجودة بالفعل.

@{
    var totalPages = (int)Math.Ceiling((double)Model.TotalItems! / (double)Model.PageSize!);
    var pageSizes = new List<int>();
    if (Model.ShowPageSize)
    {
        // Build a dynamic list of page sizes.

        // Fixed steps as a starting point.
        int[] fixedSteps = { 10, 25, 50, 75, 100, 125, 150, 200, 250, 500, 1000 };

        // Add only those fixed steps that are less than or equal to TotalItems.
        foreach (var step in fixedSteps)
        {
            if (step <= Model.TotalItems)
            {
                pageSizes.Add(step);
            }
        }

        // If TotalItems is greater than the largest fixed step,
        // add additional steps by doubling until reaching TotalItems.
        if (Model.TotalItems > fixedSteps.Last())
        {
            int next = fixedSteps.Last();
            while (next < Model.TotalItems)
            {
                next *= 2;
                // Only add if it doesn't exceed TotalItems.
                if (next < Model.TotalItems)
                {
                    pageSizes.Add(next);
                }
            }

            // Always include the actual TotalItems as the maximum option.
            if (!pageSizes.Contains(Model.TotalItems.Value))
            {
                pageSizes.Add(Model.TotalItems.Value);
            }
        }
    }
}

ثم اوضح هذا الى الصفحة

  @if (Model.ShowPageSize)
        {
            var pagerId = Model.PagerId;
            var htmxAttributes = Model.UseHtmx
                ? $"hx-get=\"{Model.LinkUrl}\" hx-trigger=\"change\" hx-include=\"#{pagerId} [name='page'], #{pagerId} [name='search']\" hx-push-url=\"true\""
                : "";


            <!-- Preserve current page -->
            <input type="hidden" name="page" value="@Model.Page"/>
            <input type="hidden" name="search" value="@Model.SearchTerm"/>
            <input type="hidden" class="useHtmx" value="@Model.UseHtmx.ToString().ToLowerInvariant()"/>
            if (!Model.UseHtmx)
            {
                <input type="hidden" class="linkUrl" value="@Model.LinkUrl"/>
            }

            <!-- Page size select with label -->
            <div class="flex items-center mr-8">
                <label for="pageSize-@pagerId" class="text-sm text-gray-600 mr-2">Page size:</label>
                <select id="pageSize-@pagerId"
                        name="pageSize"
                        class="border rounded select select-primary select-sm pt-0 mt-0 min-w-[80px] pr-4"
                        @Html.Raw(htmxAttributes)>
                    @foreach (var option in pageSizes.ToList())
                    {
                        var optionString = option.ToString();
                        if (option == Model.PageSize)
                        {
                            <option value="@optionString" selected="selected">@optionString</option>
                        }
                        else
                        {
                            <option value="@optionString">@optionString</option>
                        }
                    }
                </select>
            </div>
        }

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

إذا كنت مُنَظِف use-htmx=false معلمة على مساعد بطاقة هو لَنْ يُخرجَ هذه لكن بدلاً مِنْ ذلك سَيَسْمحُ لك بإستعمال البعضِ JS I يُزوّدُ كمساعد HTML لتحديث حجم الصفحةِ.

@Html.PageSizeOnchangeSnippet()
    

هذا نص بسيط سيقوم بتحديث حجم الصفحة وإعادة تحميل الصفحة (لاحظ أن هذا لا يعمل حتى الآن لـ بسيط CSS/ Botstrap كما أحتاج إلى العمل على أسماء الممتلكات وما إلى ذلك).

document.addEventListener("DOMContentLoaded", function () {
    document.body.addEventListener("change", function (event) {
        const selectElement = event.target.closest("#pager-container select[name='pageSize']");
        if (!selectElement) return;

        const pagerContainer = selectElement.closest("#pager-container");
        const useHtmxInput = pagerContainer.querySelector("input.useHtmx");
        const useHtmx = useHtmxInput ? useHtmxInput.value === "true" : true; // default to true

        if (!useHtmx) {
            const pageInput = pagerContainer.querySelector("[name='page']");
            const searchInput = pagerContainer.querySelector("[name='search']");

            const page = pageInput ? pageInput.value : "1";
            const search = searchInput ? searchInput.value : "";
            const pageSize = selectElement.value;
            const linkUrl =  pagerContainer.querySelector("input.linkUrl").value ?? "";
            
            const url = new URL(linkUrl, window.location.origin);
            url.searchParams.set("page", page);
            url.searchParams.set("pageSize", pageSize);

            if (search) {
                url.searchParams.set("search", search);
            }

            window.location.href = url.toString();
        }
    });
});

HTMX

دمج HTMX بسيط جداً لأن HTMX هو متعاقب إلى عناصر الطفل يمكننا تعريف بارامترات HTMX على عنصر الأم وسوف ترث.

  • hx-boost="true" - هذا استخدام النفعية (حجج)- (ميزة) لاعتراض الحدث النقري وإرسال الطلب عبر HTMX.
  • Hx- indicator="# التحميل- واسطة" - هذا يحتوي على نمط التحميل الذي سيظهر بينما الطلب يتم تجهيزه.
  • هذا هو element الردّ سيتم مبادلته، في هذه الحالة قائمة المستخدم. ملاحظة: هذا يشمل حالياً صفحة للبساطة؛ يمكنك أن تجعل هذا أكثر نشاطاً باستخدام الألب (كما هو الحال بالنسبة لي). المادة السابقة لكنه كان خارج النطاق هذه المرة.
  • shx-swap="العرض: لا يوجد"

الـ تحميل معدّل

هذا بسيط جداً و يستخدم ديزي أويل و الكوبيكونات و تايل ويند لخلق نمط تحميل بسيط

<div id="loading-modal" class="modal htmx-indicator">
    <div class="modal-box flex flex-col items-center justify-center">
        <h2 class="text-lg font-semibold">Loading...</h2>
        <i class="bx bx-loader bx-spin text-3xl mt-2"></i>
    </div>
</div>

الدالة hx- indicator="# التحميل- واسطة" ثم تحدد أنه عندما يتم تنفيذ طلب HTMX فإنه يظهر shoold ثم إخفاء هذا الواسطة.

رابعاً - الندوات في المستقبل

اذاً هذا هو الجزء 1، من الواضح ان هناك الكثير مما يمكن تغطيته وسوف اقوم به في المقالات المقبلة، بما في ذلك موقع العينة، وجهات النظر البديلة،

logo

©2024 Scott Galloway