Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/ernestmarcinko/htmx-serverless

HTMX Serverless XHR requests. A frontend tool to define custom responses to XHR requests based on the request Path.
https://github.com/ernestmarcinko/htmx-serverless

dom dom-manipulation extension htmx htmx-app jquery library

Last synced: 4 days ago
JSON representation

HTMX Serverless XHR requests. A frontend tool to define custom responses to XHR requests based on the request Path.

Awesome Lists containing this project

README

        

# HTMX Serverless Client States ![npm](https://img.shields.io/npm/v/htmx-serverless) ![npm](https://img.shields.io/npm/dy/htmx-serverless) ![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)

To use HTMX you require a back-end server to handle the XHR requests and responses. In some cases it is nice to have only a client side interaction to handle client states, **without network requests**.

This extension uses the HTMX built-in Events to intercept some XHR requests before they fire and define response texts on the client side. No need for mock or "fake" server scripts. It is **HTMX without a server** (sort of).

## Usage

### In HTML head

```html

```

Then use the `window.htmxServerless` global to set custom handlers and responses.

```javascript
// Requests to "/handler1" are replaced with "

Custom HTML
"
htmxServerless.handlers.set('/handler1', '
Custom HTML
');

// Requests to "/handler2" are managed via a function
htmxServerless.handlers.set('/handler2', function(text, params, xhr){
console.log(this, text, params, xhr);
return "

Okay!

";
});

// Directly within the hx-{request} attribute, return value of myFunc is the replacement

Click to replace via myFunc!

```

### In custom bundles

```javascript
import htmx from "htmx.org";
import htmxServerless from "htmx-serverless";

// Initialize on your local htmx
htmxServerless.init(htmx);
```

## Examples

### Handler as a string

Assume we have a button with the `serverless` **hx-ext** sattribute, which triggers a request to the path "/clicked":

```html

Click to replace!

```

To define a serverless client side response to "/clicked" in the handlers Map():

```javascript
htmxServerless.handlers.set('/clicked',
`
Hey, you clicked me!
`
);
```

The button is then replaced with the HTML defined without triggering a request to the server. It's that simple.

[Try this example here.](https://jsfiddle.net/ernestmarcinko/h0rj5pez/1/)

### Handler as a Function set excplicitly

Tha handler function is a great tool for more complex conditional logic, like it would happen on the server side.
Let's make a simple click based number increment handler:

```html
Click to Increment


```

The handler only needs to print the text as "i" is incremented by hx-vals automatically:

```javascript
let i = 0;
htmxServerless.handlers.set('/count', function(text, params, xhr){
let status = params?.myVal < 10 ? "smaller or equals to" : "bigger than";
return `Value of "myVal" is: ${params?.myVal}, it is ${status} 10.`;
});
```

[Try this example here.](https://jsfiddle.net/ernestmarcinko/fm4tu9q8/2/)

Output:

![Alt text](img/auto-increment.png)

### Handler as a Function via js:myFunc

You can set the handler function implicitly in the hx-{get,post etc..} attribute via the js:myFunc syntax:

```html
Click to Increment


```

The handler function accepts the same arguments as before:

```javascript
let i = 0;
function counter(text, params, xhr){
let status = params?.myVal < 10 ? "smaller or equals to" : "bigger than";
return `Value of "myVal" is: ${params?.myVal}, it is ${status} 10.`;
}
```

[Try this example here.](https://jsfiddle.net/ernestmarcinko/x3kdownf/3/)

## Handler function

The handler function accepts 3 parameters (4 including "this") and returns a string:
* **this** => The target element
* **ext** => The replacement text (empty)
* **params** => The GET/POST or xhr-vals arguments
* **xhr** => The current request

```javascript
/**
* The handler function
*
* @param this:Element The target element
* @param text:string The replacement text (empty)
* @param params:Object The GET/POST or xhr-vals arguments
* @param xhr:XMLHttpRequest The current request
*
* @returns string
*/
function handler(text, params, xhr){
console.log(this, text, params, xhr);
return 'Hi!';
}
```

## How does it work?
It is really simple:
- The XHR request will not be sent, the ```.send()``` method is overridden for the intercepted request
- The XHR ```loadstart```, ```load``` and ```loadend``` events are dispatched instead, as if the request was finished "successfully"
- Only requests added to the ```htmxServerless.handlers``` Map are intercepted
- Requests are intercepted based on the request path, request arguments does not matter

## What else?

Nothing actually. This is only a baseline solution, but it works. There are no fancy features, as htmx is oath to be a small but effective library. With some creativity, you could make this more convenient, I leave it up to you :)