Is there a way to publish changes from the client to the liveview socket?

Does anyone know if there is a way to publish changes from the client to the live view socket? I realized that will allow me to avoid using phx-click as a way to publish an event to the server.

1 Like

What do you mean publish, what is initiating that publish? There are lots and lots of events in the DOM that you can use. :slight_smile:

Not yet, but soon

1 Like

I’m using live view for infinite loading and you can see it working @ https://www.whatcard.sg/

How I’m triggering the “load-more” event is by using “phx-click” and the script looks something like

  <%= if length(@merchants) < @merchants_length do %>
    <div class="column">
      <div class="merchant-index-load-more" phx-click="load-more">
        <progress class="progress is-danger is-hidden" max="100">30%</progress>
      </div>
    </div>

    <script>
      new IntersectionObserver((entries, observer) => {
        const entry = entries[0];

        if (entry.isIntersecting) {
          entry.target.children[0].classList.remove("is-hidden");
          entry.target.click();
        }
      }).observe(document.querySelector(".merchant-index-load-more"), {
        root: document.querySelector(".merchant-index")
      });
    </script>
  <% end %>

I was wondering if there is a way to broadcast the “load-more” event instead of having to trigger it via a “fake” click.

@chrismccord Is it a WIP or PR welcome? :slight_smile: I read through phoenix_live_view.js briefly and it seems like we just need to expose an API for view.pushEvent.

3 Likes

Why not just use the DOM’s scroll event (onscroll="blah()" attribute), that’s what I did in Drab with a debounce setting (don’t forget that part!).

The scroll event will solve the problem of triggering an event but how does it fit into the picture of publishing an event into the socket used by live view?

1 Like

Because you can just register liveview to listen on it. :slight_smile:

I haven’t switched to liveview from drab as of yet due to lacking some pretty major features I use that would be impossible to do in liveview at this time without writing a lot of javascript, but in drab it’s as simple as just changing the event you are registering to, so instead of <button drab="click:dowhatever(42)"> can just change the click to scroll or whatever DOM event you want (even custom ones, etc…), so <button drab="scroll:dowhatever(42)"> although if it is your body scrolling it should go on the body element like <body drab="scroll:dowhatever(42)">, and adding a debounce would just be <body drab="scroll:dowhatever(42)" drab-options="debounce(500)">, so however that all gets translated in liveview, just change the name of the event you are registering to from click to scroll (so instead of phx-click maybe just phx-scroll?) and move it to whatever the scrolling container is (probably body, maybe some div, however you built it), thus no javascript then needed. :slight_smile:

At that point on the elixir side you just compare the scroll position to the total scrollable height and if close enough (I.E. near the bottom or top or whatever you want) then push the more data. :slight_smile:

I do this on both displaying some sizeable logs and a simple infinitely scrollable (up and down) mini-messenger on each page at work.

2 Likes

is this what is now implemented as pushEvent in LiveView ?

https://hexdocs.pm/phoenix_live_view/Phoenix.LiveView.html#module-js-interop-and-client-controlled-dom