<turbo-stream action="append" target="posts_list"><template>    <div class="postbit" id="373028" data-post-id="373028">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="phcurado" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/phcurado/120/39030_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  phcurado
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I have made a library (before phoenix introduced daisyUI) that creates the liveview components using daisyUI styles. You can check it <a href="https://github.com/phcurado/daisy_ui_components" rel="noopener nofollow ugc">here</a>, it includes the <a href="https://github.com/phcurado/daisy_ui_components/blob/main/lib/daisy_ui_components/modal.ex#L1" rel="noopener nofollow ugc">modal component</a>, which is based on the old phoenix generators. I use <code>dialog</code> as the html element, as recommended on daisy docs. Here is also the <a href="https://daisy-ui-components-site.fly.dev/storybook/components/modal" rel="noopener nofollow ugc">storybook</a> if you want to test it out.<br>
You can use the library or just copy the code, there are other components there from old phoenix generators if you are interested.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="373028" data-batch-url="/posts/batch_likers">
                        2
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/daisyui-modal-in-phoenix-1-8-code-example/71951/12">Post #11</a>
	                </div>
	            </div>
              <div id="likers-container-373028" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="373028"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #11"></div>
  </section>
</div>
    <div class="postbit" id="373037" data-post-id="373037">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="sreyansjain" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/sreyansjain/120/16464_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  sreyansjain
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I am trying to implement dialog using beercss.<br>
My implementation is below -</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">  attr :class, :string, default: ""
  attr :width, :string, default: "large"
  attr :style, :string, doc: "style to be applied to the dialog", default: ""
  attr :on_cancel, JS, default: %JS{}, doc: "the JS command to execute on cancel"
  def dialog(assigns) do
    ~H"""
    &lt;div id={"#{@id}_overlay"} class="overlay"&gt;&lt;/div&gt;
    &lt;dialog
      id={@id}
      phx-mounted={@show &amp;&amp; show_dialog(@id)}
      phx-remove={hide_dialog(@id)}
      data-cancel={JS.exec(@on_cancel, "phx-remove")}
      class={[@class, "modal surface", "#{@width}-width"]}
      style={@style}
    &gt;
      &lt;div id={"#{@id}-content"}&gt;
        &lt;.focus_wrap id={"#{@id}_fw"}&gt;
          {render_slot(@inner_block)}
        &lt;/.focus_wrap&gt;
      &lt;/div&gt;
    &lt;/dialog&gt;
    """
  end

  def show_dialog(js \\ %JS{}, id) when is_binary(id) do
    js
    |&gt; JS.add_class("active", to: "##{id}_overlay")
    |&gt; JS.add_class("active", to: "##{id}")
    |&gt; JS.focus_first(to: "##{id}")
  end

  def hide_dialog(js \\ %JS{}, id) do
    js
    |&gt; JS.remove_class("active", to: "##{id}_overlay")
    |&gt; JS.remove_class("active", to: "##{id}")
    |&gt; JS.pop_focus()
  end
</code></pre>
<p>The dialog is called like so -</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">&lt;.dialog
  :if={@live_action in [:new, :edit]}
  title={@title}
  id="doctor-modal"
  show
  on_cancel={JS.patch(~p"/admin/doctors")}
&gt;
  &lt;.live_component
    module={SecondOpinionWeb.Admin.DoctorLive.FormComponent}
    id={@doctor.id || :new}
    title={@page_title}
    action={@live_action}
    doctor={@doctor}
    patch={~p"/admin/doctors"}
  /&gt;
&lt;/.dialog&gt;
</code></pre>
<p>When I navigate to :new or :edit routes, the dialog appears. I have a cancel button in the live_component like so -</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">&lt;.button class=“border” phx-click={JS.exec(“data-cancel”, to: “#doctor-modal”)}&gt;Cancel&lt;/.button&gt;
</code></pre>
<p>Clicking on the cancel button works fine and I see the dialog disappear with animation.<br>
<strong>But when I click the save button on the form, it does a push_patch to the :index route, the dialog disappears abruptly.</strong><br>
It seems that phx-remove doesn’t finish before the dialog is being removed from the DOM.<br>
But whats strange is the cancel button works just fine.</p>
<p>Can someone please help? Thanks.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="373037" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/daisyui-modal-in-phoenix-1-8-code-example/71951/13">Post #12</a>
	                </div>
	            </div>
              <div id="likers-container-373037" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="373037"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #12"></div>
  </section>
</div>
    <div class="postbit" id="373051" data-post-id="373051">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="sreyansjain" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/sreyansjain/120/16464_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  sreyansjain
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I got it to work by changing the hide_dialog to below -</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">def hide_dialog(js \\ %JS{}, id) do
    js
    |&gt; JS.remove_class("active", to: "##{id}_overlay")
    |&gt; JS.remove_class("surface", to: "##{id}", transition: {"a", "active", ""}, time: 0)
    |&gt; JS.pop_focus()
  end
</code></pre> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="373051" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/daisyui-modal-in-phoenix-1-8-code-example/71951/14">Post #13</a>
	                </div>
	            </div>
              <div id="likers-container-373051" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="373051"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #13"></div>
  </section>
