HTMX Integration #3
Replies: 2 comments
-
Hi! Yes, that's in the plan. I currently have an application that uses both HTMX and Cami, and I'll extract patterns from it then share in this thread. |
Beta Was this translation helpful? Give feedback.
-
Here's a simplified / truncated example (I'll put it in the This is a rich interactive data table that shows an index of articles. Some assumptions:
<sortable-table-element
data='<%= h articles.to_json %>'
></sortable-table-element> In this example, the ruby code is wrapped around In our ReactiveElement constructor, we retrieve the data from the attribute using constructor() {
super();
this.sortKey = this.observable(null);
this.sortOrder = this.observable(1); // 1 for ascending, -1 for descending
this.dataFromAttr = this.observableAttr('data', (data) => {
return JSON.parse(data).map(item => ({ ...item, selected: false }));
});
this.data = this.observable(this.dataFromAttr.value);
} Notice that we receive the data as a string, and we need to parse then transform it. The template renders a table with interactive features like filter, sort, and select row. At the top, there is a dropdown with name "Bulk Actions", which allows you to bulk delete articles using HTMX. Here, we use This is then dispatched to the server, the server deletes the articles for the given ID, then we instruct the client to redirect using the Here is the shortened code: <section>
<sortable-table-element
data='<%= h articles.to_json %>'
></sortable-table-element>
<script type="module">
const { html, ReactiveElement } = cami;
class SortableTableElement extends ReactiveElement {
constructor() {
super();
this.sortKey = this.observable(null);
this.sortOrder = this.observable(1); // 1 for ascending, -1 for descending
this.dataFromAttr = this.observableAttr('data', (data) => {
return JSON.parse(data).map(item => ({ ...item, selected: false }));
});
this.data = this.observable(this.dataFromAttr.value);
}
// ... rest of the methods ...
template() {
return html`
<nav>
<h1>Articles</h1>
<details>
<summary>Bulk actions</summary>
<ul>
<li><a hx-delete="/articles/delete" hx-vals='${JSON.stringify({ ids: [this.data.value.filter(item => item.selected).map(item => item.id)] })}'>Delete</a></li>
</ul>
</details>
</nav>
<table>
<thead>
<tr>
<th><input type="checkbox" @change=${(e) => this.handleSelectAll(e.target.checked)} /></th>
<th @click=${() => this.handleSort('title')}>Title</th>
<th @click=${() => this.handleSort('status')}>Status</th>
<th @click=${() => this.handleSort('visibility')}>Visibility</th>
</tr>
<tr>
<th></th>
<th><input type="text" placeholder="Filter by title" @input=${(e) => this.handleFilter('title', e.target.value)} /></th>
<th><input type="text" placeholder="Filter by status" @input=${(e) => this.handleFilter('status', e.target.value)} /></th>
<th><input type="text" placeholder="Filter by visibility" @input=${(e) => this.handleFilter('visibility', e.target.value)} /></th>
</tr>
</thead>
<tbody>
${this.data.value.map(item => html`
<tr>
<td><input type="checkbox" .checked=${item.selected} @change=${(e) => this.handleSelect(item, e.target.checked)} /></td>
<td><a href="/articles/${item.id}">${item.title}</a></td>
<td>${item.status}</td>
<td>${item.visibility}</td>
</tr>
`)}
</tbody>
</table>
`;
}
}
customElements.define('sortable-table-element', SortableTableElement);
</script>
</section> |
Beta Was this translation helpful? Give feedback.
-
I was looking at the examples provided for instance, Component where there is form is returned from the script. There is one confusion define HTMX attributes ( hx-get, hx-swap, hx- trigger, hx-target etc) as the part of component will work effectively and will be able to alter theDOM based on hx tags. I believe few examples using HTMX should also included because in any case this library is intended to be used with Hypermedia driven applications.
Beta Was this translation helpful? Give feedback.
All reactions