michaelfich

michaelfich

I’ve been stuck on a particularly strange issue using Phoenix LiveView and Bootstrap.

I have a button on the page which opens a bootstrap modal when clicked. Inside the modal is a form.

When I add a phx_submit and phx_change liveview hook to the form_for tag, i encounter a bug, as the modal is closed as soon as the user begins interacting with the form (due to the phx_change) or hits the submit button (due to phx_submit).

I tried to add a regular HTML form with text inputs and a submit button, and attached a javascript submit handler that just called “preventDefault” on the form itself. The modal did not become hidden when submitting the form, as it does with form_for and the associated liveview hooks.

This is a liveview that is live_rendered on a page which is a classic phoenix view. The modal’s backdrop remains open, as it is rendered from the bootstrap JS outside of the liveview. However the modal itself is rendered from within the liveview and closes. The modal backdrop maintains the classes “modal-backdrop fade show”, but the modal itself loses the “show” class and only has “modal fade” once this behaviour occurs.

I’ve tried trimming both event handlers to simply return {:noreply, socket} however the problem persists. I’ve carefully inspected the DOM to try to see what is being changed, but haven’t found anything that would help. If anyone has any suggestions that might help, I would be very grateful.

Showing Posts 1 to 9

idi527

idi527

:waving_hand:

Sorry for being off-topic, but I’ve encountered similar problems with bootstrap+liveview (some with the modal as well) and decided to use a no-js css framework, turned out to be much simpler in the end.

Here’s an example of a modal component: chirp/lib/chirp_web/live/modal_component.ex at master · dersnek/chirp · GitHub

A modal component can also be generated with mix phx.gen.live.

dom

dom

I had problems with this too and found a tutorial:

I haven’t tried it yet, so YMMV!

benwilson512

benwilson512

Author of Craft GraphQL APIs in Elixir with Absinthe

Yes, we switched to using Bulma for this very reasons.

michaelfich

michaelfich OP

I had problems with this too and found a tutorial:

I saw that video but frankly didn’t find it all that helpful. The modal in the video is actually a LiveView modal that comes with out of the box with phx.gen.live, but seems to just have a few bootstrap classes thrown on it to have the appearance of a Bootstrap modal.

There’s nothing wrong with that at all, but it isn’t a Bootstrap modal in the sense that it uses the JS from bootstrap to toggle a modal, include a backdrop and other dynamic features.

thiagomajesk

thiagomajesk

Hi @michaelfich!

There’s a recent article by Dashbit that covers this scenario:

If you are using Bootstrap 4 with Jquery you could do something like this:

modal_component.ex

def render(assigns) do
    ~L"""
    <div class="modal fade show" tabindex="-1" role="dialog" 
        phx-target="<%= @myself %>"
        phx-capture-click="close"
        phx-page-loading>
    <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title">Modal title</h5>
        <%= live_patch to: @return_to, class: "close", "data-dismiss": "modal" do %>
          <span aria-hidden="true">&times;</span>
        <% end %>
      </div>
      <div class="modal-body">
      <%= live_component @socket, @component, @opts %>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" data-dismiss="modal" phx-capture-click="close"  phx-target="<%= @myself %>">Close</button>
        <button type="button" class="btn btn-primary">Save changes</button>
      </div>
    </div>
    </div>
    </div>
    """
  end

app.js

import $ from "jquery"

window.addEventListener("phx:page-loading-stop", info => {
  $('.modal.fade.show').modal('show')
  NProgress.done()
})
<%= if @live_action in [:new, :edit] do %>
<%= live_modal @socket, MyAppWeb.ResourceLive.FormComponent,
    return_to: Routes.resource_path(@socket, :index, @resource) %>
<% end %>

I’ve been experimenting with LV only for the past week, so I don’t know if there’s a better way of doing this. What other alternatives have you found since the last time you posted?

thiagomajesk

thiagomajesk

Update: If you are experiencing problems submitting forms inside the modal where the backdrop still is visible, you might try adding this code after the page stops loading:

$('.modal.fade.show form').on('submit', () =>  $('.modal.fade.show').modal('hide'))

PS.: In my tests, form submits and data-dismiss="modal" were blocking each other.
I could either dismiss the modal or submit the form, not both.

winescout

winescout

Its a bummer to have to pull in JQuery just to get Bootstrap components working, and having to sprinkle JS all around to get things working feels like an anti-pattern to me. I think one of the articles above suggests using BootstrapNative, and I want to highlight that here. BSN has the benefit of having its own init callback that you can fire after “phx:page-loading-stop”. Going about it this way solved most (not all though) of these kinds of issues for me:

window.addEventListener("phx:page-loading-stop", info => {
  BSN.initCallback(document.body)
  NProgress.done()
})
haubie

haubie

I’ve had this same issue for when the component itself manages it’s state of visibility and the form handling (validation, etc) is managed by the parent live view.

Did you resolve the issue?

andreyuhai

andreyuhai

Just looking for the same thing for Bootstrap 5.

If I have to switch frameworks then I’d probably switch to Bulma as suggested above but I just don’t want to deal with all the possible issues I’ll have with Webpack and etc. while trying to switch to Bulma. Moreover I’ve never used Bulma so unless there’s a way with Bootstrap 5 then I’ll consider switching. :sweat_smile:

— All posts loaded —

Where Next? Top

Trending in Questions Top

Blokh
Hey guys, I’ve got a huge CSV ( around 10 GB ) that needs to be processed hourly Do you guys have any suggestions what is the best prac...
New
kszambelanczyk
Hello! Could someone please give me a help/sample code, how to delete a file from s3 using waffle/waffle_ecto from Phoenix app. I creat...
New
Onor.io
I have what I’ve heard referred to as a “lookup table” in my database. This is a way of assigning codes to common values. One common lo...
New
Trolleger
What approach to take when sending live updates to “random” users Hi! I have a question, I have a little chat app, and when I create a DM...
New
matt-savvy
Anyone here using Honeybadger? My Honeybadger account is being overwhelmed with noise from some bots. Seeing a lot of Bandit.HTTPError...
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
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

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
garrison
Hobbes is a low-level distributed database for the Elixir programming language. Hobbes provides a simple, safe, and scalable storage lay...
New
mcass19
ExRatatui lets you cook up rich terminal UIs in Elixir, powered by Rust’s ratatui via Rustler NIFs. Build interactive terminal applicatio...
New
Damirados
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge &amp; Solve. They are GUI (Emerge) and State management (S...
New
netoum
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
wintermeyer
There are three potential reasons for members of this forum to have a look at https://vutuv.de You are tired or annoyed of LinkedIn. Yo...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews