├── .gitignore ├── .vscodeignore ├── LICENSE.txt ├── README.md ├── build-data.py ├── demo-1.png ├── demo-2.png ├── html.htmx-data.json └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | out 2 | dist 3 | node_modules 4 | .vscode-test/ 5 | *.vsix 6 | .vscode 7 | -------------------------------------------------------------------------------- /.vscodeignore: -------------------------------------------------------------------------------- 1 | .vscode/** 2 | .vscode-test/** 3 | src/** 4 | .gitignore 5 | .yarnrc 6 | vsc-extension-quickstart.md 7 | **/tsconfig.json 8 | **/.eslintrc.json 9 | **/*.map 10 | **/*.ts 11 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | 204 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # htmx-Tags 3 | 4 | htmx-Tags is a VSCode extension that provides autocompletion of htmx attributes and inline documentation for these attributes. The documentation for the attributes are fetched and parsed from the official documentation. 5 | 6 | 7 | ## Installation 8 | 9 | You can install the `htmx-tags` extension from the Visual Studio Code Marketplace or by searching for "htmx-tags" within the VSCode extension panel. 10 | Usage 11 | 12 | After installing the extension, simply start typing an htmx attribute within an HTML tag and the extension will provide autocompletion suggestions based on the official htmx documentation. 13 | 14 | Additionally, you can hover over an htmx attribute to see inline documentation within your code editor. 15 | 16 | ## Features 17 | 18 | * Autocompletion of htmx attributes 19 | * Inline documentation for htmx attributes 20 | 21 | ## Screenshots 22 | 23 | ![Attribute completion](demo-1.png) 24 | 25 | ![Inline documentation](demo-2.png) 26 | 27 | ## Contributions 28 | 29 | Contributions to the htmx-Tags extension are welcome! 30 | 31 | If you would like to contribute, please submit a pull request or open an issue on the GitHub repository. 32 | 33 | 34 | ## License 35 | 36 | htmx-Tags is licensed under the Apache 2 License. See the LICENSE file for more information. 37 | 38 | The htmx documentation is licensed under the BSD 2-clause license. 39 | -------------------------------------------------------------------------------- /build-data.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import zipfile 4 | from io import BytesIO 5 | from urllib.request import urlopen 6 | from pathlib import Path 7 | import json 8 | 9 | result = { 10 | "version": 1.1, 11 | "tags": [], 12 | "globalAttributes": [], 13 | "valueSets": [ 14 | { 15 | "name": "swap", 16 | "values": [ 17 | { 18 | "name": "innerHTML", 19 | "description": "The default, puts the content inside the target element", 20 | }, 21 | { 22 | "name": "outerHTML", 23 | "description": "Replaces the entire target element with the returned content", 24 | }, 25 | { 26 | "name": "afterbegin", 27 | "description": "Prepends the content before the first child inside the target", 28 | }, 29 | { 30 | "name": "beforebegin", 31 | "description": "Prepends the content before the target in the targets parent element", 32 | }, 33 | { 34 | "name": "beforeend", 35 | "description": "Appends the content after the last child inside the target", 36 | }, 37 | { 38 | "name": "afterend", 39 | "description": "Appends the content after the target in the targets parent element", 40 | }, 41 | { 42 | "name": "delete", 43 | "description": "Deletes the target element regardless of the response", 44 | }, 45 | { 46 | "name": "none", 47 | "description": "Does not append content from response (Out of Band Swaps and Response Headers will still be processed)", 48 | }, 49 | ], 50 | } 51 | ], 52 | } 53 | 54 | documented_value_sets = {e["name"] for e in result["valueSets"]} 55 | 56 | HTMX_VERSION = "1.9.6" 57 | 58 | response = urlopen( 59 | f"https://github.com/bigskysoftware/htmx/archive/refs/tags/v{HTMX_VERSION}.zip" 60 | ) 61 | assert response.code == 200 62 | content = response.read() 63 | 64 | zip_fd = zipfile.ZipFile(BytesIO(content)) 65 | 66 | for f in zip_fd.filelist: 67 | if ( 68 | f.filename.endswith(".md") 69 | and "/www/content/attributes/" in f.filename 70 | and "_index" not in f.filename 71 | ): 72 | p = Path(f.filename) 73 | attribute = p.name.replace(".md", "") 74 | attribute_doc: str = zip_fd.read(f).decode() 75 | # Strip front matter from markdown 76 | attribute_doc = attribute_doc[attribute_doc.find("+++", 3)+3:].strip() 77 | 78 | entry = { 79 | "name": attribute, 80 | "description": attribute_doc, 81 | "references": [ 82 | { 83 | "name": "Official documention", 84 | "url": f"https://htmx.org/attributes/{attribute}/", 85 | } 86 | ], 87 | } 88 | 89 | if attribute in documented_value_sets: 90 | entry |= {"valueSet": attribute} 91 | 92 | result["globalAttributes"].append(entry) 93 | 94 | with open("html.htmx-data.json", "w") as output_file: 95 | json.dump(result, output_file, indent=2) 96 | -------------------------------------------------------------------------------- /demo-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otovo/htmx-tags/f3d9de5028a5f7f4125e5757cd98d8f26b4352a8/demo-1.png -------------------------------------------------------------------------------- /demo-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otovo/htmx-tags/f3d9de5028a5f7f4125e5757cd98d8f26b4352a8/demo-2.png -------------------------------------------------------------------------------- /html.htmx-data.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 1.1, 3 | "tags": [], 4 | "globalAttributes": [ 5 | { 6 | "name": "hx-boost", 7 | "description": "The `hx-boost` attribute allows you to \"boost\" normal anchors and form tags to use AJAX instead. This\nhas the [nice fallback](https://en.wikipedia.org/wiki/Progressive_enhancement) that, if the user does not \nhave javascript enabled, the site will continue to work.\n\nFor anchor tags, clicking on the anchor will issue a `GET` request to the url specified in the `href` and\nwill push the url so that a history entry is created. The target is the `` tag, and the `innerHTML`\nswap strategy is used by default. All of these can be modified by using the appropriate attributes, except\nthe `click` trigger.\n\nFor forms the request will be converted into a `GET` or `POST`, based on the method in the `method` attribute\nand will be triggered by a `submit`. Again, the target will be the `body` of the page, and the `innerHTML`\nswap will be used. The url will _not_ be pushed, however, and no history entry will be created. (You can use the \n[hx-push-url](@/attributes/hx-push-url.md) attribute if you want the url to be pushed.)\n\nHere is an example of some boosted links:\n\n```html\n
\n Go To Page 1\n Go To Page 2\n
\n```\nThese links will issue an ajax `GET` request to the respective URLs and replace the body's inner content with it.\n\nHere is an example of a boosted form:\n\n```html\n
\n \n \n
\n```\nThis form will issue an ajax `POST` to the given URL and replace the body's inner content with it.\n\n\n## Notes\n\n* `hx-boost` is inherited and can be placed on a parent element\n* Only links that are to the same domain and that are not local anchors will be boosted\n* All requests are done via AJAX, so keep that in mind when doing things like redirects\n* To find out if the request results from a boosted anchor or form, look for [`HX-Boosted`](@/reference.md#request_headers) in the request header\n* Selectively disable boost on child elements with `hx-boost=\"false\"`", 8 | "references": [ 9 | { 10 | "name": "Official documention", 11 | "url": "https://htmx.org/attributes/hx-boost/" 12 | } 13 | ] 14 | }, 15 | { 16 | "name": "hx-confirm", 17 | "description": "The `hx-confirm` attribute allows you to confirm an action before issuing a request. This can be useful\nin cases where the action is destructive and you want to ensure that the user really wants to do it.\n\nHere is an example:\n\n```html\n\n```\n\n## Notes\n\n* `hx-confirm` is inherited and can be placed on a parent element", 18 | "references": [ 19 | { 20 | "name": "Official documention", 21 | "url": "https://htmx.org/attributes/hx-confirm/" 22 | } 23 | ] 24 | }, 25 | { 26 | "name": "hx-delete", 27 | "description": "The `hx-delete` attribute will cause an element to issue a `DELETE` to the specified URL and swap\nthe HTML into the DOM using a swap strategy:\n\n```html\n\n```\n\nThis example will cause the `button` to issue a `DELETE` to `/account` and swap the returned HTML into\n the `innerHTML` of the `body`.\n\n## Notes\n\n* `hx-delete` is not inherited\n* You can control the target of the swap using the [hx-target](@/attributes/hx-target.md) attribute\n* You can control the swap strategy by using the [hx-swap](@/attributes/hx-swap.md) attribute\n* You can control what event triggers the request with the [hx-trigger](@/attributes/hx-trigger.md) attribute\n* You can control the data submitted with the request in various ways, documented here: [Parameters](@/docs.md#parameters)\n* To remove the element following a successful `DELETE`, return a `200` status code with an empty body; if the server responds with a `204`, no swap takes place, documented here: [Requests & Responses](@/docs.md#requests)", 28 | "references": [ 29 | { 30 | "name": "Official documention", 31 | "url": "https://htmx.org/attributes/hx-delete/" 32 | } 33 | ] 34 | }, 35 | { 36 | "name": "hx-disable", 37 | "description": "The `hx-disable` attribute will disable htmx processing for a given element and all its children. This can be \nuseful as a backup for HTML escaping, when you include user generated content in your site, and you want to \nprevent malicious scripting attacks.\n\nThe value of the tag is ignored, and it cannot be reversed by any content beneath it.\n \n## Notes\n\n* `hx-disable` is inherited", 38 | "references": [ 39 | { 40 | "name": "Official documention", 41 | "url": "https://htmx.org/attributes/hx-disable/" 42 | } 43 | ] 44 | }, 45 | { 46 | "name": "hx-disabled-elt", 47 | "description": "The `hx-disabled-elt` attribute allows you to specify elements that will have the `disabled` attribute\nadded to them for the duration of the request.\n\nThe value of this attribute is a CSS query selector of the element or elements to apply the class to,\nor the keyword [`closest`](https://developer.mozilla.org/docs/Web/API/Element/closest), followed by a CSS selector, \nwhich will find the closest ancestor element or itself, that matches the given CSS selector (e.g. `closest tr`), or\nthe keyword `this`\n\nHere is an example with a button that will disable itself during a request:\n\n```html\n\n```\n\nWhen a request is in flight, this will cause the button to be marked with [the `disabled` attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/disabled), \nwhich will prevent further clicks from occurring. \n\n## Notes\n\n* `hx-disable-elts` is inherited and can be placed on a parent element", 48 | "references": [ 49 | { 50 | "name": "Official documention", 51 | "url": "https://htmx.org/attributes/hx-disabled-elt/" 52 | } 53 | ] 54 | }, 55 | { 56 | "name": "hx-disinherit", 57 | "description": "The default behavior for htmx is to \"inherit\" many attributes automatically: that is, an attribute such as\n[hx-target](@/attributes/hx-target.md) may be placed on a parent element, and all child elements will inherit\nthat target.\n\nThe `hx-disinherit` attribute allows you to control this automatic attribute inheritance. An example scenario is to \nallow you to place an `hx-boost` on the `body` element of a page, but overriding that behavior in a specific part\nof the page to allow for more specific behaviors.\n\nhtmx evaluates attribute inheritance as follows:\n\n* when `hx-disinherit` is set on a parent node\n * `hx-disinherit=\"*\"` all attribute inheritance for this element will be disabled\n * `hx-disinherit=\"hx-select hx-get hx-target\"` disable inheritance for only one or multiple specified attributes\n\n```html\n
\n Go To Page 1 \n Go To Page 1 \n \n
\n```\n\n```html\n
\n \n \n
\n```\n\n```html\n
\n
\n \n \n \n
\n
\n```\n\n## Notes\n\n* Read more about [Attribute Inheritance](@/docs.md#inheritance)", 58 | "references": [ 59 | { 60 | "name": "Official documention", 61 | "url": "https://htmx.org/attributes/hx-disinherit/" 62 | } 63 | ] 64 | }, 65 | { 66 | "name": "hx-encoding", 67 | "description": "The `hx-encoding` attribute allows you to switch the request encoding from the usual `application/x-www-form-urlencoded`\nencoding to `multipart/form-data`, usually to support file uploads in an ajax request.\n\nThe value of this attribute should be `multipart/form-data`.\n\nThe `hx-encoding` tag may be placed on parent elements.\n\n## Notes\n\n* `hx-encoding` is inherited and can be placed on a parent element", 68 | "references": [ 69 | { 70 | "name": "Official documention", 71 | "url": "https://htmx.org/attributes/hx-encoding/" 72 | } 73 | ] 74 | }, 75 | { 76 | "name": "hx-ext", 77 | "description": "The `hx-ext` attribute enables an htmx [extension](@/extensions/_index.md) for an element and all its children.\n\nThe value can be a single extension name or a comma separated list of extensions to apply.\n\nThe `hx-ext` tag may be placed on parent elements if you want a plugin to apply to an entire swath of the DOM,\nand on the `body` tag for it to apply to all htmx requests.\n\n## Notes\n\n* `hx-ext` is both inherited and merged with parent elements, so you can specify extensions on any element in the DOM \nhierarchy and it will apply to all child elements. \n\n* You can ignore an extension that is defined by a parent node using `hx-ext=\"ignore:extensionName\"` \n\n\n```html\n
\n \"Example\" extension is used in this part of the tree...\n
\n ... but it will not be used in this part.\n
\n
\n```", 78 | "references": [ 79 | { 80 | "name": "Official documention", 81 | "url": "https://htmx.org/attributes/hx-ext/" 82 | } 83 | ] 84 | }, 85 | { 86 | "name": "hx-get", 87 | "description": "The `hx-get` attribute will cause an element to issue a `GET` to the specified URL and swap\nthe HTML into the DOM using a swap strategy:\n\n```html\n
Get Some HTML
\n```\n\nThis example will cause the `div` to issue a `GET` to `/example` and swap the returned HTML into\n the `innerHTML` of the `div`.\n\n### Notes\n\n* `hx-get` is not inherited\n* By default `hx-get` does not include any parameters. You can use the [hx-params](@/attributes/hx-params.md)\n attribute to change this\n* You can control the target of the swap using the [hx-target](@/attributes/hx-target.md) attribute\n* You can control the swap strategy by using the [hx-swap](@/attributes/hx-swap.md) attribute\n* You can control what event triggers the request with the [hx-trigger](@/attributes/hx-trigger.md) attribute\n* You can control the data submitted with the request in various ways, documented here: [Parameters](@/docs.md#parameters)", 88 | "references": [ 89 | { 90 | "name": "Official documention", 91 | "url": "https://htmx.org/attributes/hx-get/" 92 | } 93 | ] 94 | }, 95 | { 96 | "name": "hx-headers", 97 | "description": "The `hx-headers` attribute allows you to add to the headers that will be submitted with an AJAX request. \n\nBy default, the value of this attribute is a list of name-expression values in [JSON (JavaScript Object Notation)](https://www.json.org/json-en.html) \nformat.\n\nIf you wish for `hx-headers` to *evaluate* the values given, you can prefix the values with `javascript:` or `js:`.\n\n```html\n
Get Some HTML, Including A Custom Header in the Request
\n```\n\n## Security Considerations\n\n* By default, the value of `hx-headers` must be valid [JSON](https://developer.mozilla.org/en-US/docs/Glossary/JSON). \n It is **not** dynamically computed. If you use the `javascript:` prefix, be aware that you are introducing\n security considerations, especially when dealing with user input such as query strings or user-generated content, \n which could introduce a [Cross-Site Scripting (XSS)](https://owasp.org/www-community/attacks/xss/) vulnerability. \n\n## Notes\n\n* `hx-headers` is inherited and can be placed on a parent element.\n* A child declaration of a header overrides a parent declaration.", 98 | "references": [ 99 | { 100 | "name": "Official documention", 101 | "url": "https://htmx.org/attributes/hx-headers/" 102 | } 103 | ] 104 | }, 105 | { 106 | "name": "hx-history-elt", 107 | "description": "The `hx-history-elt` attribute allows you to specify the element that will be used to snapshot and\nrestore page state during navigation. By default, the `body` tag is used. This is typically\ngood enough for most setups, but you may want to narrow it down to a child element. Just make\nsure that the element is always visible in your application, or htmx will not be able to restore\nhistory navigation properly.\n\n\nHere is an example:\n\n```html\n\n\n
\n ...\n
\n\n\n```\n\n## Notes\n\n* `hx-history-elt` is not inherited\n* In most cases we don't recommend narrowing the history snapshot", 108 | "references": [ 109 | { 110 | "name": "Official documention", 111 | "url": "https://htmx.org/attributes/hx-history-elt/" 112 | } 113 | ] 114 | }, 115 | { 116 | "name": "hx-history", 117 | "description": "Set the `hx-history` attribute to `false` on any element in the current document, or any html fragment loaded into the current document by htmx, to prevent sensitive data being saved to the localStorage cache when htmx takes a snapshot of the page state. \n\nHistory navigation will work as expected, but on restoration the URL will be requested from the server instead of the history cache.\n\nHere is an example:\n\n```html\n\n\n
\n ...\n
\n\n\n```\n\n## Notes\n\n* `hx-history=\"false\"` can be present *anywhere* in the document to embargo the current page state from the history cache (i.e. even outside the element specified for the history snapshot [hx-history-elt](@/attributes/hx-history-elt.md)).", 118 | "references": [ 119 | { 120 | "name": "Official documention", 121 | "url": "https://htmx.org/attributes/hx-history/" 122 | } 123 | ] 124 | }, 125 | { 126 | "name": "hx-include", 127 | "description": "The `hx-include` attribute allows you to include additional element values in an AJAX request. The value of\n this attribute is a CSS query selector of the element or elements to include in the query.\n\nHere is an example that includes a separate input value:\n\n```html\n
\n \n Enter email: \n
\n```\n\nThis is a little contrived as you would typically enclose both of these elements in a `form` and submit\nthe value automatically, but it demonstrates the concept.\n\nNote that if you include a non-input element, all input elements enclosed in that element will be included.\n\n## Notes\n\n* `hx-include` is inherited and can be placed on a parent element", 128 | "references": [ 129 | { 130 | "name": "Official documention", 131 | "url": "https://htmx.org/attributes/hx-include/" 132 | } 133 | ] 134 | }, 135 | { 136 | "name": "hx-indicator", 137 | "description": "The `hx-indicator` attribute allows you to specify the element that will have the `htmx-request` class\nadded to it for the duration of the request. This can be used to show spinners or progress indicators\nwhile the request is in flight.\n\nThe value of this attribute is a CSS query selector of the element or elements to apply the class to,\nor the keyword [`closest`](https://developer.mozilla.org/docs/Web/API/Element/closest), followed by a CSS selector, \nwhich will find the closest ancestor element or itself, that matches the given CSS selector (e.g. `closest tr`);\n\nHere is an example with a spinner adjacent to the button:\n\n```html\n
\n \n \n
\n```\n\nWhen a request is in flight, this will cause the `htmx-request` class to be added to the `#spinner`\nimage. The image also has the `htmx-indicator` class on it, which defines an opacity transition\nthat will show the spinner:\n\n```css\n .htmx-indicator{\n opacity:0;\n transition: opacity 500ms ease-in;\n }\n .htmx-request .htmx-indicator{\n opacity:1\n }\n .htmx-request.htmx-indicator{\n opacity:1\n }\n```\n\nIf you would prefer a different effect for showing the spinner you could define and use your own indicator\nCSS. Here is an example that uses `display` rather than opacity (Note that we use `my-indicator` instead of `htmx-indicator`):\n\n```css\n .my-indicator{\n display:none;\n }\n .htmx-request .my-indicator{\n display:inline;\n }\n .htmx-request.my-indicator{\n display:inline;\n }\n```\n\nNote that the target of the `hx-indicator` selector need not be the exact element that you\nwant to show: it can be any element in the parent hierarchy of the indicator.\n\nFinally, note that the `htmx-request` class by default is added to the element causing\nthe request, so you can place an indicator inside of that element and not need to explicitly\ncall it out with the `hx-indicator` attribute:\n\n```html\n\n```\n\n## Demo\n\nThis simulates what a spinner might look like in that situation:\n\n\n\n## Notes\n\n* `hx-indicator` is inherited and can be placed on a parent element\n* In the absence of an explicit indicator, the `htmx-request` class will be added to the element triggering the\n request\n* If you want to use your own CSS but still use `htmx-indicator` as class name, then you need to disable `includeIndicatorStyles`. See [Configuring htmx](@/docs.md#config). The easiest way is to add this the `` of your HTML:\n```html\n\n```", 138 | "references": [ 139 | { 140 | "name": "Official documention", 141 | "url": "https://htmx.org/attributes/hx-indicator/" 142 | } 143 | ] 144 | }, 145 | { 146 | "name": "hx-on", 147 | "description": "The `hx-on` attribute allows you to embed scripts inline to respond to events directly on an element; similar to the [`onevent` properties](https://developer.mozilla.org/en-US/docs/Web/Events/Event_handlers#using_onevent_properties) found in HTML, such as `onClick`.\n\n`hx-on` improves upon `onevent` by enabling the handling of any event for enhanced [Locality of Behaviour (LoB)](/essays/locality-of-behaviour/). This also enables you to handle any htmx event.\n\nThere are two forms of this attribute, one in which you specify the event as part of the attribute name\nafter a colon (`hx-on:click`, for example), and a deprecated form that uses the `hx-on` attribute directly. The\nlatter should only be used if IE11 support is required.\n\n### hx-on:* (recommended)\nThe event name follows a colon `:` in the attribute, and the attribute value is the script to be executed:\n\n```html\n
Click
\n```\n\nAll htmx events can be captured, too! Make sure to use the [kebab-case event name](@/docs.md#events),\nbecause DOM attributes do not preserve casing. For instance, `hx-on::beforeRequest` **will not work:**\nuse `hx-on::before-request` instead.\n\nTo make writing these a little easier, you can use the shorthand double-colon `hx-on::` for htmx\nevents, and omit the \"htmx\" part:\n\n```html\n\n\n\n\n\n```\n\nAdding multiple handlers is easy, you just specify additional attributes:\n```html\n\n```\n\n\n### hx-on (deprecated)\nThe value is an event name, followed by a colon `:`, followed by the script:\n\n```html\n\n```\n\nMultiple handlers can be defined by putting them on new lines:\n```html\n\n```\n\n\n### Symbols\n\nLike `onevent`, two symbols are made available to event handler scripts:\n\n* `this` - The element on which the `hx-on` attribute is defined\n* `event` - The event that triggered the handler\n\n### Notes\n\n* `hx-on` is _not_ inherited, however due to\n [event bubbling](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Events#event_bubbling_and_capture),\n `hx-on` attributes on parent elements will typically be triggered by events on child elements\n* `hx-on:*` and `hx-on` cannot be used together on the same element; if `hx-on:*` is present, the value of an `hx-on` attribute\n on the same element will be ignored. The two forms can be mixed in the same document, however.", 148 | "references": [ 149 | { 150 | "name": "Official documention", 151 | "url": "https://htmx.org/attributes/hx-on/" 152 | } 153 | ] 154 | }, 155 | { 156 | "name": "hx-params", 157 | "description": "The `hx-params` attribute allows you to filter the parameters that will be submitted with an AJAX request. \n\nThe possible values of this attribute are:\n\n* `*` - Include all parameters (default)\n* `none` - Include no parameters\n* `not ` - Include all except the comma separated list of parameter names\n* `` - Include all the comma separated list of parameter names\n\n```html\n
Get Some HTML, Including Params
\n```\n\nThis div will include all the parameters that a `POST` would, but they will be URL encoded\nand included in the URL, as per usual with a `GET`.\n\n## Notes\n\n* `hx-params` is inherited and can be placed on a parent element", 158 | "references": [ 159 | { 160 | "name": "Official documention", 161 | "url": "https://htmx.org/attributes/hx-params/" 162 | } 163 | ] 164 | }, 165 | { 166 | "name": "hx-patch", 167 | "description": "The `hx-patch` attribute will cause an element to issue a `PATCH` to the specified URL and swap\nthe HTML into the DOM using a swap strategy:\n\n```html\n\n```\n\nThis example will cause the `button` to issue a `PATCH` to `/account` and swap the returned HTML into\n the `innerHTML` of the `body`.\n \n## Notes\n\n* `hx-patch` is not inherited\n* You can control the target of the swap using the [hx-target](@/attributes/hx-target.md) attribute\n* You can control the swap strategy by using the [hx-swap](@/attributes/hx-swap.md) attribute\n* You can control what event triggers the request with the [hx-trigger](@/attributes/hx-trigger.md) attribute\n* You can control the data submitted with the request in various ways, documented here: [Parameters](@/docs.md#parameters)", 168 | "references": [ 169 | { 170 | "name": "Official documention", 171 | "url": "https://htmx.org/attributes/hx-patch/" 172 | } 173 | ] 174 | }, 175 | { 176 | "name": "hx-post", 177 | "description": "The `hx-post` attribute will cause an element to issue a `POST` to the specified URL and swap\nthe HTML into the DOM using a swap strategy:\n\n```html\n\n```\n\nThis example will cause the `button` to issue a `POST` to `/account/enable` and swap the returned HTML into\n the `innerHTML` of the `body`.\n \n## Notes\n\n* `hx-post` is not inherited\n* You can control the target of the swap using the [hx-target](@/attributes/hx-target.md) attribute\n* You can control the swap strategy by using the [hx-swap](@/attributes/hx-swap.md) attribute\n* You can control what event triggers the request with the [hx-trigger](@/attributes/hx-trigger.md) attribute\n* You can control the data submitted with the request in various ways, documented here: [Parameters](@/docs.md#parameters)", 178 | "references": [ 179 | { 180 | "name": "Official documention", 181 | "url": "https://htmx.org/attributes/hx-post/" 182 | } 183 | ] 184 | }, 185 | { 186 | "name": "hx-preserve", 187 | "description": "The `hx-preserve` attribute allows you to keep an element unchanged during HTML replacement.\nElements with `hx-preserve` set are preserved by `id` when htmx updates any ancestor element.\nYou *must* set an unchanging `id` on elements for `hx-preserve` to work.\nThe response requires an element with the same `id`, but its type and other attributes are ignored.\n\nNote that some elements cannot unfortunately be preserved properly, such as `` (focus and caret position are lost), iframes or certain types of videos. To tackle some of these cases we recommend the [morphdom extension](@/extensions/morphdom-swap.md), which does a more elaborate DOM\nreconciliation.\n\n## Notes\n\n* `hx-preserve` is not inherited", 188 | "references": [ 189 | { 190 | "name": "Official documention", 191 | "url": "https://htmx.org/attributes/hx-preserve/" 192 | } 193 | ] 194 | }, 195 | { 196 | "name": "hx-prompt", 197 | "description": "The `hx-prompt` attribute allows you to show a prompt before issuing a request. The value of\nthe prompt will be included in the request in the `HX-Prompt` header.\n\nHere is an example:\n\n```html\n\n```\n\n## Notes\n\n* `hx-prompt` is inherited and can be placed on a parent element", 198 | "references": [ 199 | { 200 | "name": "Official documention", 201 | "url": "https://htmx.org/attributes/hx-prompt/" 202 | } 203 | ] 204 | }, 205 | { 206 | "name": "hx-push-url", 207 | "description": "The `hx-push-url` attribute allows you to push a URL into the browser [location history](https://developer.mozilla.org/en-US/docs/Web/API/History_API).\nThis creates a new history entry, allowing navigation with the browser\u2019s back and forward buttons.\nhtmx snapshots the current DOM and saves it into its history cache, and restores from this cache on navigation.\n\nThe possible values of this attribute are:\n\n1. `true`, which pushes the fetched URL into history.\n2. `false`, which disables pushing the fetched URL if it would otherwise be pushed due to inheritance or [`hx-boost`](/attributes/hx-boost).\n3. A URL to be pushed into the location bar.\n This may be relative or absolute, as per [`history.pushState()`](https://developer.mozilla.org/en-US/docs/Web/API/History/pushState).\n\nHere is an example:\n\n```html\n
\n Go to My Account\n
\n```\n\nThis will cause htmx to snapshot the current DOM to `localStorage` and push the URL `/account' into the browser location bar.\n\nAnother example:\n\n```html\n
\n Go to My Account\n
\n```\n\nThis will push the URL `/account/home' into the location history.\n\n## Notes\n\n* `hx-push-url` is inherited and can be placed on a parent element\n* The [`HX-Push-Url` response header](@/headers/hx-push-url.md) has similar behavior and can override this attribute.\n* The [`hx-history-elt` attribute](@/attributes/hx-history-elt.md) allows changing which element is saved in the history cache.", 208 | "references": [ 209 | { 210 | "name": "Official documention", 211 | "url": "https://htmx.org/attributes/hx-push-url/" 212 | } 213 | ] 214 | }, 215 | { 216 | "name": "hx-put", 217 | "description": "The `hx-put` attribute will cause an element to issue a `PUT` to the specified URL and swap\nthe HTML into the DOM using a swap strategy:\n\n```html\n\n```\n\nThis example will cause the `button` to issue a `PUT` to `/account` and swap the returned HTML into\n the `innerHTML` of the `body`.\n \n## Notes\n\n* `hx-put` is not inherited\n* You can control the target of the swap using the [hx-target](@/attributes/hx-target.md) attribute\n* You can control the swap strategy by using the [hx-swap](@/attributes/hx-swap.md) attribute\n* You can control what event triggers the request with the [hx-trigger](@/attributes/hx-trigger.md) attribute\n* You can control the data submitted with the request in various ways, documented here: [Parameters](@/docs.md#parameters)", 218 | "references": [ 219 | { 220 | "name": "Official documention", 221 | "url": "https://htmx.org/attributes/hx-put/" 222 | } 223 | ] 224 | }, 225 | { 226 | "name": "hx-replace-url", 227 | "description": "The `hx-replace-url` attribute allows you to replace the current url of the browser [location history](https://developer.mozilla.org/en-US/docs/Web/API/History_API).\n\nThe possible values of this attribute are:\n\n1. `true`, which replaces the fetched URL in the browser navigation bar.\n2. `false`, which disables replacing the fetched URL if it would otherwise be replaced due to inheritance.\n3. A URL to be replaced into the location bar.\n This may be relative or absolute, as per [`history.replaceState()`](https://developer.mozilla.org/en-US/docs/Web/API/History/replaceState).\n\nHere is an example:\n\n```html\n
\n Go to My Account\n
\n```\n\nThis will cause htmx to snapshot the current DOM to `localStorage` and replace the URL `/account' in the browser location bar.\n\nAnother example:\n\n```html\n
\n Go to My Account\n
\n```\n\nThis will replace the URL `/account/home' in the browser location bar.\n\n## Notes\n\n* `hx-replace-url` is inherited and can be placed on a parent element\n* The [`HX-Replace-Url` response header](@/headers/hx-replace-url.md) has similar behavior and can override this attribute.\n* The [`hx-history-elt` attribute](@/attributes/hx-history-elt.md) allows changing which element is saved in the history cache.\n* The [`hx-push-url` attribute](@/attributes/hx-push-url.md) is a similar and more commonly used attribute, which creates a \n new history entry rather than replacing the current one.", 228 | "references": [ 229 | { 230 | "name": "Official documention", 231 | "url": "https://htmx.org/attributes/hx-replace-url/" 232 | } 233 | ] 234 | }, 235 | { 236 | "name": "hx-request", 237 | "description": "The `hx-request` attribute allows you to configure various aspects of the request via the following attributes:\n \n* `timeout` - the timeout for the request, in milliseconds\n* `credentials` - if the request will send credentials\n* `noHeaders` - strips all headers from the request\n\nThese attributes are set using a JSON-like syntax:\n\n```html\n
\n ...\n
\n```\n\nYou may make the values dynamically evaluated by adding the `javascript:` or `js:` prefix:\n\n```html\n
\n ...\n
\n```\n\n## Notes\n\n* `hx-request` is merge-inherited and can be placed on a parent element", 238 | "references": [ 239 | { 240 | "name": "Official documention", 241 | "url": "https://htmx.org/attributes/hx-request/" 242 | } 243 | ] 244 | }, 245 | { 246 | "name": "hx-select-oob", 247 | "description": "The `hx-select-oob` attribute allows you to select content from a response to be swapped in via an out-of-band swap. \nThe value of this attribute is comma separated list of elements to be swapped out of band. This attribute is almost\nalways paired with [hx-select](@/attributes/hx-select.md).\n\nHere is an example that selects a subset of the response content:\n\n```html\n
\n
\n \n
\n```\n\nThis button will issue a `GET` to `/info` and then select the element with the id `info-details`,\nwhich will replace the entire button in the DOM, and, in addition, pick out an element with the id `alert` \nin the response and swap it in for div in the DOM with the same ID.\n\nEach value in the comma separated list of values can specify any valid [`hx-swap`](@/attributes/hx-swap.md)\nstrategy by separating the selector and the swap strategy with a `:`.\n\nFor example, to prepend the alert content instead of replacing it:\n\n```html\n
\n
\n \n
\n```\n\n## Notes\n\n* `hx-select-oob` is inherited and can be placed on a parent element", 248 | "references": [ 249 | { 250 | "name": "Official documention", 251 | "url": "https://htmx.org/attributes/hx-select-oob/" 252 | } 253 | ] 254 | }, 255 | { 256 | "name": "hx-select", 257 | "description": "The `hx-select` attribute allows you to select the content you want swapped from a response. The value of\nthis attribute is a CSS query selector of the element or elements to select from the response.\n\nHere is an example that selects a subset of the response content:\n\n```html\n
\n \n
\n```\n\nSo this button will issue a `GET` to `/info` and then select the element with the id `info-detail`,\nwhich will replace the entire button in the DOM.\n\n## Notes\n\n* `hx-select` is inherited and can be placed on a parent element", 258 | "references": [ 259 | { 260 | "name": "Official documention", 261 | "url": "https://htmx.org/attributes/hx-select/" 262 | } 263 | ] 264 | }, 265 | { 266 | "name": "hx-sse", 267 | "description": "*Note: This attribute will be migrated to an extension in htmx 2.0, which is available now. Please visit the\n[SSE extension page](@/extensions/server-sent-events.md) to learn about the new implementation of SSE as an extension.*\n\nThe `hx-sse` allows you to work with [Server Sent Event](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events)\n`EventSource`s directly from HTML. The value of the attribute can be one or more of the following, separated by white space:\n\n* `connect:` - A URL to establish an `EventSource` against\n* `swap:` - Swap SSE message content into a DOM node on matching event names\n\n### Swap Message Content\n\nWhen an SSE connection has been established (using the `connect` keyword) the contents of SSE messages can be swapped into the DOM using the `swap` keyword. This can be done on the element that creates the SSE connection, or any child element of it. Multiple elements can use `swap` to listen for Server Sent Events.\n\nHere is an example:\n\n```html\n
\n ...\n
\n```\n\nThis example connects to a Server Sent Event stream, and begins swapping events named `eventName` into the same element.\n\nHere is another example:\n\n```html\n
\n
\n ...\n
\n
\n ...\n
\n
\n```\n\nThis example connects the Server Sent Event stream to the parent node, and directs different events to different child nodes based on the event name returned by the server.\n\n### Trigger Server Callbacks\n\nWhen a connection for server sent events has been established, child elements can listen for these events by using the special [`hx-trigger`](@/attributes/hx-trigger.md) syntax `sse:`. This, when combined with an `hx-get` or similar will trigger the element to make a request.\n\nHere is an example:\n\n```html\n
\n
\n ...\n
\n
\n```\n\nThis example establishes an SSE connection to the `event_stream` end point which then triggers\na `GET` to the `/chatroom` url whenever the `chatter` event is seen.\n\n### Named Events\n\nThe Server Sent Event specification allows servers to optionally include an event name with every event. **Named events** look like this:\n\n```txt\nevent: EventName\ndata:
Content to swap into your HTML page.
\n```\n\n```html\n
\n```\n\n### Data Only Events\n\nAlternatively, servers can provide **data only events** that do not have a name. In this case, Javascript (and HTMX) use the name \"message\" like this:\n\n```txt\ndata:
Content to swap into your HTML page.
\n```\n\n```html\n
\n```\n\n### Test SSE Server\n\nHtmx includes an SSE test server with many more examples of how to use Server Sent Events. Download the htmx source code from GitHub and navigate to /test/servers/sse to experiment.\n\n## Notes\n\n* `hx-sse` is not inherited", 268 | "references": [ 269 | { 270 | "name": "Official documention", 271 | "url": "https://htmx.org/attributes/hx-sse/" 272 | } 273 | ] 274 | }, 275 | { 276 | "name": "hx-swap-oob", 277 | "description": "The `hx-swap-oob` attribute allows you to specify that some content in a response should be \nswapped into the DOM somewhere other than the target, that is \"Out of Band\". This allows you to piggy back updates to other element updates on a response.\n\nConsider the following response HTML: \n\n```html\n
\n ...\n
\n
\n Saved!\n
\n\n```\n\nThe first div will be swapped into the target the usual manner. The second div, however, will be swapped in as a replacement for the element with the id `alerts`, and will not end up in the target.\n\nThe value of the `hx-swap-oob` can be:\n\n* `true`\n* any valid [`hx-swap`](@/attributes/hx-swap.md) value\n* any valid [`hx-swap`](@/attributes/hx-swap.md) value, followed by a colon, followed by a CSS selector\n\nIf the value is `true` or `outerHTML` (which are equivalent) the element will be swapped inline. \n\nIf a swap value is given, that swap strategy will be used.\n\nIf a selector is given, all elements matched by that selector will be swapped. If not, the element with an ID matching the new content will be swapped.\n\n## Notes\n\n* `hx-swap-oob` is not inherited\n* Out of band elements must be in the top level of the response, and not children of the top level elements.", 278 | "references": [ 279 | { 280 | "name": "Official documention", 281 | "url": "https://htmx.org/attributes/hx-swap-oob/" 282 | } 283 | ] 284 | }, 285 | { 286 | "name": "hx-swap", 287 | "description": "The `hx-swap` attribute allows you to specify how the response will be swapped in relative to the\n[target](@/attributes/hx-target.md) of an AJAX request. If you do not specify the option, the default is\n`htmx.config.defaultSwapStyle` (`innerHTML`).\n\nThe possible values of this attribute are:\n\n* `innerHTML` - Replace the inner html of the target element\n* `outerHTML` - Replace the entire target element with the response\n* `beforebegin` - Insert the response before the target element\n* `afterbegin` - Insert the response before the first child of the target element\n* `beforeend` - Insert the response after the last child of the target element\n* `afterend` - Insert the response after the target element\n* `delete` - Deletes the target element regardless of the response\n* `none`- Does not append content from response (out of band items will still be processed).\n\nThese options are based on standard DOM naming and the \n[`Element.insertAdjacentHTML`](https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentHTML)\nspecification.\n\nSo in this code:\n\n```html\n
Get Some HTML & Append It
\n```\n\nThe `div` will issue a request to `/example` and append the returned content after the `div`\n\n### Modifiers\n\nThe `hx-swap` attributes supports modifiers for changing the behavior of the swap. They are outlined below.\n\n#### Transition: `transition`\n\nIf you want to use the new [View Transitions](https://developer.mozilla.org/en-US/docs/Web/API/View_Transitions_API) API\nwhen a swap occurs, you can use the `transition:true` option for your swap. You can also enable this feature globally by\nsetting the `htmx.config.globalViewTransitions` config setting to `true`.\n\n#### Timing: `swap` & `settle`\n\nYou can modify the amount of time that htmx will wait after receiving a response to swap the content\nby including a `swap` modifier:\n\n```html\n \n
Get Some HTML & Append It
\n```\n\nSimilarly, you can modify the time between the swap and the settle logic by including a `settle`\nmodifier:\n\n```html\n \n
Get Some HTML & Append It
\n```\n\nThese attributes can be used to synchronize htmx with the timing of CSS transition effects.\n\n#### Title: `ignoreTitle`\n\nBy default, htmx will update the title of the page if it finds a `` tag in the response content. You can turn\noff this behavior by setting the `ignoreTitle` option to true.\n\n#### Scrolling: `scroll` & `show`\n\nYou can also change the scrolling behavior of the target element by using the `scroll` and `show` modifiers, both\nof which take the values `top` and `bottom`:\n\n```html\n <!-- this fixed-height div will scroll to the bottom of the div after content is appended -->\n <div style=\"height:200px; overflow: scroll\" \n hx-get=\"/example\" \n hx-swap=\"beforeend scroll:bottom\">\n Get Some HTML & Append It & Scroll To Bottom\n </div>\n```\n\n```html\n <!-- this will get some content and add it to #another-div, then ensure that the top of #another-div is visible in the \n viewport -->\n <div hx-get=\"/example\" \n hx-swap=\"innerHTML show:top\"\n hx-target=\"#another-div\">\n Get Some Content\n </div>\n```\n\nIf you wish to target a different element for scrolling or showing, you may place a CSS selector after the `scroll:`\nor `show:`, followed by `:top` or `:bottom`:\n\n```html\n <!-- this will get some content and swap it into the current div, then ensure that the top of #another-div is visible in the \n viewport -->\n <div hx-get=\"/example\" \n hx-swap=\"innerHTML show:#another-div:top\">\n Get Some Content\n </div>\n```\n\nYou may also use `window:top` and `window:bottom` to scroll to the top and bottom of the current window.\n\n\n```html\n <!-- this will get some content and swap it into the current div, then ensure that the viewport is scrolled to the\n very top -->\n <div hx-get=\"/example\" \n hx-swap=\"innerHTML show:window:top\">\n Get Some Content\n </div>\n```\n\n#### Focus scroll\n\nhtmx preserves focus between requests for inputs that have a defined id attribute. By default htmx prevents auto-scrolling to focused inputs between requests which can be unwanted behavior on longer requests when the user has already scrolled away. To enable focus scroll you can use `focus-scroll:true`.\n\n```html\n <input id=\"name\" hx-get=\"/validation\" \n hx-swap=\"outerHTML focus-scroll:true\"/>\n```\n\nAlternatively, if you want the page to automatically scroll to the focused element after each request you can change the htmx global configuration value `htmx.config.defaultFocusScroll` to true. Then disable it for specific requests using `focus-scroll:false`.\n\n```html\n <input id=\"name\" hx-get=\"/validation\" \n hx-swap=\"outerHTML focus-scroll:false\"/>\n```\n\n## Notes\n\n* `hx-swap` is inherited and can be placed on a parent element\n* The default value of this attribute is `innerHTML`\n* Due to DOM limitations, it\u2019s not possible to use the `outerHTML` method on the `<body>` element.\n htmx will change `outerHTML` on `<body>` to use `innerHTML`.\n* The default swap delay is 0ms\n* The default settle delay is 20ms", 288 | "references": [ 289 | { 290 | "name": "Official documention", 291 | "url": "https://htmx.org/attributes/hx-swap/" 292 | } 293 | ] 294 | }, 295 | { 296 | "name": "hx-sync", 297 | "description": "The `hx-sync` attribute allows you to synchronize AJAX requests between multiple elements.\n\nThe `hx-sync` attribute consists of a CSS selector to indicate the element to synchronize on, followed optionally\nby a colon and then by an optional syncing strategy. The available strategies are:\n\n* `drop` - drop (ignore) this request if an existing request is in flight (the default)\n* `abort` - drop (ignore) this request if an existing request is in flight, and, if that is not the case, \n *abort* this request if another request occurs while it is still in flight\n* `replace` - abort the current request, if any, and replace it with this request\n* `queue` - place this request in the request queue associated with the given element\n\nThe `queue` modifier can take an additional argument indicating exactly how to queue:\n\n* `queue first` - queue the first request to show up while a request is in flight\n* `queue last` - queue the last request to show up while a request is in flight\n* `queue all` - queue all requests that show up while a request is in flight\n\n## Notes\n\n* `hx-sync` is inherited and can be placed on a parent element\n\nThis example resolves a race condition between a form's submit request and an individual input's validation request. Normally, without using `hx-sync`, filling out the input and immediately submitting the form triggers two parallel requests to `/validate` and `/store`. Using `hx-sync=\"closest form:abort\"` on the input will watch for requests on the form and abort the input's request if a form request is present or starts while the input request is in flight.\n\n```html\n<form hx-post=\"/store\">\n <input id=\"title\" name=\"title\" type=\"text\" \n hx-post=\"/validate\" \n hx-trigger=\"change\"\n hx-sync=\"closest form:abort\">\n <button type=\"submit\">Submit</button>\n</form>\n```\n\nIf you'd rather prioritize the validation request over the submit request, you can use the `drop` strategy. This example will prioritize the validation request over the submit request so that if a validation request is in flight, the form cannot be submitted.\n\n```html\n<form hx-post=\"/store\">\n <input id=\"title\" name=\"title\" type=\"text\" \n hx-post=\"/validate\" \n hx-trigger=\"change\"\n hx-sync=\"closest form:drop\"\n >\n <button type=\"submit\">Submit</button>\n</form>\n```\n\nWhen dealing with forms that contain many inputs, you can prioritize the submit request over all input validation requests using the hx-sync `replace` strategy on the form tag. This will cancel any in-flight validation requests and issue only the `hx-post=\"/store\"` request. If you'd rather abort the submit request and prioritize any existing validation requests you can use the `hx-sync=\"this:abort\"` strategy on the form tag.\n\n```html\n<form hx-post=\"/store\" hx-sync=\"this:replace\">\n <input id=\"title\" name=\"title\" type=\"text\" hx-post=\"/validate\" hx-trigger=\"change\" />\n <button type=\"submit\">Submit</button>\n</form>\n```\n\nWhen implementing active search functionality the hx-trigger attribute's `delay` modifier can be used to debounce the user's input and avoid making multiple requests while the user types. However, once a request is made, if the user begins typing again a new request will begin even if the previous one has not finished processing. This example will cancel any in-flight requests and use only the last request. In cases where the search input is contained within the target, then using `hx-sync` like this also helps reduce the chances that the input will be replaced while the user is still typing.\n\n```html\n<input type=\"search\" \n hx-get=\"/search\" \n hx-trigger=\"keyup changed delay:500ms, search\" \n hx-target=\"#search-results\"\n hx-sync=\"this:replace\">\n```", 298 | "references": [ 299 | { 300 | "name": "Official documention", 301 | "url": "https://htmx.org/attributes/hx-sync/" 302 | } 303 | ] 304 | }, 305 | { 306 | "name": "hx-target", 307 | "description": "The `hx-target` attribute allows you to target a different element for swapping than the one issuing the AJAX\nrequest. The value of this attribute can be:\n\n* A CSS query selector of the element to target.\n* `this` which indicates that the element that the `hx-target` attribute is on is the target.\n* `closest <CSS selector>` which will find the [closest](https://developer.mozilla.org/docs/Web/API/Element/closest)\n ancestor element or itself, that matches the given CSS selector\n (e.g. `closest tr` will target the closest table row to the element).\n* `find <CSS selector>` which will find the first child descendant element that matches the given CSS selector.\n* `next <CSS selector>` which will scan the DOM forward for the first element that matches the given CSS selector.\n (e.g. `next .error` will target the closest following sibling element with `error` class)\n* `previous <CSS selector>` which will scan the DOM backwards for the first element that matches the given CSS selector.\n (e.g `previous .error` will target the closest previous sibling with `error` class)\n\n\nHere is an example that targets a div:\n\n```html\n<div>\n <div id=\"response-div\"></div>\n <button hx-post=\"/register\" hx-target=\"#response-div\" hx-swap=\"beforeend\">\n Register!\n </button>\n</div>\n```\n\nThe response from the `/register` url will be appended to the `div` with the id `response-div`.\n\nThis example uses `hx-target=\"this\"` to make a link that updates itself when clicked:\n```html\n<a hx-post=\"/new-link\" hx-target=\"this\" hx-swap=\"outerHTML\">New link</a>\n```\n\n## Notes\n\n* `hx-target` is inherited and can be placed on a parent element", 308 | "references": [ 309 | { 310 | "name": "Official documention", 311 | "url": "https://htmx.org/attributes/hx-target/" 312 | } 313 | ] 314 | }, 315 | { 316 | "name": "hx-trigger", 317 | "description": "The `hx-trigger` attribute allows you to specify what triggers an AJAX request. A trigger\nvalue can be one of the following:\n\n* An event name (e.g. \"click\" or \"my-custom-event\") followed by an event filter and a set of event modifiers\n* A polling definition of the form `every <timing declaration>`\n* A comma-separated list of such events\n\n### Standard Events\n\nA standard event, such as `click` can be specified as the trigger like so:\n\n```html\n<div hx-get=\"/clicked\" hx-trigger=\"click\">Click Me</div>\n```\n\n#### Standard Event Filters\n\nEvents can be filtered by enclosing a boolean javascript expression in square brackets after the event name. If\nthis expression evaluates to `true` the event will be triggered, otherwise it will be ignored.\n\n```html\n<div hx-get=\"/clicked\" hx-trigger=\"click[ctrlKey]\">Control Click Me</div>\n```\n\nThis event will trigger if a click event is triggered with the `event.ctrlKey` property set to true.\n\nConditions can also refer to global functions or state\n\n```html\n<div hx-get=\"/clicked\" hx-trigger=\"click[checkGlobalState()]\">Control Click Me</div>\n```\n\nAnd can also be combined using the standard javascript syntax\n\n```html\n<div hx-get=\"/clicked\" hx-trigger=\"click[ctrlKey&&shiftKey]\">Control-Shift Click Me</div>\n```\n\nNote that all symbols used in the expression will be resolved first against the triggering event, and then next\nagainst the global namespace, so `myEvent[foo]` will first look for a property named `foo` on the event, then look\nfor a global symbol with the name `foo`\n\n#### Standard Event Modifiers\n\nStandard events can also have modifiers that change how they behave. The modifiers are:\n\n* `once` - the event will only trigger once (e.g. the first click)\n* `changed` - the event will only change if the value of the element has changed. Please pay attention `change` is the name of the event and `changed` is the name of the modifier.\n* `delay:<timing declaration>` - a delay will occur before an event triggers a request. If the event\nis seen again it will reset the delay.\n* `throttle:<timing declaration>` - a throttle will occur after an event triggers a request. If the event\nis seen again before the delay completes, it is ignored, the element will trigger at the end of the delay.\n* `from:<Extended CSS selector>` - allows the event that triggers a request to come from another element in the document (e.g. listening to a key event on the body, to support hot keys)\n * A standard CSS selector resolves to all elements matching that selector. Thus, `from:input` would listen on every input on the page.\n * The extended CSS selector here allows for the following non-standard CSS values:\n * `document` - listen for events on the document\n * `window` - listen for events on the window\n * `closest <CSS selector>` - finds the [closest](https://developer.mozilla.org/docs/Web/API/Element/closest) ancestor element or itself, matching the given css selector\n * `find <CSS selector>` - finds the closest child matching the given css selector\n* `target:<CSS selector>` - allows you to filter via a CSS selector on the target of the event. This can be useful when you want to listen for\ntriggers from elements that might not be in the DOM at the point of initialization, by, for example, listening on the body,\nbut with a target filter for a child element\n* `consume` - if this option is included the event will not trigger any other htmx requests on parents (or on elements\n listening on parents)\n* `queue:<queue option>` - determines how events are queued if an event occurs while a request for another event is in flight. Options are:\n * `first` - queue the first event\n * `last` - queue the last event (default)\n * `all` - queue all events (issue a request for each event)\n * `none` - do not queue new events\n\nHere is an example of a search box that searches on `keyup`, but only if the search value has changed\nand the user hasn't typed anything new for 1 second:\n\n```html\n<input name=\"q\"\n hx-get=\"/search\" hx-trigger=\"keyup changed delay:1s\"\n hx-target=\"#search-results\"/>\n```\n\nThe response from the `/search` url will be appended to the `div` with the id `search-results`.\n\n### Non-standard Events\n\nThere are some additional non-standard events that htmx supports:\n\n* `load` - triggered on load (useful for lazy-loading something)\n* `revealed` - triggered when an element is scrolled into the viewport (also useful for lazy-loading). If you are using `overflow` in css like `overflow-y: scroll` you should use `intersect once` instead of `revealed`.\n* `intersect` - fires once when an element first intersects the viewport. This supports two additional options:\n * `root:<selector>` - a CSS selector of the root element for intersection\n * `threshold:<float>` - a floating point number between 0.0 and 1.0, indicating what amount of intersection to fire the event on\n\n### Triggering via the `HX-Trigger` header\n\nIf you're trying to fire an event from <code>HX-Trigger</code> response header, you will likely want to\nuse the `from:body` modifier. E.g. if you send a header like this <code>HX-Trigger: my-custom-event</code>\nwith a response, an element would likely need to look like this:\n\n```html\n <div hx-get=\"/example\" hx-trigger=\"my-custom-event from:body\">\n Triggered by HX-Trigger header...\n </div>\n```\n\nin order to fire.\n\nThis is because the header will likely trigger the event in a different DOM hierarchy than the element that you\nwish to be triggered. For a similar reason, you will often listen for hot keys from the body.\n\n### Polling\n\nBy using the syntax `every <timing declaration>` you can have an element poll periodically:\n\n```html\n<div hx-get=\"/latest_updates\" hx-trigger=\"every 1s\">\n Nothing Yet!\n</div>\n```\n\nThis example will issue a `GET` to the `/latest_updates` URL every second and swap the results into\nthe innerHTML of this div.\n\nIf you want to add a filter to polling, it should be added *after* the poll declaration:\n\n```html\n<div hx-get=\"/latest_updates\" hx-trigger=\"every 1s [someConditional]\">\n Nothing Yet!\n</div>\n```\n\n### Multiple Triggers\n\nMultiple triggers can be provided, separated by commas. Each trigger gets its own options.\n```html\n <div hx-get=\"/news\" hx-trigger=\"load, click delay:1s\"></div>\n```\nThis example will load `/news` immediately on page load, and then again with a delay of one second after each click.\n\n### Via JavaScript\n\nThe AJAX request can be triggered via JavaScript [`htmx.trigger()`](@/api.md#trigger), too.\n\n## Notes\n\n* `hx-trigger` is not inherited\n* `hx-trigger` can be used without an AJAX request, in which case it will only fire the `htmx:trigger` event", 318 | "references": [ 319 | { 320 | "name": "Official documention", 321 | "url": "https://htmx.org/attributes/hx-trigger/" 322 | } 323 | ] 324 | }, 325 | { 326 | "name": "hx-validate", 327 | "description": "The `hx-validate` attribute will cause an element to validate itself by way of the [HTML5 Validation API](@/docs.md#validation)\nbefore it submits a request.\n\nForm elements do this by default, but other elements do not.\n\n## Notes\n\n* `hx-validate` is not inherited", 328 | "references": [ 329 | { 330 | "name": "Official documention", 331 | "url": "https://htmx.org/attributes/hx-validate/" 332 | } 333 | ] 334 | }, 335 | { 336 | "name": "hx-vals", 337 | "description": "The `hx-vals` attribute allows you to add to the parameters that will be submitted with an AJAX request. \n\nBy default, the value of this attribute is a list of name-expression values in [JSON (JavaScript Object Notation)](https://www.json.org/json-en.html) \nformat.\n\nIf you wish for `hx-vals` to *evaluate* the values given, you can prefix the values with `javascript:` or `js:`.\n\n```html\n <div hx-get=\"/example\" hx-vals='{\"myVal\": \"My Value\"}'>Get Some HTML, Including A Value in the Request</div>\n\n <div hx-get=\"/example\" hx-vals='js:{myVal: calculateValue()}'>Get Some HTML, Including a Dynamic Value from Javascript in the Request</div>\n```\n\nWhen using evaluated code you can access the `event` object. This example includes the value of the last typed key within the input.\n\n```html\n <div hx-get=\"/example\" hx-trigger=\"keyup\" hx-vals='js:{lastKey: event.key}'>\n <input type=\"text\" />\n </div>\n```\n\n## Security Considerations\n\n* By default, the value of `hx-vals` must be valid [JSON](https://developer.mozilla.org/en-US/docs/Glossary/JSON). \n It is **not** dynamically computed. If you use the `javascript:` prefix, be aware that you are introducing\n security considerations, especially when dealing with user input such as query strings or user-generated content, \n which could introduce a [Cross-Site Scripting (XSS)](https://owasp.org/www-community/attacks/xss/) vulnerability. \n\n## Notes\n\n* `hx-vals` is inherited and can be placed on a parent element.\n* A child declaration of a variable overrides a parent declaration.\n* Input values with the same name will be overridden by variable declarations.", 338 | "references": [ 339 | { 340 | "name": "Official documention", 341 | "url": "https://htmx.org/attributes/hx-vals/" 342 | } 343 | ] 344 | }, 345 | { 346 | "name": "hx-vars", 347 | "description": "**NOTE: `hx-vars` has been deprecated in favor of [`hx-vals`](@/attributes/hx-vals.md), which is safer by default.**\n\nThe `hx-vars` attribute allows you to dynamically add to the parameters that will be submitted with an AJAX request. \n\nThe value of this attribute is a comma separated list of `name`:`<expression>` values, the same as the internal\nsyntax of javascript [Object Literals](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Grammar_and_types#Object_literals).\n\n```html\n <div hx-get=\"/example\" hx-vars=\"myVar:computeMyVar()\">Get Some HTML, Including A Dynamic Value in the Request</div>\n```\n\n## Security Considerations\n\n* The expressions in `hx-vars` are dynamically computed which allows you to add JavaScript code that will be executed. Be careful to **never** trust user input in your expressions as this may lead to a [Cross-Site Scripting (XSS)](https://owasp.org/www-community/attacks/xss/) vulnerability. If you are dealing with user input such as query strings or user-generated content, consider using [hx-vals](@/attributes/hx-vals.md) which is a safer alternative.\n\n## Notes\n\n* `hx-vars` is inherited and can be placed on a parent element.\n* A child declaration of a variable overrides a parent declaration.\n* Input values with the same name will be overridden by variable declarations.", 348 | "references": [ 349 | { 350 | "name": "Official documention", 351 | "url": "https://htmx.org/attributes/hx-vars/" 352 | } 353 | ] 354 | }, 355 | { 356 | "name": "hx-ws", 357 | "description": "*Note: This attribute will be migrated to an extension in htmx 2.0, which is available now. Please visit the \n[WebSockets extension page](@/extensions/web-sockets.md) to learn about the new implementation of Web Sockets as an extension.*\n\nThe `hx-ws` allows you to work with [Web Sockets](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_client_applications)\ndirectly from HTML. The value of the attribute can be one or more of the following, separated by commas:\n\n* `connect:<url>` or `connect:<prefix>:<url>` - A URL to establish an `WebSocket` connection against.\n* Prefixes `ws` or `wss` can optionally be specified. If not specified, HTMX defaults to add the location's scheme-type, host and port to have browsers send cookies via websockets.\n* `send` - Sends a message to the nearest websocket based on the trigger value for the element (either the natural event\nor the event specified by [`hx-trigger`])\n\nHere is an example:\n\n```html\n <div hx-ws=\"connect:/chatroom\">\n <div id=\"chat_room\">\n ...\n </div>\n <form hx-ws=\"send\">\n <input name=\"chat_message\">\n </form>\n </div>\n```\n\nThis example establishes a WebSocket to the `chatroom` end point. Content that is sent down from the websocket will\nbe parsed as HTML and swapped in by the `id` property, using the same logic as [Out of Band Swaps](@/attributes/hx-swap-oob.md).\n\nThe form uses the `send` syntax to indicate that when it is submitted, the form values should be serialized as JSON\nand send to the nearest enclosing `WebSocket`.\n\nThe serialized values will include a field, `HEADERS`, that includes the headers normally submitted with an htmx\nrequest.\n\nAfter an unexpected connection loss due to `Abnormal Closure`, `Service Restart` or `Try Again Later`,\nreconnecting is tried until successful.\nThe default reconnection interval is implemented with the full-jitter exponential-backoff algorithm.\nOwn implementations can be provided by setting `htmx.config.wsReconnectDelay` to a function with\n`retryCount` as its only parameter.\n\n\n### Test Web Sockets Server\n\nHtmx includes a WebSockets test server with many more examples of how to use Server Sent Events. Download the htmx source code from GitHub and navigate to /test/servers/ws to experiment.\n\n## Notes\n\n* `hx-ws` is not inherited", 358 | "references": [ 359 | { 360 | "name": "Official documention", 361 | "url": "https://htmx.org/attributes/hx-ws/" 362 | } 363 | ] 364 | } 365 | ], 366 | "valueSets": [ 367 | { 368 | "name": "swap", 369 | "values": [ 370 | { 371 | "name": "innerHTML", 372 | "description": "The default, puts the content inside the target element" 373 | }, 374 | { 375 | "name": "outerHTML", 376 | "description": "Replaces the entire target element with the returned content" 377 | }, 378 | { 379 | "name": "afterbegin", 380 | "description": "Prepends the content before the first child inside the target" 381 | }, 382 | { 383 | "name": "beforebegin", 384 | "description": "Prepends the content before the target in the targets parent element" 385 | }, 386 | { 387 | "name": "beforeend", 388 | "description": "Appends the content after the last child inside the target" 389 | }, 390 | { 391 | "name": "afterend", 392 | "description": "Appends the content after the target in the targets parent element" 393 | }, 394 | { 395 | "name": "delete", 396 | "description": "Deletes the target element regardless of the response" 397 | }, 398 | { 399 | "name": "none", 400 | "description": "Does not append content from response (Out of Band Swaps and Response Headers will still be processed)" 401 | } 402 | ] 403 | } 404 | ] 405 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "htmx-tags", 3 | "description": "Provides HTMX tag completion in HTML files in VSCode", 4 | "version": "0.0.7", 5 | "publisher": "otovo-oss", 6 | "repository": "https://github.com/otovo/htmx-tags", 7 | "engines": { 8 | "vscode": "^1.63.0" 9 | }, 10 | "contributes": { 11 | "html": { 12 | "customData": [ 13 | "./html.htmx-data.json" 14 | ] 15 | } 16 | } 17 | } 18 | --------------------------------------------------------------------------------