Premise
We have talked about optimistic UI before, but what if we actually want to add a new HTML fragment complete with an ID reflecting the stored record after a form is submitted?
Impossible? Not quite! There is a way to bestow a record with a valid ID before form submission on the client. Enter ULID.
“Universally Unique Lexicographically Sortable Identifiers” make sure that you can create a ID just client-side without having to worry about collisions. Their first 48bits represent the current timestamp, which is why they can be sorted just like regular integers.
Starting Point
We’re using the simplest TODO list app there is: a form, and an unordered list.
There’s only one thing that’s special about the form
- it’s tagged with data-optimistic-form
, and contains a Turbo Stream template for the list element to be appended.
https://stackblitz.com/edit/turbo-drive-ulids?file=index.html%3AL46
On the server we’re mocking a database just with an array:
https://stackblitz.com/edit/turbo-drive-ulids?file=index.js%3AL7
We’re then manually populating the list, emulating a template engine:
https://stackblitz.com/edit/turbo-drive-ulids?file=index.js%3AL13
When the form is POSTed, we append a new item to the todos
array containing the form data, and send a 303 response, as required by Turbo:
https://stackblitz.com/edit/turbo-drive-ulids?file=index.js%3AL36
(Note that I’m simulating a slow response by wrapping it in a 1 second timeout again).
Challenge
An event listener is already set up to handle turbo:submit-start
events. In it we’d like to
- create a ULID using the ULID javascript library, and
- populate the optimistic template, then append it to the page’s HTML using
insertAdjacentHTML
. Note that I’m using Dom Christie’s small composite helpers here to achieve this. (Essentially it’s a minimal browser templating engine)
As usual, here’s a preview of the outcome:
Note that the elements coming back to the server have the identical ULIDs as the optimistically added list items.