</div>
    <div class="postbit" id="375357" data-post-id="375357">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="ryoung786" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/ryoung786/120/32635_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  ryoung786
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I ended up using a colocated hook - I like how it keeps everything consolidated into one spot in the codebase.</p>
<p>You can show the modal with something like <code>&lt;button onclick="my_modal.showModal()"&gt;open modal&lt;/button&gt;</code> and <code>&lt;.modal id=”my_modal”&gt;This is the body of the modal&lt;/.modal&gt;</code></p>
<pre data-code-wrap="elixir"><code class="lang-elixir">  def modal(assigns) do
    ~H"""
    &lt;script :type={Phoenix.LiveView.ColocatedHook} name=".Modal"&gt;
      export default {
        mounted() {
          window.addEventListener("myapp:close-modal", (e) =&gt; {
            this.el.close()
          });
        }
      }
    &lt;/script&gt;
    &lt;dialog id={@id} class="modal" phx-hook=".Modal"&gt;
      &lt;div class="modal-box overflow-visible"&gt;
        &lt;button
          class="btn btn-sm btn-circle btn-ghost absolute right-2 top-2"
          phx-click={JS.dispatch("myapp:close-modal")}
        &gt;
          ✕
        &lt;/button&gt;
        {render_slot(@inner_block)}
      &lt;/div&gt;
      &lt;div class="modal-backdrop"&gt;
        &lt;button phx-click={JS.dispatch("myapp:close-modal")}&gt;
          close
        &lt;/button&gt;
      &lt;/div&gt;
    &lt;/dialog&gt;
    """
  end
</code></pre> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="375357" data-batch-url="/posts/batch_likers">
                        3
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/daisyui-modal-in-phoenix-1-8-code-example/71951/15">Post #14</a>
	                </div>
	            </div>
              <div id="likers-container-375357" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="375357"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #14"></div>
  </section>
</div>
    <div class="postbit" id="384973" data-post-id="384973">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="matt-savvy" src="/assets/icons/user-9f439610.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  matt-savvy
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I’m usually using a nested form, so my solution is:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir"># regular button            
&lt;button type="button" class="..." onclick="some_modal.showModal()"&gt;Select $ITEM&lt;/button&gt;

# modal is a dialog using JS.ignore_attributes so the page update doesn't break
      &lt;dialog
        phx-mounted={JS.ignore_attributes("open")}
        id="some_modal"
        class="modal"
      &gt;
        &lt;div class="modal-box"&gt;
          &lt;h3 class="text-lg font-bold"&gt;Select $ITEM&lt;/h3&gt;

          &lt;.live_component
            module={MyAppWeb.Items.SelectionForm}
            id="add-item-form-component"
            ...
          /&gt;
        &lt;/div&gt;
      &lt;/dialog&gt;

# nested form submits its info to the parent live view via send
# use push_event to send an event to the client
  @impl true
  def handle_info({:add_item, selected_item}, socket) do
    ...

    {:noreply,
      socket 
      |&gt; ... # any other updates
      |&gt; push_event("close-modal", %{id: "some_modal_id"})} # send close-modal event to client 
  end
</code></pre>
<p>and finally, in app.js, add an event listener which closes the modal.</p>
<pre data-code-wrap="javascript"><code class="lang-javascript">window.addEventListener("phx:close-modal", (e) =&gt; {
    const modalId = e.detail.id;
    const modal = document.getElementById(modalId);
    modal.close();
})

</code></pre> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="384973" data-batch-url="/posts/batch_likers">
                        2
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/daisyui-modal-in-phoenix-1-8-code-example/71951/16">Post #15</a>
	                </div>
	            </div>
              <div id="likers-container-384973" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="384973"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #15"></div>
  </section>
</div>
    <div class="postbit" id="387563" data-post-id="387563">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="kish10" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/kish10/120/32272_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  kish10
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Here is a simple &amp; easy solution that worked for me with Liveview &amp; daisyUI modal on a <code>dialog</code> tag.</p>
<p>The idea is to use <code>JS.set_attribute({“open”, “”}, to: “#modal-id”)</code> &amp; <code>JS.remove_attribute(“open”, to: “#modal-id”)</code>, to open &amp; close the modal.</p>
<p>Example:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir"># -- Modal

&lt;dialog id="example-modal" class="modal"&gt;
    &lt;div class="modal-box"&gt;
      &lt;p&gt;Hello!&lt;/p&gt;
      &lt;button phx-click={JS.remove_attribute("open", to: "#example-modal")}&gt;Close&lt;/button&gt;
    &lt;/div&gt;
    &lt;div class="modal-backdrop" phx-click={JS.remove_attribute("open", to: "#example-modal")}&gt;&lt;/div&gt;
&lt;/dialog&gt;

# -- Open button

&lt;button phx-click={JS.set_attribute({“open”, “”}, to: “#example-modal”)}&gt;Open&lt;/button&gt;
</code></pre> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="387563" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/daisyui-modal-in-phoenix-1-8-code-example/71951/17">Post #16</a>
	                </div>
	            </div>
              <div id="likers-container-387563" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="387563"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-last-post cat-last-post" title="Last post!"></div>
  </section>
</div>
</template></turbo-stream><turbo-stream action="replace" target="load-more-container"><template><div id="load-more-container" class="load-more-container">
    <span class="all-loaded">— All posts loaded —</span>
</div></template></turbo-stream>