Valeriy

Valeriy

Hi guys!
I try CSV Export with Phoenix and LiveView with this guide CSV Export with Phoenix and LiveView - Tutorials and screencasts for Elixir, Phoenix and LiveView (fullstackphoenix.com).
I use filters for data displayed as a table on my heex:

<form phx-change=“filter” class=“pt-4 pb-4 text-sm”>
<span class=“inline-flex”>
<span>
<label>node:</label>
<%= Phoenix.HTML.Form.number_input(:options, :node,
value: @options.node,
“phx-debounce”: “300”,
class: “text-sm border border-slate-300 text-slate-600 w-20 ml-2 mr-4”
) %>
</span>
<span>
<label>date:
<%= Phoenix.HTML.Form.date_input(:options, :date,
value: @options.date,
class: “text-sm border border-slate-300 text-slate-600 ml-2 mr-4”
) %>
</span>
</span>
</form>

and link to export on the same heex:

<.link
href={~p"/export?#{%{message: “journals”, node: @options.node, date: @options.date, sort_by: @options.sort_by, sort_order: @options.sort_order}}“}
method=“post”
class=”-ml-px inline-flex items-center px-3 h-10 border border-slate-300 bg-white text-base font-medium text-slate-600 no-underline hover:bg-slate-300 rounded-md"
>
Export
</.link>

In export controller:

def create(conn, %{“message” => “journals”, “node” => node, “date” => date, “sort_by” => sort_by, “sort_order” => sort_order}) do

csv_data = …

conn
|> put_resp_content_type(“text/csv”)
|> put_resp_header(“content-disposition”, “attachment; filename="journals.csv"”)
|> put_root_layout(false)
|> send_resp(200, csv_data)
end

CSV export works fine, but i have some quiestion: the filter (form) stops responding to changes after loading csv-file, but all other links work (pagination and sorting).
It seems that “phx-change” don’t send any messages to my live_view.

I also read this topics, but could not find an answer to my question:

Thank you.

Showing Posts 1 to 8

codeanpeace

codeanpeace

Off the top of my head, I suspect what’s going on here is that the LiveView socket disconnects on export since clicking a default generated <.link href=...> results in traditional browser navigation. You can check if this is the case by using the phx-disconnected binding to show/do something.

If that is the case, you could try specifying the anchor tag’s download attribute and/or target attribute as new tab and see if that makes a difference.

Updated to add:
https://github.com/phoenixframework/phoenix_live_view/issues/2552

Valeriy

Valeriy OP

Thank you codeanpeace!
target=“_blank” works fine, but this causes the opening of a blank page for a short time. It seems not very nice.

I couldn’t get download attribute to work. I try this:

<.link
href={~p"/export?#{%{message: “journals”, node: @options.node, date: @options.date, sort_by: @options.sort_by, sort_order: @options.sort_order}}“}
method=“post”
download
…>
Export
</.link>

or

<.link
href={~p"/export?#{%{message: “journals”, node: @options.node, date: @options.date, sort_by: @options.sort_by, sort_order: @options.sort_order}}“}
method=“post”
download = “journals.csv”
…>
Export
</.link>

Do you have any thoughts on this?

codeanpeace

codeanpeace

Hmm, could you elaborate a bit more? Are you seeing an error? Does no download take place? What does the rendered html of the a anchor tag look like?

The MDN docs list linked above mentions some requirements for the download attribute for anchor elements and different browsers may handle things a bit differently as well.

Valeriy

Valeriy OP

As I can see, there are no errors.
Dev-tools console output:

phx-F46Bx0s-9TzePR4i socket: disconnect for page nav - undefined
phx-F46Bx0s-9TzePR4i destroyed: the child has been removed from the parent - undefined
destroyed: the child has been removed from the parent - undefined

Yes, it works well.

HTML code for:

<.link
href={~p"/export?#{%{message: “journals”, node: @options.node, date: @options.date, sort_by: @options.sort_by, sort_order: @options.sort_order}}“}
method=“post”
download
…>
Export
</.link>

looks like this:

<a href=“/export?message=journals&sort_by=date&sort_order=desc&node=3&date=” data-method=“post” data-csrf=“DHpdChIqN3AaPQUjBSdfCSIaWRknNnF64IeXjx_IlUABDkfXmJtNsP6-” data-to=“/export?message=journals&sort_by=date&sort_order=desc&node=3&date=” class=“-ml-px inline-flex items-center px-3 h-10 border border-slate-300 bg-white text-base font-medium text-slate-600 no-underline hover:bg-slate-300 rounded-md” download=“”>
Export
</a>

I try it in two browsers: edge and chrome, the behavior in both cases is the same.

P.S. Just in case:

mix phx.new --version
Phoenix installer v1.7.2

elixir --version
Erlang/OTP 26 [erts-14.0.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit:ns]

Elixir 1.15.4 (compiled with Erlang/OTP 26)

codeanpeace

codeanpeace

That’s odd, LiveView shouldn’t disconnect when the download attribute as of this PR: Fix for #2552: do not unload LiveView socket on `download` link clicks. by sherbondy · Pull Request #2611 · phoenixframework/phoenix_live_view · GitHub

I’d suggest taking a few steps back and directly specifying the anchor tag with the download attribute temporarily just to see if that changes anything and get it working as expected.

<a href="/export?message=journals&sort_by=date&sort_order=desc&node=3&date=" download>
Export
</a>
Valeriy

Valeriy OP

I try this:

<a
href=“/export?message=journals&sort_by=date&date=&sort_order=desc&node=”
data-method=“post”
data-to=“/export?message=journals&sort_by=date&date=&sort_order=desc&node=”
data-csrf=“xxx”
class=“-ml-px inline-flex items-center px-3 h-10 border border-slate-300 bg-white text-base font-medium text-slate-600 no-underline hover:bg-slate-300 rounded-md”
download
>
Export
</a>

The behavior is the same:

phx-F47RLs3Fj_DdkRFB socket: disconnect for page nav - undefined
phx-F47RLs3Fj_DdkRFB destroyed: the child has been removed from the parent - undefined
destroyed: the child has been removed from the parent - undefined

Perhaps some other settings are required somewhere else?

Valeriy

Valeriy OP

That’s odd, LiveView shouldn’t disconnect when the download attribute as of this PR: Fix for #2552: do not unload LiveView socket on download link clicks. by sherbondy · Pull Request #2611 · phoenixframework/phoenix_live_view · GitHub

I find this code in phoenix_live_view/assets/js/phoenix_live_view/dom.js:

wantsNewTab(e){
let wantsNewTab = e.ctrlKey || e.shiftKey || e.metaKey || (e.button && e.button === 1)
let isDownload = (e.target instanceof HTMLAnchorElement && e.target.hasAttribute(“download”))
let isTargetBlank = e.target.hasAttribute(“target”) && e.target.getAttribute(“target”).toLowerCase() === “_blank”
return wantsNewTab || isTargetBlank || isDownload
},

I additionally tried simple GET (not POST):

<a
href=“/export?message=journals&sort_by=date&date=&sort_order=desc&node=”
download
>
Export
</a>

and got the same result: download file works well, but “socket: disconnect for page nav” and “destroyed: the child has been removed from the parent”.

Valeriy

Valeriy OP

wantsNewTab(e){
let wantsNewTab = e.ctrlKey || e.shiftKey || e.metaKey || (e.button && e.button === 1)
let isDownload = (e.target instanceof HTMLAnchorElement && e.target.hasAttribute(“download”))
let isTargetBlank = e.target.hasAttribute(“target”) && e.target.getAttribute(“target”).toLowerCase() === “_blank”
return wantsNewTab || isTargetBlank || isDownload
},

BTW (for FF and chrome):
e.ctrlKey - don’t work in my case
e.shiftKey - works, but open a blank page
download - don’t work in my case
target=“_blank” - works, but open a blank page for a short time

— All posts loaded —

Where Next? Top

Trending in Questions Top

RSP87
I’m working on a project that simulates the bumbl example in the programming phoenix book. It acts almost like an email client. We have a...
New
nseaSeb
Hello, I know there is an approach for handling lists that allows for optimized traversal, but I can’t recall the specific method (somet...
New
RemyXRenard
I’m seeing that a list inside a Kino.DataTable will be interpreted as a charlist, even if the Kino.configure() is set to charlists: :as_l...
New
brecabral
Documentation While reading the Scoped Routes section, I noticed that the documentation currently refers to a problem without explainin...
New
velrest
So my question is quite simple and i have found no conclusive answer on forum, google or AI. Should we use :erlang.float for Integer to ...
New
samoloth
Hi, I’ve just set up an application with ash_authentication. There is only magic link strategy for now, so there is no confirmation add o...
New
FlyingNoodle
If a change or preparation module uses Ash.Changeset.get_argument/2 or Ash.Query.get_argument/2 (or any of the other get_argument functio...
New

Other Trending Topics Top

mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Dmk
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New
netoum
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
webofbits
With AI doing more of the implementation work, I’ve been wondering how much coding I should deliberately keep doing myself. My main conc...
#ai
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews