Everyone, I scoured the web and cobbled together a solution. I’ll do a writeup on my blog soon. For now, to summarize:
In the LiveView’s .ex
file:
@impl true
def handle_event("download", form, socket) do
svg = form_to_svg(form)
fp = filename_args(form)
filename = "obidenticon_#{fp}.svg"
filename_args(form)
Process.send_after(self(), :clear_flash, 2000)
{:noreply,
socket
|> put_flash(:info, "Downloading #{filename}")
|> push_event("download-file", %{
svg: svg,
filename: filename
})}
end
In the LiveView’s HEEx template:
<.form for={@form} phx-change="validate" phx-submit="download">
...
<button type="submit">Download SVG</button>
</.form>
<script>
window.addEventListener("phx:download-file", (event) => {
console.log("Event received:", event);
var element = document.createElement('a');
const encodedSvg = encodeURIComponent(event.detail.svg);
const hrefValue = 'data:image/svg+xml;charset=utf-8,' + encodedSvg;
element.setAttribute('href', hrefValue);
element.setAttribute('download', event.detail.filename);
element.style.display = 'none';
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
});
</script>
It’s up and running at https://obidenticon.overbring.com/