How to Create Nested LiveView Components: Difference between revisions

From ElixirBlocks
Jump to: navigation, search
No edit summary
No edit summary
 
Line 37: Line 37:
<source>
<source>


# 1. Create component with phx-click attributes for event handlers and a render slot fo text:  <%= render_slot(@inner_block) %>
defmodule Example do
  use Phoenix.Component
  def simple_button(assigns) do
    ~H"""
    <button
      style="background-color: #000000; color: #ffffff; padding: 8px 16px; border-radius: 4px; font-weight: bold;"
      phx-click={@on_click}
    >
      <%= render_slot(@inner_block) %>
    </button>
    """
  end
end
#___________PARENT


defmodule AppWeb.PageLive do
defmodule AppWeb.PageLive do
   use AppWeb, :live_view
   use AppWeb, :live_view
  import Example
 
   def mount(_params, _session, socket) do
   def mount(_params, _session, socket) do
    # Initialize state with a counter
     socket = assign(socket, count: 0)
     socket = assign(socket, count: 0)
     {:ok, socket}
     {:ok, socket}
   end
   end
      # Event handler in the parent LiveView
  def handle_event("increment", _params, socket) do
      {:noreply, assign(socket, count: socket.assigns.count + 1)}
  end
 


   def render(assigns) do
   def render(assigns) do
Line 76: Line 61:
       </div>
       </div>


 
       <.simple_button on_click="increment">
<!-- # 2 add component to parent. Event handlers will come from parent-->
         Increment Counter
       <Example.simple_button on_click="increment">
       </.simple_button>
         <span>Click to increment</span>
       </Example.simple_button>
     </div>
     </div>
     """
     """
   end
   end


   # Event handler in the parent LiveView
 
   def handle_event("increment", _params, socket) do
 
     {:noreply, assign(socket, count: socket.assigns.count + 1)}
 
 
#_________________________________________________________BUTTON
 
   # Simplified button component
   def simple_button(assigns) do
     ~H"""
      <button class="btn btn-lg"    phx-click={@on_click} >   
      <%= render_slot(@inner_block) %>
      </button>
    """
   end
   end
#___________________________________________________________END BUTTON
end
end


</source>
</source>

Latest revision as of 00:33, 8 April 2025

This example demonstrates a nested LiveView component.


defmodule AppxWeb.SandboxLive do
   use AppxWeb, :live_view  
   import MyComponent
   def mount(_params, _session, socket)  do
	 {:ok, socket}  
   end
   def render(assigns) do
	   ~H"""
	      Hello World! YAY
	     <MyComponent.greet name="Jane" />
	   """ 
   end
end

defmodule MyComponent do
   use Phoenix.Component

   def greet(assigns) do
	   ~H"""
	     <p>Hello, <%= @name %>!</p>
	   """ 
   end
end


An Example of a Button



defmodule AppWeb.PageLive do
  use AppWeb, :live_view

  def mount(_params, _session, socket) do
    socket = assign(socket, count: 0)
    {:ok, socket}
  end

      # Event handler in the parent LiveView
  def handle_event("increment", _params, socket) do
       {:noreply, assign(socket, count: socket.assigns.count + 1)}
  end
  

  def render(assigns) do
    ~H"""
    <div class="container mx-auto p-4">
      <h1 class="text-xl font-bold mb-4">Counter with Button Component</h1>

      <div class="mb-4">
        <p>Current count: <span class="font-bold"><%= @count %></span></p>
      </div>

      <.simple_button on_click="increment">
        Increment Counter
      </.simple_button>
    </div>
    """
  end





#_________________________________________________________BUTTON

  # Simplified button component 
  def simple_button(assigns) do
    ~H"""
      <button class="btn btn-lg"    phx-click={@on_click} >    
      <%= render_slot(@inner_block) %>
      </button>
    """
  end

#___________________________________________________________END BUTTON



end