Introduction
Ajaxial is a library that embeds instructions for AJAX operations directly in your HTML structure, allowing you to easily model client-server interactions with little to no JavaScript. In order to do so, it offers a host of custom attributes that can be applied to any HTML element, which define Ajaxial's behavior.
For a simple example, the following HTML will show a button at the end of a partial article, which will replace itself with the rest of the article when clicked, assuming the proper server-side structure.
Installing
You can install Ajaxial by downloading it from the Github releases page and including it in your page via <script> tag.
Alternatively, you can install it without downloading via a Github CDN like JSDelivr.
Editor Support
Ajaxial has extensions that add autocompletion support for the following editors:
Core Attributes
Attributes are the core of Ajaxial's behavior, and allow you to define essentially everything about how your site should behave.
ajxl-path
The single most important attribute Ajaxial offers is ajxl-path. This marks an element as an "entrypoint" for Ajaxial behavior, and also provides the URL to which Ajaxial will make a request when triggered. Putting Ajaxial attributes on an element without ajxl-path will do nothing (unless a child element has ajxl-path – see Inheritance).
In fact, ajxl-path is so important that in some cases, it's the only Ajaxial attribute you need – every other attribute Ajaxial offers has a reasonable default value when not specified.
ajxl-event
When Ajaxial first finds an element with ajxl-path, the next thing it does is look at its ajxl-event for which events to listen for as triggers. When one of the events listed in ajxl-event is triggered on or bubbles up to that element, Ajaxial will begin its process of firing off a request.
Keep in mind that since the value of ajxl-event is used immediately when an element is processed, it's the only Ajaxial attribute which cannot have its value changed afterwards; attempting to do so will do nothing.
As a special shortcut, events that begin with ajaxial:, like ajaxial:load, can be written in shorthand by prefixing them with a colon, e.g. :load.
If ajxl-event is not specified, Ajaxial will try to pick a reasonable default event based on the type of element it's attaching to:
formelements will trigger onsubmitinput,select, andtextareaelements will trigger onchange- All other elements will trigger on
click
ajxl-method
Upon triggering, Ajaxial will look at the triggering element's ajxl-method to determine how to retrieve the requested content. The values available by default correspond to the various HTTP request methods:
getwill perform a GET request to the URL contained inajxl-path.postwill perform a POST request.putwill perform a PUT request.patchwill perform a PATCH request.deletewill perform a DELETE request.
If ajxl-method is not specified, it will default to get. You can also add your own custom methods – see Extending Ajaxial.
ajxl-target
By default, Ajaxial will look to insert the requested content into the triggering element. If you'd like to have it target a different element instead, you can use the ajxl-target attribute to define a CSS selector which will be used to find the target element(s).
If the selector specified by ajxl-target matches more than one element, the requested content will be duplicated and inserted into each.
ajxl-swap
When Ajaxial finishes making a request, it will attempt to insert the response body into the target element(s) as HTML. By default, it will replace the children of the target element(s) with the requested content; however, if you can override this behavior by setting ajxl-swap to one of the following values:
innerHTML– replace the target element's children (default).outerHTML– replace the target element.beforeBegin– insert before the target element.afterBegin– prepend before the target element's children.beforeEnd– append after the target element's children.afterEnd– insert after the target element.none– do not swap in the requested content.
You can also add your own custom swap strategies – see Extending Ajaxial.
ajxl-params
When sending a request, Ajaxial will generally either send no parameters, or if the triggering element is a form it will gather the values of each of that form's inputs as the parameters. If you need to add additional parameters on top of that behavior, you can specify them in JSON format with the ajxl-params attribute.
Just like automatically loaded parameters, these parameters will be used as the query string for GET/DELETE requests, and the request body for POST/PUT/PATCH requests.
HTTP Request Attributes
While all of the methods Ajaxial provides by default perform HTTP requests, this does not necessarily apply to custom methods. As a result, the following attributes are only applicable to the default methods, and may or may not be used by custom methods.
ajxl-encoding
Specifies the desired encoding of the request body for POST/PUT/PATCH requests. GET/DELETE requests don't use this attribute, as they send their parameters via the requested URL's query parameters.
Valid values for this attribute are:
application/x-www-form-urlencoded– encode the body as URL-encoded form data (default).application/json– encode the body as JSON.multipart/form-data– encode the body as multipart form data.
You can also add your own custom request encodings – see Extending Ajaxial.
ajxl-convert
Specifies the process Ajaxial should use for converting the response body from raw text to a DocumentFragment.
Valid values for this attribute are:
html– process the response body as HTML, including running<script>tags and applying<style>tags (default).plaintext– process the response body as normal text rather than HTML code.
You can also add your own custom response converters – see Extending Ajaxial.
ajxl-headers
By default, the only special HTTP header Ajaxial will send along with requests is the appropriate Content-Type for the given ajxl-encoding. If you need to add additional headers on top of that behavior, you can specify them in JSON format with the ajxl-headers attribute.
Utility Attributes
Ajaxial also provides a handful of utility attributes with various uses, which can adjust minor elements of its behavior or serve as hooks for external CSS/JavaScript.
ajxl-debounce
If present, Ajaxial will wait the specified number of milliseconds before acting upon a trigger, resetting the timer if another trigger occurs in that time. This is useful in cases such as "seach while typing", in order to prevent a request from being fired off for every single keystroke.
ajxl-settle
If present, Ajaxial will wait the specified number of milliseconds after a swap to remove the ajxl-added attribute from swapped-in elements. Defaults to 20ms if unspecified.
ajxl-inflight
Will be automatically added to triggering elements during method execution, such as while waiting for a response to an HTTP request, to allow for hooking into the process with CSS to display loading indicators or similar.
ajxl-added
Will be automatically added to elements at the top level of a response that have just been swapped in, to allow for hooking into the process with CSS to display transitions or similar. Will be removed after 20ms by default, or a number of milliseconds specified by ajxl-settle if present.
Inheritance
Except for ajxl-path, all attributes provided by Ajaxial are inherited from parent elements if they aren't present on the triggering element. For example, you can set ajxl-encoding on the page body to very simply ensure all Ajaxial POST requests on your page are sent as JSON:
If multiple parent elements provide a value for an attribute, the innermost parent takes priority. For example, clicking the button in the example below will send a GET request, not a POST request.
disinherit
You can also prevent inheritance by setting the value of any Ajaxial attribute to the special keyword value disinherit. If set on the triggering element, the default value will be used, and if set on a parent element, only inherited values within that parent element will be considered.
For example, the following code will result in the same as the above example, since ajxl-method falls back on the default value of get.
Integrating with JavaScript
While Ajaxial does its best to work seamlessly in as many situations as possible, it simply isn't possible to catch every edge case. In some cases, it will be necessary to manually tell Ajaxial where to look for elements with its attributes.
AJAX / Generated Elements
If you use systems other than Ajaxial for AJAX, or generate elements via JavaScript, Ajaxial won't know to look for them by default. You can use the Ajaxial.process function to notify it of new elements.
Shadow DOM
Similarly, Ajaxial doesn't know about or access the shadow DOM on its own. If you want to pair it with web components or other shadow DOM-based libraries, you'll need to call Ajaxial.process on each shadow root to connect it.
Keep in mind that ajxl-target finds elements based on the root element it's in; if you use it inside of shadow DOM, it will only find elements inside the same shadow root. This means that it's not currently possible for Ajaxial to cross the boundaries of a given shadow root in either direction, bar creating extensions as described below.
Extending Ajaxial
While Ajaxial provides an extensive amount of functionality by default, sometimes certain behaviors can only be achieved by extending it with JavaScript. The majority of Ajaxial's functionality is heavily modular to allow for as much extensibility as possible.
Custom Methods
By adding new functions to the Ajaxial.methods object, you can add new values to be accepted by ajxl-method.
Each method is an async function, identified by its key in the Ajaxial.methods object, which takes the following parameters:
path– a string containing the value of the triggering element'sajxl-path.source– the triggering element.params– an object corresponding to the keys and values of each parameter, determined fromajxl-paramsor form elements.
Methods should return either a DocumentFragment or a function of the form HTMLElement => DocumentFragment. If a DocumentFragment is returned, it will be used directly as the content for each swap; this should be used in 99% of cases.
If a function is returned, it will be called for each target element and passed the expected parent element after the swap occurs. Note that this is not necessarily the target element – this is passed to allow for Ajaxial to determine the context into which the content will be swapped, which may be either the target element or its parent.
Custom Swap Strategies
By adding new functions to the Ajaxial.swapStrategies object, you can add new values to be accepted by axjl-swap.
Each swap strategy is a function, identified by its key in the Ajaxial.swapStrategies object, which takes the following parameters:
target– the target element.fragment– theDocumentFragmentto be swapped in.
Note: swap strategies should absolutely never have unnecessary side effects! In some cases, Ajaxial will attempt to dry-run a swap strategy to determine the parent element after the swap is performed, which may cause unexpected results if the swap strategy performs side effects other than the swap itself.
Custom Encodings
By adding new functions to the Ajaxial.requestEncodings object, you can add new values to be accepted by axjl-encoding.
Each request encoding is a function, identified by its key in the Ajaxial.requestEncodings object, which takes the following parameters:
params– an object corresponding to the keys and values of each parameter, determined fromajxl-paramsor form elements.
Request encodings should return a valid value for a fetch request body, calculated from the given parameters. Keep in mind that the name of each request encoding must also be a valid MIME type corresponding to the resulting encoded data.
Custom Converters
By adding new functions to the Ajaxial.responseConverters object, you can add new values to be accepted by axjl-convert.
Each response converter is a function, identified by its key in the Ajaxial.responseConverters object, which takes the following parameters:
body– a string containing the response body....params– an optional list of parameters specified after the converter name inajxl-convert.
Response converters should return the same way as methods, as the request body will be passed through them to create the DocumentFragment expected from the default methods.
Response converters can also accept parameters specified in the ajxl-convert attribute, to allow for specialization of generic converters.
Adjusting Defaults
All of Ajaxial's default values for attributes which refer to extensible registries can be adjusted by overriding the key in that registry corresponding to the Ajaxial.default symbol.
You can also adjust the default value of ajxl-event on a per-tag basis by adding keys to Ajaxial.defaultEvents.