Back to "एचटीएमएस एक्सटेंशनों का एक Whistle-stop टूर और ASP के साथ 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

ASP.NET Core HTMX Javascript

एचटीएमएस एक्सटेंशनों का एक Whistle-stop टूर और ASP के साथ HTMX का उपयोग

Friday, 02 May 2025

परिचय

एचटीएमएस एक शक्तिशाली जावास्क्रिप्ट लाइब्रेरी है जो आपको न्यूनतम JavaScript के साथ गतिशील वेब अनुप्रयोग बनाने की अनुमति देता है।

परन्तु मैं अभी भी यह दावा नहीं करता कि मैं इसके बारे में विशेषज्ञ ज्ञान रखता हूँ।

अनुषंगी अनुच्छेद इस लेख में HTMX' के घटना प्रणाली पर ध्यान दिया गया है। ASP के साथ HTMX.

घटनाएँ

अनुरोध तैयार करना

अनुरोध तैयारी चरण यह है जहाँ एचटीएमएस सर्वर को भेजने से पहले अनुरोध को कॉन्फ़िगर करता है।

flowchart LR

        A[htmx:configRequest] --> B[htmx:confirm] --> C[htmx:prompt] --> D[htmx:abort]

अनुरोध जीवन चक्र

अनुरोध जीवन चक्र चरण है जहां HTMX सर्वर को अनुरोध भेजता है और प्रतिक्रिया का कार्य करता है

flowchart LR
 E[htmx:beforeRequest] --> F[htmx:request] --> G[htmx:afterRequest]

प्रतिक्रिया प्रबंधन

प्रतिक्रिया प्रबंधन चरण है जहां HTMX सर्वर से प्रतिक्रिया को प्रक्रमित करता है और DOM को अद्यतन करता है

flowchart LR
        H[htmx:beforeOnLoad] --> I[htmx:onLoad]
        I --> J[htmx:beforeSwap] --> K[htmx:swap] --> L[htmx:afterSwap]
        L --> M[htmx:afterSettle] --> N[htmx:afterOnLoad]

इतिहास प्रबंधन

इतिहास प्रबंधन चरण है जहां एचटीएमएस ब्राउज़र इतिहास और यूआरएल को अद्यतन करता है

flowchart LR
 A[htmx:historyRestoreRequest]
 A --> B[htmx:historyPopped]
 B --> C[htmx:historyRestorePage]

जैसा कि आप देख सकते हैं, एचटीएमएस कई घटनाएं प्रदान करता है जिन्हें आप अनुरोध या प्रतिक्रिया को बदलने के लिए जोड़ सकते हैं।

एक्सटेंशन

एचटीएमएक्स के सबसे शक्तिशाली पहलुओं में से एक है करने की क्षमता विस्तार बनाएँ अपनी क्षमताओं को विस्तारित करने के लिए. मेरे मामले में htmx:configRequest अनुरोध में अतिरिक्त पैरामीटर जोड़ने के लिए. यह उपयोगी है जब आप बिना एचटीएमएल या जावास्क्रिप्ट कोड को परिवर्धित करने के अतिरिक्त डेटा सर्वर को पास करना चाहते हैं

