├── .editorconfig
├── .github
└── workflows
│ ├── docs.yml
│ └── tests.yml
├── .gitignore
├── LICENSE.md
├── README.md
├── builds
├── cdn.js
├── module.js
└── server.js
├── cypress.config.js
├── docs
├── _includes
│ ├── demo.njk
│ ├── example.njk
│ ├── googlec8986a0731969a6e.html
│ ├── jukebox.svg
│ ├── layout.njk
│ ├── logo.svg
│ ├── page.njk
│ ├── phone.svg
│ ├── remote.svg
│ ├── sample.njk
│ ├── server.svg
│ └── topper.svg
├── changelog.md
├── comparisons.md
├── css
│ ├── lite-yt-embed.css
│ ├── main.css
│ └── prism-a11y-dark.css
├── eleventy.config.js
├── examples.njk
├── examples
│ ├── bulk-update.md
│ ├── delete-row.md
│ ├── dialog-form.md
│ ├── dialog.md
│ ├── edit-row.md
│ ├── examples.json
│ ├── filterable-content.md
│ ├── infinite-scroll.md
│ ├── inline-edit.md
│ ├── inline-validation.md
│ ├── instant-search.md
│ ├── lazy-load.md
│ ├── loading.md
│ ├── notifications.md
│ ├── progress-bar.md
│ ├── server-events.md
│ └── toggle-button.md
├── fonts
│ ├── helsinki.woff
│ ├── helsinki.woff2
│ ├── ibm-plex-mono-400.woff
│ └── ibm-plex-mono-400.woff2
├── github.md
├── img
│ ├── bg-texture.png
│ ├── favicon.svg
│ ├── share.png
│ └── sponsors
│ │ └── moonbase-labs.svg
├── index.njk
├── js
│ ├── lite-yt-embed.js
│ └── main.js
├── postcss.config.js
├── reference.njk
├── reference
│ ├── ajax.md
│ ├── configuration.md
│ ├── creating-demos.md
│ ├── events.md
│ ├── installation.md
│ ├── loading-states.md
│ ├── navigation.md
│ ├── reference.json
│ ├── usage.md
│ ├── x-focus.md
│ ├── x-headers.md
│ ├── x-merge.md
│ ├── x-sync.md
│ └── x-target.md
└── tailwind.config.js
├── package-lock.json
├── package.json
├── scripts
└── build.js
├── src
├── index.js
└── server.js
└── tests
├── ajax.cy.js
├── cache.cy.js
├── cdn-late.html
├── cdn.cy.js
├── cdn.html
├── configure.cy.js
├── dynamic.cy.js
├── events.cy.js
├── exceptions.cy.js
├── focus.cy.js
├── form.cy.js
├── history.cy.js
├── index.html
├── link.cy.js
├── load.cy.js
├── map.cy.js
├── merge.cy.js
├── queue.cy.js
├── status.cy.js
├── sync.cy.js
└── utils.js
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | charset = utf-8
5 | end_of_line = lf
6 | insert_final_newline = true
7 | indent_style = space
8 | indent_size = 2
9 | trim_trailing_whitespace = true
10 |
--------------------------------------------------------------------------------
/.github/workflows/docs.yml:
--------------------------------------------------------------------------------
1 | name: Build Documentation
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 |
8 | jobs:
9 | build:
10 | runs-on: ubuntu-22.04
11 |
12 | steps:
13 | - uses: actions/checkout@v2
14 |
15 | - name: Setup Node
16 | uses: actions/setup-node@v1
17 | with:
18 | node-version: '18.x'
19 |
20 | - name: Install dependencies & build
21 | run: |
22 | npm install
23 | npm run build
24 | npm run build:docs
25 |
26 | - name: Deploy
27 | uses: peaceiris/actions-gh-pages@v3
28 | with:
29 | publish_dir: ./docs/_site
30 | github_token: ${{ secrets.GITHUB_TOKEN }}
31 | cname: alpine-ajax.js.org
32 |
--------------------------------------------------------------------------------
/.github/workflows/tests.yml:
--------------------------------------------------------------------------------
1 |
2 | name: Run Tests
3 |
4 | on:
5 | push:
6 | branches:
7 | - main
8 | pull_request:
9 |
10 | jobs:
11 | tests:
12 |
13 | runs-on: ubuntu-latest
14 |
15 | steps:
16 | - name: Checkout repository
17 | uses: actions/checkout@v3
18 |
19 | - name: Run tests
20 | uses: cypress-io/github-action@v5
21 | with:
22 | build: npm run build
23 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /node_modules
2 | /dist
3 | /docs/_site
4 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 Christian Taylor
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Alpine AJAX
2 |
3 | A set of AlpineJS directives that enable forms and links to make asynchronous HTTP requests and render the response to the page.
4 |
5 | Learn more at [alpine-ajax.js.org](https://alpine-ajax.js.org).
6 |
7 | ## Contributing
8 |
9 | Clone this repo and run `npm install` to get started.
10 |
11 | `npm run build` will build a fresh version of the library in `/dist`.
12 |
13 | `npm run watch` will watch for file changes and rebuild the library.
14 |
15 | ## Documentation
16 |
17 | The documentation site is hosted at [https://alpine-ajax.js.org](https://alpine-ajax.js.org), the source files are located in `/docs`.
18 |
19 | `npm run start` will locally serve the documentation site built with [Eleventy](https://www.11ty.dev/). The site automatically bundles the latest Alpine AJAX build in `/docs/js/main.js`.
20 |
21 | ## Testing
22 |
23 | Tests are located in `/tests`.
24 |
25 | `npm run test` will run the test suite in the [Cypress](https://www.cypress.io/) CLI.
26 |
27 | `npm run cypress` will open the Cypress browser UI.
28 |
29 | ## Sponsors
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/builds/cdn.js:
--------------------------------------------------------------------------------
1 | import ajax from '../src/index'
2 |
3 | document.addEventListener('alpine:initializing', () => {
4 | ajax.configure(window.alpineAJAX || {})
5 | ajax(window.Alpine)
6 | })
7 |
--------------------------------------------------------------------------------
/builds/module.js:
--------------------------------------------------------------------------------
1 | import ajax from '../src/index.js'
2 |
3 | export default ajax
4 |
--------------------------------------------------------------------------------
/builds/server.js:
--------------------------------------------------------------------------------
1 | import '../src/server.js'
2 |
--------------------------------------------------------------------------------
/cypress.config.js:
--------------------------------------------------------------------------------
1 | const { defineConfig } = require("cypress")
2 |
3 | module.exports = defineConfig({
4 | e2e: {
5 | retries: 2, // This is a workaround for flaky network tests
6 | specPattern: 'tests/*.cy.js',
7 | supportFile: false,
8 | },
9 | downloadsFolder: 'tests/downloads',
10 | fixturesFolder: false,
11 | video: false,
12 | screenshotOnRunFailure: false,
13 | })
14 |
--------------------------------------------------------------------------------
/docs/_includes/demo.njk:
--------------------------------------------------------------------------------
1 |
6 |
<form x-target="songs" action="/songs">
<input name="search" @input.debounce="$el.form.requestSubmit()">
</form>
<ul id="songs">…</ul>
2 |
--------------------------------------------------------------------------------
/docs/_includes/topper.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/docs/changelog.md:
--------------------------------------------------------------------------------
1 | ---
2 | eleventyNavigation:
3 | key: Changelog
4 | url: https://github.com/imacrayon/alpine-ajax/releases
5 | order: 4
6 | permalink: false
7 | ---
8 |
--------------------------------------------------------------------------------
/docs/comparisons.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: page.njk
3 | title: Comparisons
4 | description: Compare Alpine AJAX to similar frameworks
5 | eleventyNavigation:
6 | key: Comparisons
7 | order: 3
8 | ---
9 |
10 | # Comparisons
11 |
12 | What follows is a general guide that lays out some comparisons between Alpine AJAX and other similar libraries. The intention here is to give you some context around how Alpine AJAX sets itself apart and when it may or may not makes sense to use. All of the following libraries are awesome in their own right, and each one served as inspiration for Alpine AJAX.
13 |
14 | * [HTMX](#htmx)
15 | * [Hotwired Turbo](#hotwired-turbo)
16 | * [Unpoly](#unpoly)
17 | * [Laravel Livewire](#laravel-livewire)
18 |
19 | ## HTMX
20 |
21 | [https://htmx.org](https://htmx.org)
22 |
23 | Both HTMX and Alpine AJAX are server-agnostic, they'll integrate nicely with almost any server-side language and architecture. Even more, both Alpine AJAX and HTMX work with Alpine.js. In general the HTMX community encourages developers to use [_hyperscript](https://hyperscript.org/) in place of Alpine.js, but Alpine.js is still considered a good option for adding client-side interaction. Since Alpine AJAX is designed as an Alpine.js plugin, it follows Alpine.js conventions; so if you're already building apps with Alpine.js, Alpine AJAX will feel more familiar.
24 |
25 | HTMX favors flexibility where as Alpine AJAX prefers [convention over configuration](https://en.wikipedia.org/wiki/Convention_over_configuration). Beyond the low-level tooling that HTMX provides, the library isn't very prescriptive about how it should be used. The [HTMX documentation for updating content](https://htmx.org/examples/update-other-content/) is one example of the library's lack of opinion: It presents you with four different solutions and leaves it up to you to consider the trade-offs for each. In contrast, Alpine AJAX tries to provide you with more guidance so you can become productive faster without stumbling into common accessibility and progressive enhancement pitfalls.
26 |
27 | HTMX weighs in at 13kB of JavaScript compared to only 3kB for Alpine AJAX.
28 |
29 | ## Hotwired Turbo
30 |
31 | [https://turbo.hotwired.dev](https://turbo.hotwired.dev)
32 |
33 | Turbo can be paired with almost any server-side language, however it holds strict opinions around response status codes, headers, and content; so it does require some back-end configuration to get started. In contrast, Alpine AJAX only requires that the server respond with HTML so you can be up and running more quickly. It's worth noting that Turbo is designed to work with the [Ruby on Rails](https://rubyonrails.org/) framework out of the box, so installation should be easy if you're building a Rails app.
34 |
35 | For client-side interactions, Turbo works well with Alpine.js, however the Turbo community generally encourages developers to use [Stimulus](https://stimulus.hotwired.dev/).
36 |
37 | Alpine AJAX enables functionality very similar to Turbo's `Below are a set of UX patterns implemented using Alpine AJAX with minimal HTML and styling.
13 | 14 |You can copy and paste them and then adjust them for your needs.
15 | 16 |Edit | 17 |Name | 18 |Status | 19 |
---|---|---|
24 | | Finn Mertins | 25 |Active | 26 |
Name | 17 |19 | |
---|