htmx/www/content/examples/bulk-update.md
Denis Palashevskii 18aa2470a0
fix accesibility and keyboard navigation issues in examples (#1433)
* fix accesibility and keyboard navigation issues in examples

* fix review comments

* remove redundant aria attributes, remove redundant autofocus

* rework progress bar demo's accesibility

* rework tabs HATEOS example to be more ARIA compliant

* rework tabs _hyperscript example to be ARIA compliant
2023-06-30 11:28:54 -05:00

164 lines
4.6 KiB
Markdown

+++
title = "Bulk Update"
template = "demo.html"
+++
This demo shows how to implement a common pattern where rows are selected and then bulk updated. This is
accomplished by putting a form around a table, with checkboxes in the table, and then including the checked
values in `PUT`'s to two different endpoints: `activate` and `deactivate`:
```html
<div hx-include="#checked-contacts" hx-target="#tbody">
<button class="btn" hx-put="/activate">Activate</button>
<button class="btn" hx-put="/deactivate">Deactivate</button>
</div>
<form id="checked-contacts">
<table>
<thead>
<tr>
<th></th>
<th>Name</th>
<th>Email</th>
<th>Status</th>
</tr>
</thead>
<tbody id="tbody">
<tr class="">
<td><input type='checkbox' name='ids' value='0'></td>
<td>Joe Smith</td>
<td>joe@smith.org</td>
<td>Active</td>
</tr>
...
</tbody>
</table>
</form>
```
The server will either activate or deactivate the checked users and then rerender the `tbody` tag with
updated rows. It will apply the class `activate` or `deactivate` to rows that have been mutated. This allows
us to use a bit of CSS to flash a color helping the user see what happened:
```css
.htmx-settling tr.deactivate td {
background: lightcoral;
}
.htmx-settling tr.activate td {
background: darkseagreen;
}
tr td {
transition: all 1.2s;
}
```
You can see a working example of this code below.
<style scoped="">
.htmx-settling tr.deactivate td {
background: lightcoral;
}
.htmx-settling tr.activate td {
background: darkseagreen;
}
tr td {
transition: all 1.2s;
}
</style>
{{ demoenv() }}
<script>
//=========================================================================
// Fake Server Side Code
//=========================================================================
// data
var dataStore = function(){
var data = [
{ name: "Joe Smith", email: "joe@smith.org", status: "Active" },
{ name: "Angie MacDowell", email: "angie@macdowell.org", status: "Active" },
{ name: "Fuqua Tarkenton", email: "fuqua@tarkenton.org", status: "Active" },
{ name: "Kim Yee", email: "kim@yee.org", status: "Inactive" }
];
return {
findContactById : function(id) {
return data[id];
},
allContacts : function() {
return data;
}
}
}()
function getIds(params) {
if(params['ids']) {
if(Array.isArray(params['ids'])) {
return params['ids'].map(x => parseInt(x))
} else {
return [parseInt(params['ids'])];
}
} else {
return [];
}
}
// routes
init("/demo", function(request){
return displayUI(dataStore.allContacts());
});
onPut("/activate", function(request, params){
var ids = getIds(params);
for (var i = 0; i < ids.length; i++) {
dataStore.findContactById(ids[i])['status'] = 'Active';
}
return displayTable(ids, dataStore.allContacts(), 'activate');
});
onPut("/deactivate", function (req, params) {
var ids = getIds(params);
for (var i = 0; i < ids.length; i++) {
dataStore.findContactById(ids[i])['status'] = 'Inactive';
}
return displayTable(ids, dataStore.allContacts(), 'deactivate');
});
// templates
function displayUI(contacts) {
return `<h3>Select Rows And Activate Or Deactivate Below</h3>
<form id="checked-contacts">
<table>
<thead>
<tr>
<th></th>
<th>Name</th>
<th>Email</th>
<th>Status</th>
</tr>
</thead>
<tbody id="tbody">
${displayTable([], contacts, "")}
</tbody>
</table>
</form>
<br/>
<br/>
<div hx-include="#checked-contacts" hx-target="#tbody">
<button class="btn" hx-put="/activate">Activate</button>
<button class="btn" hx-put="/deactivate">Deactivate</button>
</div>`
}
function displayTable(ids, contacts, action) {
var txt = "";
for (var i = 0; i < contacts.length; i++) {
var c = contacts[i];
txt += `\n<tr class="${ids.includes(i) ? action : ""}">
<td><input type='checkbox' name='ids' value='${i}'></td><td>${c.name}</td><td>${c.email}</td><td>${c.status}</td>
</tr>`
}
return txt;
}
</script>