अन्य एक्सटेंशन हो सकता है htmx:beforeRequest अनुरोध को भेजने से पहले परिवर्धित करने के लिए बाद अधिकतर अन्य एक्सटेंशन जो हैक configRequest; जैसा कि beforeRequest जैसे HX-Vals और HX-Includeके लिए पहले से ही जुड़ा है (या तो पैयलोड में | \ | क्वेरीस्ट्रिंग आप भी हैक कर सकते हैं htmx:afterSwap कार्यों को निष्पादित करने के बाद सामग्री swapped किया गया है. क्लाइंट साइड टेम्पलेटिंग लाइब्रेरी जैसे साथ संयोजित एल्पीन या लीट आप न्यूनतम कोड के साथ शक्तिशाली गतिशील अनुप्रयोग बना सकते हैं

एचटीएमएस कुछ निर्मित ध्वनि विस्तार प्रदान करता है जैसे hx-boost और hx-swap-oob जो आप को किसी भी पसंदीदा कोड लिखने के बिना HTMX की कार्यक्षमता में वृद्धि करने के लिए अनुमति देता है

उदाहरण के लिए, आप अपने अनुरोधों में मनपसंद हेडर जोड़ना चाहते हैं

इस को प्राप्त करने के लिए HTMX आपको कुछ उपयोगी इंटीग्रेशन बिंदुएँ प्रदान करता है


{
  /**
   * init(api)
   * Called once when the extension is initialized.
   * Use it to set up internal state, store references, or access HTMX utility functions via the api parameter.
   */
  init: function(api) {
    return null;
  },

  /**
   * getSelectors()
   * Returns additional CSS selectors that HTMX should monitor.
   * Useful if your extension needs to handle custom elements or dynamic behavior.
   */
  getSelectors: function() {
    return null;
  },

  /**
   * onEvent(name, evt)
   * Called on every HTMX event (e.g., htmx:beforeRequest, htmx:afterSwap).
   * Return false to cancel the event or stop propagation.
   */
  onEvent: function(name, evt) {
    return true;
  },

  /**
   * transformResponse(text, xhr, elt)
   * Modify the raw response text before it is parsed and swapped into the DOM.
   * Use this to sanitize or preprocess HTML.
   */
  transformResponse: function(text, xhr, elt) {
    return text;
  },

  /**
   * isInlineSwap(swapStyle)
   * Return true if your extension will handle this swap style manually.
   * This tells HTMX to skip default behavior.
   */
  isInlineSwap: function(swapStyle) {
    return false;
  },

  /**
   * handleSwap(swapStyle, target, fragment, settleInfo)
   * Perform custom DOM manipulation if you implement a custom swap style.
   * Return true to prevent HTMX's default swap.
   */
  handleSwap: function(swapStyle, target, fragment, settleInfo) {
    return false;
  },

  /**
   * encodeParameters(xhr, parameters, elt)
   * Modify or serialize request parameters before sending.
   * Return null to use default URL/form encoding.
   * Return a string to override with a custom payload (e.g., JSON).
   */
  encodeParameters: function(xhr, parameters, elt) {
    return null;
  }
}

एचटीएमएक्स आप कर सकते हैं pre-बाइल्ट एक्सटेंशन की एक संख्या प्रदान करता है यहाँ पढ़ो.

उदाहरण के लिए एक उपयोगी बनाया गया json-encode आपको यूआरएल के बजाय अनुरोध मुख्य भाग में JSON डेटा भेजने की अनुमति देता है आप देख सकते हैं कि यह 3 घटनाओं में जुड़ता है

  • init एक्सटेंशन सेटअप करने और HTMX API के संदर्भ को भंडारित करने के लिए -
  • onEvent सेट करने के लिए - Content-Type शीर्षिका को application/json जब अनुरोध कॉन्फ़िगर किया जा रहा है
  • encodeParameters डिफ़ॉल्ट यूआरएल को ओवरराइड करने के लिए - एनकोडेड फ़ॉर्म एनकोडिंग और पैरामीटरों को JSON के रूप में सीरियलाइज करने के लिये . यह एक स्ट्रिंग भी लौटाता है जो एचटीएमएस को डिफॉल्ट युआरएल का उपयोग करने से रोकता है
(function() {
  let api
  htmx.defineExtension('json-enc', {
    init: function(apiRef) {
      api = apiRef
    },

    onEvent: function(name, evt) {
      if (name === 'htmx:configRequest') {
        evt.detail.headers['Content-Type'] = 'application/json'
      }
    },

    encodeParameters: function(xhr, parameters, elt) {
      xhr.overrideMimeType('text/json')

      const object = {}
      parameters.forEach(function(value, key) {
        if (Object.hasOwn(object, key)) {
          if (!Array.isArray(object[key])) {
            object[key] = [object[key]]
          }
          object[key].push(value)
        } else {
          object[key] = value
        }
      })

      const vals = api.getExpressionVars(elt)
      Object.keys(object).forEach(function(key) {
        // FormData encodes values as strings, restore hx-vals/hx-vars with their initial types
        object[key] = Object.hasOwn(vals, key) ? vals[key] : object[key]
      })

      return (JSON.stringify(object))
    }
  })
})()

या और भी सरल लेकिन और अधिक HANDY hx-debug विस्तार जो एक जोड़ता है HX-Debug अनुरोध के लिए शीर्षिका. यह त्रुटिमोचन और लॉगिंग प्रयोजनों के लिए उपयोगी है

(function() {
  htmx.defineExtension('debug', {
    onEvent: function(name, evt) {
      if (console.debug) {
        console.debug(name, evt)
      } else if (console) {
        console.log('DEBUG:', name, evt)
      } else {
        throw new Error('NO CONSOLE SUPPORTED')
      }
    }
  })
})()

वहाँ ''' बहुत अधिक है ';' एक बहुत शक्तिशाली सहित क्लाइंट साइड टेम्पलेटिंग एक्सटेंशन जो आपको क्लाइंट का उपयोग करने की अनुमति देता है-साइड टेम्पलेटिंग लाइब्रेरी को HTML में लौटाए गए JSON डेटा में रूपांतरित करने के लिए प्रयोग करता है

कुछ मनपसंद विस्तार

गतिशील पंक्ति आईडी

उदाहरण के लिए एक हाल ही में परियोजना में मैं एक तालिका में पंक्तियों की संख्या को अद्यतन करने के लिए HTMX OOB स्क्वाप का प्रयोग किया यह करने के लिए मैं जानना चाहता था कि कौन सी पंक्तियाँ वर्तमान में तालिका में प्रदर्शित की जा रही हैं, तो मैंने केवल दृश्यात्मक पंक्तियों को अद्यतन किया है

एक्सटेंशन

export default {
    encodeParameters: function (xhr, parameters, elt) {
        const ext = elt.getAttribute('hx-ext') || '';
        if (!ext.split(',').map(e => e.trim()).includes('dynamic-rowids')) {
            return null; // Use default behavior
        }

        const id = elt.dataset.id;
        const approve = elt.dataset.approve === 'true';
        const minimal = elt.dataset.minimal === 'true';
        const single = elt.dataset.single === 'true';

        const target = elt.dataset.target;
        const payload = { id, approve, minimal, single };

        if (approve && target) {
            const table = document.querySelector(target);
            if (table) {
                const rowIds = Array.from(table.querySelectorAll('tr[id^="row-"]'))
                    .map(row => row.id.replace('row-', ''));
                payload.rowIds = rowIds;
            }
        }

        // Merge payload into the parameters object
        Object.assign(parameters, payload);
        return null; // Return null to continue with default URL-encoded form encoding
    }
}

इसका उपयोग

इसका उपयोग करने के लिए हमें अपने HTMX कॉन्फ़िगरेशन में एक्सटेंशन जोड़ने की जरूरत है तो अपने प्रविष्टि बिंदु js फ़ाइल में (आप को मानते हुए 'आप मॉड्यूल का उपयोग कर रहे हैं

import dynamicRowIds from "./dynamicRowIds"; // Load the file

htmx.defineExtension("dynamic-rowids", dynamicRowIds); // Register the extension

फिर किसी भी तत्व पर आप इसे उपयोग करने के लिए चाहते हैं आप जोड़ सकते है hx-ext मूल्य के साथ विशेषता dynamic-rowids.

                <button
                    hx-ext="dynamic-rowids"
                    data-target="#my-table"
                    data-id="@Model.Id"
                    data-param1="true"
                    data-param2="false"
                    data-param3="@Model.Whatever"
                    hx-post
                    hx-controller="Contoller"
                    hx-action="Action"
                >
                    <i class='bx bx-check text-xl text-white'></i>
                </button>

पैरामीज़ बनाए रखें

यह एक और सरल HTMX एक्सटेंशन है htmx:configRequest के रूप में हम अनुप्रयोग भेजने से पहले यूआरएल को परिवर्धित कर रहे हैं. यह एक्सटेंशन उपयोगी है यदि आप क्यूरीस्ट्रिंग आधारित फ़िल्टरिंग आदि का उपयोग करते हैं।

यह मौजूदा HTMX एक्सटेंशन के समान है लेकिन बिल्कुल नहीं push

एक्सटेंशन

आप देख सकते हैं कि हम hook onEvent सुनने के लिए htmx:configRequest घटना

तो हम

  • घटना को ट्रिगर करने वाले तत्व प्राप्त करें
  • प्राप्त करें preserve-params-exclude तत्व से विशेषता (यदि यह मौजूद है तो )\ और इसे कुंजियों की एक सरणी में विभाजित करने के लिए बाहर निकालने के लिए \ (\ इसलिए हम नहीं \
  • विंडो स्थान से मौजूदा यूआरएल पैरामीटर प्राप्त करें
  • अनुरोध यूआरएल से नए पैरामीटर प्राप्त करें
  • मौजूदा पैरामीटरों के माध्यम से लूप करें और जाँचें कि क्या वे बहिष्कार सूची में नहीं हैं और नए पैरामीटरों में पहले से नहीं है
  • यदि वे नहीं हैं, हम उन्हें नए पैरामीटर में जोड़ें
  • अंत में हम अनुरोध यूआरएल के लिए नए पैरामीटर सेट करें और अनुरोध के साथ जारी रखने के लिए सही लौटाएँ
export default {
    onEvent: function (name, evt) {
        if (name !== 'htmx:configRequest') return;
        const el = evt.detail.elt;
        const excludeStr = el.getAttribute('preserve-params-exclude') || '';
        const exclude = excludeStr.split(',').map(s => s.trim());

        const currentParams = new URLSearchParams(window.location.search);
        const newParams = new URLSearchParams(evt.detail.path.split('?')[1] || '');

        currentParams.forEach((value, key) => {
            if (!exclude.includes(key) && !newParams.has(key)) {
                newParams.set(key, value);
            }
        });

        evt.detail.path = evt.detail.path.split('?')[0] + '?' + newParams.toString();

        return true;
    }
};

यहाँ मैं अनिवार्य का उपयोग करता हूँ HTMX.नेट इसके टैग मददगारों के लिए. की तरह hx-controller और hx-action टैग मददगार हैं जो आपके लिए सही HTMX विशेषताएं उत्पन्न करते हैं. साथ ही hx-route-<x> पथ में पार करने के लिए मानों के लिए. यह वास्तव में उपयोगी है क्योंकि यह आपको अपने HTML में उन्हें हार्डकोड करने की बजाय विशेषताओं के लिए सही मानों को उत्पन्न करने के लिये C कूट का उपयोग करने देता है

इसका उपयोग

एक एक्सटेंशन होने के कारण यह वास्तव में उपयोग करने के लिए सरल है

पहले हमें अपने HTMX कॉन्फ़िगरेशन में एक्सटेंशन जोड़ने की जरूरत है


import preserveParams from './preserveParams.js';
htmx.defineExtension('preserve-params', preserveParams);

नोट करें: आप को पता चलेगा कि डिफ़ॉल्ट HTMX एक्सटेंशन एक्सटेंडेशन को लोड करने के लिए 'autoload' विधि का उपयोग करते हैं

// Autoloading the extension and registering it
(function() {
  htmx.defineExtension('debug', {
}

यह ऐसा करने का एक अच्छा तरीका है यदि आप HTMX को गैर मॉड्यूल वातावरण में उपयोग कर रहे हैं। import एक्सटेंशन को लोड करने के लिए कथन फिर स्पष्ट रूप से अपने विरुद्ध इसे पंजीकृत htmx उदाहरण. यह आपको पेड़ का लाभ उठाने के लिए अनुमति देता है

फिर अपने तत्व पर आप जोड़ सकते हैं hx-ext मूल्य के साथ विशेषता preserve-params और preserve-params-exclude क्रें


<a class="btn-outline-icon"
   hx-controller="MyController"
   hx-action="MyAction"
   hx-route-myparam="@MyParam"
   hx-push-url="true"
   hx-ext="preserve-params"
   preserve-params-exclude="page,sort"
   hx-target="#page-content"
   hx-swap="innerHTML show:top"
   hx-indicator>
    <i class="bx bx-search"></i>
</a>

इस मामले में कारण event.detail.path नया होना myparam इस में यह मान सेट करेगा ' हमारे नए मूल्य के साथ कि एक को बदल देगा लेकिन सभी अन्य को सुरक्षित रखें except page और sortइसलिए हम किसी भी फ़िल्टर को, जिसे हमने यूआरएल में सेट किया है, सर्वर से पास कर सकते हैं और नये अनुरोध करने पर उन्हें खो जाने के बारे में चिंता नहीं करते

ASP.NET कोर

एचटीएमएस के बारे में एक साफ बात यह है कि सर्वर के साथ इसका अधिकतर संवाद HTTP हेडरों के माध्यम से होता है।

फिर एक प्रमुख घटक यह है HTMX.नेट. कई वस्तुओं में यह उपलब्ध कराता है साफ Request HTMX अनुरोधों को पता लगाने के लिए एक्सटेंशन. यह निर्धारित करने के लिए उपयोगी है कि क्या एक अनुरोध HT MX द्वारा किया गया था या नहीं

यह भी ट्रिगर भेजने के लिए अपनी अपनी प्रक्रिया है


Response.Htmx(h => {
    h.WithTrigger("yes")
     .WithTrigger("cool", timing: HtmxTriggerTiming.AfterSettle)
     .WithTrigger("neat", new { valueForFrontEnd= 42, status= "Done!" }, timing: HtmxTriggerTiming.AfterSwap);
});

Push Urls आदि Khalid ने ASP में HTMX के साथ काम करने को आसान बनाने के लिए एक सेट एक्सटेंशन बनाने का एक महान कार्य किया

यह HTMX और ASP के साथ काम करते समय मेरे उपकरण बक्से में एक कुंजी उपकरण है इसे जाँचें

सामान्य HTMX निवेदन हेडर

यहाँ सबसे उपयोगी शीर्षिकाओं का विभाजन है HTMX प्रत्येक अनुरोध के साथ भेजता है

हेडर |----------------------------|------------------------------------------------------------------------------------------------------------------| किसी भी HTMX के लिए हमेशा सही पर सेट करें | HX अनुप्रयोग को ट्रिगर करने वाले तत्व का आईडी | HX hx से उपयोक्ता इनपुट युक्त है | HXM SK1Current-URL | जब अनुरोध आरंभ किया गया तो ब्राउज़र यूआरएल | HXM SK1History-RestoreMSC3Request | Sent as true if the request is part of a history restoration after navigation

एक्सटेंशन की मांग करें

मैं इन का अपने ASP में काफी व्यापक रूप से उपयोग करता हूँ Request.IsHtmx() , Request.IsHtmxBoosted() और Request.IsHtmxNonBoosted() आप HTMX अनुरोधों को आसानी से पता लगा सकते हैं और तदनुसार उत्तर दें

उदाहरण के लिए, मेरे पास Request की एक वास्तव में सरल विस्तार है जो मुझे पता लगाने देता है अगर एक अनुरोध मेरी मुख्य लक्ष्य कर रहा है #page-content div. यदि यह है तो मैं जानता हूँ कि मुझे एक आंशिक वापस भेजना चाहिए नोट: बहुत से नहीं मानते कि आप एक पूर्ण पृष्ठ को आंशिक रूप में निर्दिष्ट कर सकते हैं

        if (Request.PageContentTarget())
        {   
            Response.PushUrl(Request);
            return PartialView("List", vm);
        }
        return View("List", vm);
        
        public static class RequestExtensions
{
        
        public static bool PageContentTarget(this HttpRequest request)
    {
        bool isPageContentTarget = request.Headers.TryGetValue("hx-target", out var pageContentHeader) 
                                   && pageContentHeader == "page-content";
        
        return isPageContentTarget;
    }
    }

प्रतिक्रिया विस्तार

अनुप्रयोग विस्तारों के अलावा आप प्रतिक्रिया विस्तार भी बना सकते हैं ग्राहक को घटनाओं को वापस भेजने के लिए

SweetAlert उदाहरण

उदाहरण के लिए मेरे SweetAlert2 एकीकरण में मैं एक ट्रिगर के उपयोग से संवाद बंद करने को सक्षम करता हूँ जो सर्वर से सेट किया गया है

    document.body.addEventListener('sweetalert:close', closeSweetAlertLoader);

यह एक HTMX ट्रिगर घटना के रूप में सर्वर से ट्रिकर किया जाता है


    public static void CloseSweetAlert(this HttpResponse response)
    {
        response.Headers.Append("HX-Trigger" , JsonSerializer.Serialize(new
        {
            sweetalert = "close"
        }));

    }

यह ट्रिगर करेगा sweetalert:close आप संवाद बंद करने के लिए अनुमति देता है क्लाइंट पक्ष पर घटना, HX-Trigger हेडर. यह एचटीएमएल या जावास्क्रिप्ट कोड को परिवर्धित करने के बिना सर्वर से क्लाइंट को डेटा हस्तांतरित करने में उपयोगी है

जैसा कि आप देख रहे हैं, यह एक घटना श्रोता को शरीर में जोड़कर इन घटनाओं के लिए सुनने की आसान है

टॉस्ट दिखाएँ

मैं पहले अपनी टोस्ट विधि के बारे में लिखा था यहाँलेकिन यह है

    public static void ShowToast(this HttpResponse response, string message, bool success = true)
    {
        response.Headers.Append("HX-Trigger", JsonSerializer.Serialize(new
        {
            showToast = new
            {
                toast = message,
                issuccess =success
            }
        }));

    }

मैं फिर घटना क्लाइंट पक्ष में जुड़ा और मेरे कॉल showToast प्रकार्य

import { showToast, showHTMXToast } from './toast';

window.showHTMXToast = showHTMXToast;

document.body.addEventListener("showToast", showHTMXToast);

यह तब मेरे में बुलाता है showToast फ़ंक्शन और कुएँ, एक टोस्ट दिखाता है; फिर से इसके बारे में अधिक देखें अनुच्छेद में .



export function showHTMXToast(event) {
    const xhr = event?.detail?.xhr;
    let type = 'success';
    let message = xhr?.responseText || 'Done!';

    try {
        const data = xhr ? JSON.parse(xhr.responseText) : event.detail;

        if (data.toast) message = data.toast;
        if ('issuccess' in data) {
            type = data.issuccess === false ? 'error' : 'success';
        } else if (xhr?.status >= 400) {
            type = 'error';
        } else if (xhr?.status >= 300) {
            type = 'warning';
        }

    } catch {
        if (xhr?.status >= 400) type = 'error';
        else if (xhr?.status >= 300) type = 'warning';
    }

    showToast(message, 3000, type);
}

अंत में

अच्छी तरह से यह है कि HTMX और ASP का एक चक्रवात दौरा।

इस ब्लॉग पर संबंधित लेख

सहयोगी अनुच्छेद

यह लेख ASP के साथ HTMX पर दोpart श्रृंखला का हिस्सा है

  1. ASP.NET कोर भागों के साथ HTMX ASP पर ध्यान केंद्रित करता है
  2. इस लेख - HTMX घटनाओं में गहराई से डायव

अधिक HTMX लेख

आगे पढ़ने

आधिकारिक HTMX दस्तावेज़

लाइब्रेरी

सामुदायिक संसाधन

logo

© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.