Htmxλ λμμ μμ νκ³ κ°μ νλ λ° μ¬μ©ν μ μλ κ΄λ²μν μ΄λ²€νΈ μμ€ν μ μ 곡ν©λλ€. μ΄λ²€νΈλ λ€μκ³Ό κ°μ΅λλ€.
htmx:abortμ΄ μ΄λ²€νΈλ λ€λ₯Έ μ΄λ²€νΈμ λ¬λ¦¬ htmxκ° νΈλ¦¬κ±°νμ§ μκ³ λκΈ°νλ€λ μ μμ λ€λ¦ λλ€.
μμ²μ νλ μμμ htmx:abort μ΄λ²€νΈλ₯Ό 보λ΄λ©΄ μμ²μ μ€λ¨ν©λλ€:
<button id="request-button" hx-post="/example">Issue Request</button>
<button onclick="htmx.trigger('#request-button', 'htmx:abort')">Cancel Request</button>
htmx:afterOnLoadμ΄ μ΄λ²€νΈλ AJAX onloadκ° μλ£λ νμ νΈλ¦¬κ±°λ©λλ€.
μ΄λ μ½ν
μΈ κ° μμ§ κ΅μ²΄λκ±°λ μ 리λμμμ μλ―Ένλ κ²μ΄ μλλΌ μμ²μ΄ μλ£λμμμ μλ―Ένλ€λ μ μ μ μνμΈμ.
detail.elt - μμ²μ λ³΄λΈ μμdetail.xhr - the XMLHttpRequestdetail.target - μμ² λμdetail.requestConfig - AJAX μμ²μ ꡬμ±htmx:afterProcessNodeμ΄ μ΄λ²€νΈλ htmxκ° DOM λ Έλλ₯Ό μ΄κΈ°νν νμ νΈλ¦¬κ±°λ©λλ€. νμ₯ νλ‘κ·Έλ¨μ΄ λ Έλμ μΆκ° κΈ°λ₯μ λΉλνλ € ν λ μ μ©ν μ μμ΅λλ€.
detail.elt - μμ²μ λ³΄λΈ μμhtmx:afterRequestμ΄ μ΄λ²€νΈλ μμ²μ΄ μ±κ³΅ν κ²½μ°(404μ κ°μ μ격 μ€λ₯ μ½λλ₯Ό λ°ννμ μ μμ) λλ
λ€νΈμν¬ μ€λ₯ μν©μμ AJAX μμ²μ΄ μλ£λ νμ νΈλ¦¬κ±°λ©λλ€. μ΄ μ΄λ²€νΈλ μμ² μ£ΌκΈ°μ λ°λΌ
λμμ wrapνκΈ° μν΄ htmx:beforeRequestμ ν¨κ» μ¬μ©ν μ μμ΅λλ€.
detail.elt - μμ²μ λ³΄λΈ μμdetail.xhr - the XMLHttpRequestdetail.target - μμ² λμdetail.requestConfig - AJAX μμ²μ ꡬμ±detail.successful - μλ΅μ 20x μν μ½λκ° μκ±°λ htmx:beforeSwap μ΄λ²€νΈμμ detail.isError = falseλ‘ νμλλ©΄ trueμ΄κ³ , κ·Έλ μ§ μμΌλ©΄ falseμ
λλ€.
htmx:beforeSwap event, else falsedetail.failed - μλ΅μ 20x μν μ½λκ° μκ±°λ htmx:beforeSwap μ΄λ²€νΈμμ detail.isError = trueλ‘ νμλ κ²½μ° true, κ·Έλ μ§ μμΌλ©΄ falseμ
λλ€.htmx:afterSettleμ΄ μ΄λ²€νΈλ DOMμ΄ μ 리λ νμ νΈλ¦¬κ±°λ©λλ€.
detail.elt - μμ²μ λ³΄λΈ μμdetail.xhr - the XMLHttpRequestdetail.target - μμ² λμdetail.requestConfig - AJAX μμ²μ ꡬμ±htmx:afterSwapμ΄ μ΄λ²€νΈλ DOMμμμ κ΅μ²΄κ° μΌμ΄λ νμ νΈλ¦¬κ±°λ©λλ€.
detail.elt - μμ²μ λ³΄λΈ μμdetail.xhr - the XMLHttpRequestdetail.target - μμ² λμdetail.requestConfig - AJAX μμ²μ ꡬμ±htmx:beforeCleanupElementμ΄ μ΄λ²€νΈλ htmxκ° μμλ₯Ό λΉνμ±ννκ±°λ DOMμμ μ κ±°νκΈ° μ μ νΈλ¦¬κ±°λ©λλ€.
detail.elt - μ 리λ μμhtmx:beforeOnLoadμ΄ μ΄λ²€νΈλ μλ΅ μ²λ¦¬κ° λ°μνκΈ° μ μ νΈλ¦¬κ±°λ©λλ€. μ΄λ²€νΈκ° μ·¨μλλ©΄ κ΅μ²΄κ° λ°μνμ§ μμ΅λλ€.
detail.elt - μμ²μ λ³΄λΈ μμdetail.xhr - the XMLHttpRequestdetail.target - μμ² λμdetail.requestConfig - AJAX μμ²μ ꡬμ±htmx:beforeProcessNodeμ΄ μ΄λ²€νΈλ htmxκ° DOM λ
Έλλ₯Ό μ΄κΈ°ννκ³ λͺ¨λ hx- μμ±μ μ²λ¦¬νκΈ° μ μ νΈλ¦¬κ±°λ©λλ€. μ΄λ₯Ό ν΅ν΄ νμ₯ νλ‘κ·Έλ¨ λ° κΈ°ν μΈλΆ μ½λκ° μ²λ¦¬λκΈ° μ μ DOM λ
Έλμ λ΄μ©μ μμ ν μ μμ΅λλ€.
detail.elt - μμ²μ λ³΄λΈ μμhtmx:beforeRequestμ΄ μ΄λ²€νΈλ AJAX μμ²μ΄ 보λ΄μ§κΈ° μ μ νΈλ¦¬κ±°λ©λλ€. μ΄λ²€νΈκ° μ·¨μλλ©΄ μμ²μ΄ λ°μνμ§ μμ΅λλ€.
detail.elt - μμ²μ λ³΄λΈ μμdetail.xhr - the XMLHttpRequestdetail.target - μμ² λμdetail.requestConfig - AJAX μμ²μ ꡬμ±htmx:beforeSendμ΄ μ΄λ²€νΈλ μμ²μ΄ μ μ‘λκΈ° μ§μ μ νΈλ¦¬κ±°λ©λλ€. μ΄ μ΄λ²€νΈκ° λ°μνλ©΄ μμ²μ μ·¨μν μ μμ΅λλ€.
detail.elt - μμ²μ λ³΄λΈ μμdetail.xhr - the XMLHttpRequestdetail.target - μμ² λμdetail.requestConfig - AJAX μμ²μ ꡬμ±htmx:beforeSwapμ΄ μ΄λ²€νΈλ μ μ½ν μΈ κ° DOM μμμ κ΅μ²΄κ° μ΄λ£¨μ§κΈ° μ μ νΈλ¦¬κ±°λ©λλ€. μ΄λ²€νΈκ° μ·¨μλλ©΄ κ΅μ²΄κ° λ°μνμ§ μμ΅λλ€.
μ΄λ²€νΈ μΈλΆμ 보μ shouldSwap λ° target propertyλ₯Ό μμ νμ¬ κΈ°λ³Έ κ΅μ²΄ λμμ μμ ν μ μμ΅λλ€.
μμΈν λ΄μ©μ κ΅μ²΄ μμ
ꡬμ±μ λν λ¬Έμλ₯Ό μ°Έμ‘°νμΈμ.
detail.elt - μμ²μ λ³΄λΈ μμdetail.xhr - the XMLHttpRequestdetail.requestConfig - AJAX μμ²μ ꡬμ±detail.shouldSwap - κ΅μ²΄λ μ½ν
μΈ (200μ΄ μλ μλ΅ μ½λμ κ²½μ° κΈ°λ³Έκ°μ false)detail.ignoreTitle - trueμΈ κ²½μ° μλ΅μ μ λͺ© νκ·Έκ° λ¬΄μλ©λλ€.detail.target - κ΅μ²΄ λμhtmx:beforeTransitionμ΄ μ΄λ²€νΈλ View TransitionμΌλ‘ wrapλ κ΅μ²΄κ° λ°μνκΈ° μ μ νΈλ¦¬κ±°λ©λλ€. μ΄λ²€νΈκ° μ·¨μλλ©΄ View Transitionμ΄ λ°μνμ§ μκ³ λμ μΌλ° κ΅μ²΄ λ‘μ§μ΄ λ°μν©λλ€.
detail.elt - μμ²μ λ³΄λΈ μμdetail.xhr - the XMLHttpRequestdetail.requestConfig - AJAX μμ²μ ꡬμ±detail.shouldSwap - κ΅μ²΄λ μ½ν
μΈ (200μ΄ μλ μλ΅ μ½λμ κ²½μ° κΈ°λ³Έκ°μ false)detail.target - κ΅μ²΄ λμhtmx:configRequestμ΄ μ΄λ²€νΈλ htmxκ° μμ²μ ν¬ν¨ν λ§€κ°λ³μλ₯Ό μμ§ν νμ νΈλ¦¬κ±°λ©λλ€. μ΄ μ΄λ²€νΈλ htmxκ° μ μ‘ν λ§€κ° λ³μλ₯Ό ν¬ν¨νκ±°λ μ λ°μ΄νΈνλ λ° μ¬μ©ν μ μμ΅λλ€:
document.body.addEventListener('htmx:configRequest', function(evt) {
evt.detail.parameters['auth_token'] = getAuthToken(); // μ λ§€κ°λ³μ μΆκ°
});
μ
λ ₯ κ°μ΄ λ λ² μ΄μ νμλλ κ²½μ° parameters κ°μ²΄μ κ°μ λ¨μΌ κ°μ΄ μλ λ°°μ΄μ΄ λ©λλ€.
detail.parameters - μμ² μμ
μ μ μΆλ λ§€κ°λ³μdetail.unfilteredParameters - hx-selectλ‘ νν°λ§νκΈ° μ μ λ°κ²¬λ λ§€κ°λ³μdetail.headers - μμ² ν€λdetail.elt - μμ²μ νΈλ¦¬κ±°ν μμdetail.target - μμ² λμdetail.verb - μ¬μ©λ HTTP λ©μλhtmx:confirmμ΄ μ΄λ²€νΈλ μμμμ νΈλ¦¬κ±°κ° λ°μν μ§νμ νΈλ¦¬κ±°λ©λλ€. μ΄λ₯Ό ν΅ν΄ AJAX μμ²μ μ·¨μ(λλ μ§μ°)ν μ μμ΅λλ€.
μ΄λ²€νΈμμ preventDefault()λ₯Ό νΈμΆνλ©΄ μ§μ λ μμ²μ 보λ΄μ§ μμ΅λλ€.
detail κ°μ²΄μλ λμ€μ μ€μ AJAX μμ²μ λ°ννλ λ° μ¬μ©ν μ μλ ν¨μμΈ evt.detail.issueRequest()κ° ν¬ν¨λμ΄ μμ΅λλ€.
μ΄ λ κΈ°λ₯μ κ²°ν©νλ©΄ λΉλκΈ° confirmation λν μμλ₯Ό λ§λ€ μ μμ΅λλ€.
λ€μμ confirm-with-sweet-alert='true' μμ±μ΄ μλ λͺ¨λ μμμ sweet alertλ₯Ό μ¬μ©νλ μμμ
λλ€:
document.body.addEventListener('htmx:confirm', function(evt) {
if (evt.target.matches("[confirm-with-sweet-alert='true']")) {
evt.preventDefault();
swal({
title: "Are you sure?",
text: "Are you sure you are sure?",
icon: "warning",
buttons: true,
dangerMode: true,
}).then((confirmed) => {
if (confirmed) {
evt.detail.issueRequest();
}
});
}
});
{target: target, elt: elt, path: path, verb: verb, triggeringEvent: event, etc: etc, issueRequest: issueRequest}
detail.elt - ν΄λΉ μμdetail.etc - μΆκ°μ μΈ μμ²μ μ 보 (λλΆλΆ λ―Έμ¬μ©)detail.issueRequest - μμ²μ 보λ΄κΈ° μν΄ νΈμΆν μ μλ μΈμ μλ ν¨μ(evt.preventDefault()μ μμ μ΄λ£¨μ΄μΌ ν¨!)detail.path - μμ²μ κ²½λ‘detail.target - μμ²μ λμdetail.triggeringEvent - μ΄ μμ²μ νΈλ¦¬κ±°ν μλ μ΄λ²€νΈdetail.verb - μμ² λ©μλ (μλ₯Ό λ€μ΄ GET)htmx:historyCacheErrorμ΄ μ΄λ²€νΈλ localStorageμ μΊμλ₯Ό μ μ₯νλ €λ μλκ° μ€ν¨ν λ νΈλ¦¬κ±°λ©λλ€.
detail.cause - νμ€ν 리λ₯Ό localStorageμ μ μ₯νλ €λ μλ μ€μ λ°μν Exceptionhtmx:historyCacheMissμ΄ μ΄λ²€νΈλ νμ€ν 리λ₯Ό 볡μνλ λμ μΊμ λ―Έμ€κ° λ°μν λ νΈλ¦¬κ±°λ©λλ€.
detail.xhr - 볡μμ μν΄ μ격 μ½ν
μΈ λ₯Ό κ°μ Έμ¬ XMLHttpRequestdetail.path - 볡μ μ€μΈ νμ΄μ§μ κ²½λ‘μ 쿼리htmx:historyCacheMissErrorμ΄ μ΄λ²€νΈλ μΊμ λ―Έμ€κ° λ°μνκ³ λ³΅μμ μν μ½ν
μΈ κ° μλ²μμ μλ΅λμμ§λ§, μλ΅μ΄ μ€λ₯μΈ κ²½μ°(μ: 404) νΈλ¦¬κ±°λ©λλ€.
detail.xhr - XMLHttpRequestdetail.path - 볡μ μ€μΈ νμ΄μ§μ κ²½λ‘μ 쿼리htmx:historyCacheMissLoadμ΄ μ΄λ²€νΈλ μΊμ λ―Έμ€κ° λ°μνκ³ λ³΅μμ μν μ½ν μΈ κ° μλ²μμ μ±κ³΅μ μΌλ‘ μλ΅λμμ λ νΈλ¦¬κ±°λ©λλ€.
detail.xhr - XMLHttpRequestdetail.path - 볡μ μ€μΈ νμ΄μ§μ κ²½λ‘μ 쿼리htmx:historyRestoreμ΄ μ΄λ²€νΈλ htmxκ° νμ€ν 리 볡μ μμ μ μ²λ¦¬ν λ νΈλ¦¬κ±°λ©λλ€.
detail.path - 볡μ μ€μΈ νμ΄μ§μ κ²½λ‘μ 쿼리htmx:beforeHistorySaveμ΄ μ΄λ²€νΈλ htmxκ° νμ€ν 리 볡μ μμ μ μ²λ¦¬ν λ νΈλ¦¬κ±°λ©λλ€.
detail.path - 볡μ μ€μΈ νμ΄μ§μ κ²½λ‘μ 쿼리detail.historyElt - 볡μλ νμ€ν 리 μμhtmx:loadμ΄ μ΄λ²€νΈλ htmxκ° μλ‘μ΄ λ Έλλ₯Ό DOMμ λ‘λν λ νΈλ¦¬κ±°λ©λλ€.
detail.elt - μλ‘ μΆκ°λ μμhtmx:noSSESourceErrorμ΄ μ΄λ²€νΈλ μμκ° νΈλ¦¬κ±°μμ SSE μ΄λ²€νΈλ₯Ό μ°Έμ‘°νμ§λ§, μμ SSE μμ€κ° μ μλμ§ μμ κ²½μ° νΈλ¦¬κ±°λ©λλ€.
detail.elt - μλͺ»λ SSE νΈλ¦¬κ±°κ° μλ μμhtmx:oobAfterSwapμ΄ μ΄λ²€νΈλ out of band κ΅μ²΄ μμ μ μΌλΆλ‘ νΈλ¦¬κ±°λλ©° κ΅μ²΄ μμ μ΄ν μ΄λ²€νΈμ λμΌνκ² μλν©λλ€.
detail.elt - μμ²μ λ³΄λΈ μμdetail.shouldSwap - μ½ν
μΈ κ° κ΅μ²΄λμλ κ°(κΈ°λ³Έκ°μ true)detail.target - κ΅μ²΄ λμdetail.fragment - μλ΅ μ‘°κ°htmx:oobBeforeSwapμ΄ μ΄λ²€νΈλ out of band κ΅μ²΄ μμ μ μΌλΆλ‘ νΈλ¦¬κ±°λλ©° κ΅μ²΄ μμ μ΄μ μ΄λ²€νΈμ λμΌνκ² μλν©λλ€.
detail.elt - μμ²μ λ³΄λΈ μμdetail.shouldSwap - μ½ν
μΈ κ° κ΅μ²΄λμλ κ°(κΈ°λ³Έκ°μ true)detail.target - κ΅μ²΄ λμdetail.fragment - μλ΅ μ‘°κ°htmx:oobErrorNoTargetμ΄ μ΄λ²€νΈλ out of band swapμ΄ DOMμ μ νν λμνλ μμκ° μμ λ νΈλ¦¬κ±°λ©λλ€.
detail.content - μλͺ»λ OOB IDλ₯Ό κ°μ§ μμhtmx:onLoadErrorμ΄ μ΄λ²€νΈλ AJAX νΈμΆμ load μ²λ¦¬ μ€μ μ€λ₯κ° λ°μνλ©΄ νΈλ¦¬κ±°λ©λλ€.
detail.xhr - the XMLHttpRequestdetail.elt - μμ²μ νΈλ¦¬κ±°ν μμdetail.target - μμ² λμdetail.exception - λ°μν μμΈdetail.requestConfig - AJAX μμ²μ ꡬμ±htmx:promptμ΄ μ΄λ²€νΈλ hx-prompt μμ±μ μ¬μ©νμ¬ μ¬μ©μμκ² ν둬ννΈκ° νμλ νμ νΈλ¦¬κ±°λ©λλ€.
μ΄ μ΄λ²€νΈκ° μ·¨μλλ©΄ AJAX μμ²μ΄ λ°μνμ§ μμ΅λλ€.
detail.elt - μμ²μ νΈλ¦¬κ±°ν μμdetail.target - μμ² λμdetail.prompt - ν둬ννΈμ λν μ¬μ©μ μλ΅htmx:beforeHistoryUpdateμ΄ μ΄λ²€νΈλ νμ€ν 리 μ
λ°μ΄νΈκ° μνλκΈ° μ μ νΈλ¦¬κ±°λ©λλ€. νμ€ν 리 μ
λ°μ΄νΈμ μ¬μ©λλ path λλ typeμ μμ νλ λ° μ¬μ©ν μ μμ΅λλ€.
detail.history - νμ€ν 리 μ
λ°μ΄νΈλ₯Ό μν pathμ type (push, replace)detail.elt - μμ²μ λ³΄λΈ μμdetail.xhr - XMLHttpRequestdetail.target - μμ²μ λμdetail.requestConfig - AJAX μμ²μ ꡬμ±htmx:pushedIntoHistoryμ΄ μ΄λ²€νΈλ URLμ΄ νμ€ν 리μ μΆκ°λ νμ νΈλ¦¬κ±°λ©λλ€.
detail.path - νμ€ν 리μ μΆκ°λ URLμ κ²½λ‘μ 쿼리htmx:replacedInHistoryμ΄ μ΄λ²€νΈλ URLμ΄ νμ€ν 리μμ κ΅μ²΄λ νμ νΈλ¦¬κ±°λ©λλ€.
detail.path - νμ€ν 리μμ κ΅μ²΄λ URLμ κ²½λ‘μ 쿼리htmx:responseErrorμ΄ μ΄λ²€νΈλ HTTP μ€λ₯ μλ΅μ΄ λ°μνμ λ νΈλ¦¬κ±°λ©λλ€.
detail.xhr - XMLHttpRequestdetail.elt - μμ²μ νΈλ¦¬κ±°ν μμdetail.target - μμ²μ λμdetail.requestConfig - AJAX μμ²μ ꡬμ±htmx:sendErrorμ΄ μ΄λ²€νΈλ λ€νΈμν¬ μ€λ₯λ‘ μΈν΄ HTTP μμ²μ΄ λ°μνμ§ λͺ»ν λ νΈλ¦¬κ±°λ©λλ€.
detail.xhr - XMLHttpRequestdetail.elt - μμ²μ νΈλ¦¬κ±°ν μμdetail.target - μμ²μ λμdetail.requestConfig - AJAX μμ²μ ꡬμ±htmx:sseErrorμ΄ μ΄λ²€νΈλ SSE μμ€μμ μ€λ₯κ° λ°μνμ λ νΈλ¦¬κ±°λ©λλ€.
detail.elt - μλͺ»λ SSE μμ€κ° μλ μμdetail.error - μ€λ₯detail.source - SSE μμ€htmx:swapErrorμ΄ μ΄λ²€νΈλ κ΅μ²΄ λ¨κ³μμ μ€λ₯κ° λ°μνμ λ νΈλ¦¬κ±°λ©λλ€.
detail.xhr - XMLHttpRequestdetail.elt - μμ²μ νΈλ¦¬κ±°ν μμdetail.target - μμ²μ λμdetail.requestConfig - AJAX μμ²μ ꡬμ±htmx:targetErrorμ΄ μ΄λ²€νΈλ hx-target μμ±μ μλͺ»λ μ νμ(μ: μμ #κ° μλ μμ ID)κ° μ¬μ©λ λ νΈλ¦¬κ±°λ©λλ€.
detail.elt - μμ²μ νΈλ¦¬κ±°ν μμdetail.target - μλͺ»λ CSS μ νμhtmx:timeoutμ΄ μ΄λ²€νΈλ μμ² μκ° μ΄κ³Όκ° λ°μνλ©΄ νΈλ¦¬κ±°λ©λλ€. μ΄ μ΄λ²€νΈλ XMLHttpRequestμ μΌλ°μ μΈ timeout μ΄λ²€νΈλ₯Ό wrapν©λλ€.
timeout μκ°μ htmx.config.timeoutμ μ¬μ©νμ¬ μ€μ νκ±°λ hx-requestλ₯Ό μ¬μ©νμ¬ μμλ³λ‘ μ€μ ν μ μμ΅λλ€.
detail.elt - μμ²μ λ³΄λΈ μμdetail.xhr - the XMLHttpRequestdetail.target - μμ²μ λμdetail.requestConfig - AJAX μμ²μ ꡬμ±htmx:triggerμ΄ μ΄λ²€νΈλ AJAX μμ²μ΄ μ§μ λμ§ μμ κ²½μ°μλ AJAX μμ²μ΄ μμ λλ§λ€ νΈλ¦¬κ±°λ©λλ€. μ΄ μ΄λ²€νΈλ μ£Όλ‘ hx-triggerκ°
ν΄λΌμ΄μΈνΈ μΈ‘ μ€ν¬λ¦½νΈλ₯Ό μ€νν μ μλλ‘ νκΈ° μν κ²μΌλ‘, AJAX μμ²μλ
htmx:beforeRequest λλ htmx:afterRequestμ κ°μ λ μΈλΆνλ μ΄λ²€νΈλ₯Ό μ¬μ©ν μ μμ΅λλ€.
detail.elt - μμ²μ νΈλ¦¬κ±°ν μμhtmx:validateUrlμ΄ μ΄λ²€νΈλ μμ²μ΄ μ΄λ£¨μ΄μ§κΈ° μ μ νΈλ¦¬κ±°λμ΄ htmxκ° μμ²ν URLμ μ ν¨μ±μ κ²μ¬ν μ μμ΅λλ€.
μ΄λ²€νΈμμ preventDefault()κ° νΈμΆλλ©΄ μμ²μ΄ μ΄λ£¨μ΄μ§μ§ μμ΅λλ€.
document.body.addEventListener('htmx:validateUrl', function (evt) {
// νμ¬ μλ²μ myserver.comμ λν μμ²λ§ νμ©ν©λλ€.
if (!evt.detail.sameHost && evt.detail.url.hostname !== "myserver.com") {
evt.preventDefault();
}
});
detail.elt - μμ²μ νΈλ¦¬κ±°ν μμdetail.url - μμ²μ΄ μ μ‘λ URLμ λνλ΄λ URL κ°μ²΄μ
λλ€.detail.sameHost - μμ²μ΄ documentμ λμΌν νΈμ€νΈμ λν κ²½μ° trueμ
λλ€.htmx:validation:validateμ΄ μ΄λ²€νΈλ μμμ μ ν¨μ±μ κ²μ¬νκΈ° μ μ νΈλ¦¬κ±°λ©λλ€. μ΄ μ΄λ²€νΈλ
μ¬μ©μ μ μ μ ν¨μ± κ²μ¬ κ·μΉμ ꡬννκΈ° μν΄ elt.setCustomValidity() λ©μλμ ν¨κ» μ¬μ©ν μ μμ΅λλ€.
<form hx-post="/test">
<input _="on htmx:validation:validate
if my.value != 'foo'
call me.setCustomValidity('Please enter the value foo')
else
call me.setCustomValidity('')"
name="example">
</form>
detail.elt - μμ²μ νΈλ¦¬κ±°ν μμhtmx:validation:failedμ΄ μ΄λ²€νΈλ μμκ° μ ν¨μ± κ²μ¬μ μ€ν¨ν λ νΈλ¦¬κ±°λ©λλ€.
detail.elt - μμ²μ νΈλ¦¬κ±°ν μμdetail.message - μ ν¨μ± κ²μ¬ μ€λ₯ λ©μμ§detail.validity - μ ν¨μ± κ²μ¬ μ€ν¨ λ°©λ²μ μ§μ νλ μμ±μ ν¬ν¨νλ μ ν¨μ± κ°μ²΄htmx:validation:haltedμ΄ μ΄λ²€νΈλ μ ν¨μ± κ²μ¬ μ€λ₯λ‘ μΈν΄ μμ²μ΄ μ€λ¨λ λ νΈλ¦¬κ±°λ©λλ€.
detail.elt - μμ²μ νΈλ¦¬κ±°ν μμdetail.errors - μ ν¨νμ§ μμ μμ λ° μ΄μ κ΄λ ¨λ μ€λ₯κ° μλ μ€λ₯ κ°μ²΄ λ°°μ΄μ
λλ€.htmx:xhr:abortμ΄ μ΄λ²€νΈλ ajax μμ²μ΄ μ€λ¨λ λ νΈλ¦¬κ±°λ©λλ€.
detail.elt - μμ²μ νΈλ¦¬κ±°ν μμhtmx:xhr:loadstartμ΄ μ΄λ²€νΈλ ajax μμ²μ΄ μμλ λ νΈλ¦¬κ±°λ©λλ€.
detail.elt - μμ²μ νΈλ¦¬κ±°ν μμhtmx:xhr:loadendμ΄ μ΄λ²€νΈλ ajax μμ²μ΄ μλ£λ λ νΈλ¦¬κ±°λ©λλ€.
detail.elt - μμ²μ νΈλ¦¬κ±°ν μμhtmx:xhr:progressμ΄ μ΄λ²€νΈλ μ§ν μνλ₯Ό μ§μνλ ajax μμ²μ΄ μ§ν μ€μΌ λ μ£ΌκΈ°μ μΌλ‘ νΈλ¦¬κ±°λ©λλ€.
detail.elt - μμ²μ νΈλ¦¬κ±°ν μμ