Premise
Sometimes (not always) the simplest solution to a problem is also the most straightforward one. Suppose we have the following problem:
- a textarea that should accept markdown
- a preview area that should show the rendered markdown as you type
- changes are automatically saved.
As it turns out, you can solve all three issues with a single Turbo Frame wrapping a form.
Starting Point
In our markup, we have a simple form containing a <textarea>
. That form itself is wrapped by a Turbo Frame:
https://stackblitz.com/edit/turbo-frames-markdown-preview?file=index.html%3AL41-L41
Note that below the form there’s an <article>
tag containing a {content}
placeholder to be filled with the rendered markdown on the server.
Speaking of, we are mimicking a “template engine” again in the GET route, simply replacing this placeholder by the string held in a local content
variable. The equivalent in Rails would be an instance variable, or simply an attribute on a model.
https://stackblitz.com/edit/turbo-frames-markdown-preview?file=index.js%3AL18
Whenever the form is submitted, we transform the markdown into HTML markup using the marked
package (the equivalent in Ruby-land would be kramdown
, for example):
https://stackblitz.com/edit/turbo-frames-markdown-preview?file=index.js%3AL28
The result is then stored in the mentioned content
variable, and a 303 response is issued to redirect back to /
.
Challenge
To render a preview, it’s just necessary to submit the form. Write an event listener that triggers a POST request and reloads the frame:
This is what the result looks like:
If you’re curious as to why a <turbo-frame>
is even needed, try to comment it out in the HTML. What do you observe?
Teaser
Triggering a server roundtrip for every keystroke might not be feasible. What could you do to remedy this?