<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>http://elixirblocks.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Admin</id>
	<title>ElixirBlocks - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="http://elixirblocks.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Admin"/>
	<link rel="alternate" type="text/html" href="http://elixirblocks.com/Special:Contributions/Admin"/>
	<updated>2026-06-02T05:11:44Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.39.1</generator>
	<entry>
		<id>http://elixirblocks.com/index.php?title=Live_view_and_handle_info&amp;diff=1916</id>
		<title>Live view and handle info</title>
		<link rel="alternate" type="text/html" href="http://elixirblocks.com/index.php?title=Live_view_and_handle_info&amp;diff=1916"/>
		<updated>2026-01-29T00:14:46Z</updated>

		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Phoenix LiveView handle_info Guide for Web Developers =&lt;br /&gt;
&lt;br /&gt;
== What is handle_info? ==&lt;br /&gt;
&lt;br /&gt;
handle_info is Phoenix LiveView's way of handling messages sent to the LiveView process from outside normal user interactions (like clicks). It's your LiveView's inbox for asynchronous events.&lt;br /&gt;
&lt;br /&gt;
In traditional web development, everything is request-response: user clicks, server responds, done. But LiveView processes are long-running and can receive messages from other parts of your system while they're alive.&lt;br /&gt;
&lt;br /&gt;
== Basic Syntax ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;elixir&amp;quot;&amp;gt;&lt;br /&gt;
def handle_info(message, socket) do&lt;br /&gt;
  # Process the message&lt;br /&gt;
  # Update socket state if needed&lt;br /&gt;
  {:noreply, socket}&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Example 1: Timer (sending to self) ==&lt;br /&gt;
&lt;br /&gt;
The simplest way to trigger handle_info - send a message to yourself:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;elixir&amp;quot;&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    Process.send_after(self(), :refresh, 5000)&lt;br /&gt;
    {:ok, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_info(:refresh, socket) do&lt;br /&gt;
    IO.inspect(&amp;quot;Message received after 5 seconds!&amp;quot;)&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    Page&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Example 2: Sending Between LiveViews with PubSub ==&lt;br /&gt;
&lt;br /&gt;
'''This is the recommended way''' to send messages between LiveViews.&lt;br /&gt;
&lt;br /&gt;
=== In PageLive (the receiver): ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;elixir&amp;quot;&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    if connected?(socket) do&lt;br /&gt;
      Phoenix.PubSub.subscribe(App.PubSub, &amp;quot;events&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
    {:ok, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_info(:my_message, socket) do&lt;br /&gt;
    IO.inspect(&amp;quot;handle_info received!&amp;quot;)&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    Page&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== In HomeLive (the sender): ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;elixir&amp;quot;&amp;gt;&lt;br /&gt;
defmodule AppWeb.HomeLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    {:ok, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;trigger_page&amp;quot;, _params, socket) do&lt;br /&gt;
    Phoenix.PubSub.broadcast(App.PubSub, &amp;quot;events&amp;quot;, :my_message)&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    &amp;lt;button phx-click=&amp;quot;trigger_page&amp;quot;&amp;gt;Trigger Page handle_info&amp;lt;/button&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Why do you need both subscribe AND broadcast? ===&lt;br /&gt;
&lt;br /&gt;
* '''Subscribe''' = &amp;quot;I want to listen to messages on the 'events' topic&amp;quot;&lt;br /&gt;
* '''Broadcast''' = &amp;quot;Send this message to everyone listening to 'events'&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Without subscribe, the LiveView won't receive broadcasts. Think of it like tuning a radio to a channel - you must tune in (subscribe) before you can hear what's being transmitted (broadcast).&lt;br /&gt;
&lt;br /&gt;
=== PubSub works with multiple LiveViews ===&lt;br /&gt;
&lt;br /&gt;
If you have 3 PageLive tabs open, all 3 will receive the broadcast. That's a feature, not a bug.&lt;br /&gt;
&lt;br /&gt;
== Example 3: Process Registration (not recommended) ==&lt;br /&gt;
&lt;br /&gt;
You can register a LiveView process with a name and send directly to it:&lt;br /&gt;
&lt;br /&gt;
=== In PageLive: ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;elixir&amp;quot;&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    if connected?(socket) do&lt;br /&gt;
      Process.register(self(), :page_live_process)&lt;br /&gt;
    end&lt;br /&gt;
    {:ok, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_info(:my_message, socket) do&lt;br /&gt;
    IO.inspect(&amp;quot;handle_info received!&amp;quot;)&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    Page&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== In HomeLive: ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;elixir&amp;quot;&amp;gt;&lt;br /&gt;
defmodule AppWeb.HomeLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    {:ok, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;send_to_page&amp;quot;, _params, socket) do&lt;br /&gt;
    send(:page_live_process, :my_message)&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    &amp;lt;button phx-click=&amp;quot;send_to_page&amp;quot;&amp;gt;Send to Page&amp;lt;/button&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Problems with this approach: ===&lt;br /&gt;
&lt;br /&gt;
* Only works with ONE PageLive instance at a time&lt;br /&gt;
* Crashes if name is already taken&lt;br /&gt;
* Requires error handling bloat&lt;br /&gt;
* PageLive must be mounted first&lt;br /&gt;
&lt;br /&gt;
'''Use PubSub instead''' - it's simpler and more robust.&lt;br /&gt;
&lt;br /&gt;
== Common Sources of Messages ==&lt;br /&gt;
&lt;br /&gt;
handle_info receives messages from:&lt;br /&gt;
&lt;br /&gt;
# '''Timers''': &amp;lt;code&amp;gt;Process.send_after(self(), :tick, 1000)&amp;lt;/code&amp;gt;&lt;br /&gt;
# '''PubSub broadcasts''': &amp;lt;code&amp;gt;Phoenix.PubSub.broadcast(App.PubSub, &amp;quot;topic&amp;quot;, :msg)&amp;lt;/code&amp;gt;&lt;br /&gt;
# '''Other processes''': &amp;lt;code&amp;gt;send(liveview_pid, :msg)&amp;lt;/code&amp;gt;&lt;br /&gt;
# '''Tasks''': Background jobs completing&lt;br /&gt;
# '''GenServers''': Other parts of your application&lt;br /&gt;
&lt;br /&gt;
== Safety: Catch-all handle_info ==&lt;br /&gt;
&lt;br /&gt;
Always add a catch-all to prevent crashes from unexpected messages:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;elixir&amp;quot;&amp;gt;&lt;br /&gt;
def handle_info(msg, socket) do&lt;br /&gt;
  IO.warn(&amp;quot;Unhandled message: #{inspect(msg)}&amp;quot;)&lt;br /&gt;
  {:noreply, socket}&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Key Takeaways ==&lt;br /&gt;
&lt;br /&gt;
* handle_info handles asynchronous messages sent to your LiveView&lt;br /&gt;
* Use &amp;lt;code&amp;gt;send(self(), :msg)&amp;lt;/code&amp;gt; to send messages to yourself&lt;br /&gt;
* Use '''PubSub''' (not process registration) to send between LiveViews&lt;br /&gt;
* You must '''subscribe''' to a topic before you can receive broadcasts on that topic&lt;br /&gt;
* Always include a catch-all handle_info to handle unexpected messages&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_____________________________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Building a Real-Time Phoenix LiveView App with GenServer and PubSub =&lt;br /&gt;
&lt;br /&gt;
This tutorial demonstrates how to create a Phoenix LiveView application that uses:&lt;br /&gt;
&lt;br /&gt;
* A GenServer to send periodic timer updates&lt;br /&gt;
* Phoenix PubSub for broadcasting messages&lt;br /&gt;
* LiveView's &amp;lt;code&amp;gt;handle_info/2&amp;lt;/code&amp;gt; to receive and handle messages&lt;br /&gt;
* Multiple LiveViews communicating with each other&lt;br /&gt;
&lt;br /&gt;
== What We're Building ==&lt;br /&gt;
&lt;br /&gt;
* '''TimerServer''': A GenServer that broadcasts a message every 3 seconds&lt;br /&gt;
* '''PageLive''': A LiveView that subscribes to timer updates and displays them&lt;br /&gt;
* '''HomeLive''': A LiveView with a button that can manually trigger messages to PageLive&lt;br /&gt;
&lt;br /&gt;
== Step 1: Create the GenServer ==&lt;br /&gt;
&lt;br /&gt;
Create &amp;lt;code&amp;gt;lib/app/timer_server.ex&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;elixir&amp;quot;&amp;gt;&lt;br /&gt;
defmodule App.TimerServer do&lt;br /&gt;
  use GenServer&lt;br /&gt;
  require Logger&lt;br /&gt;
&lt;br /&gt;
  @interval 3_000  # 3 seconds&lt;br /&gt;
&lt;br /&gt;
  # Client API&lt;br /&gt;
&lt;br /&gt;
  def start_link(_opts) do&lt;br /&gt;
    GenServer.start_link(__MODULE__, %{}, name: __MODULE__)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Server Callbacks&lt;br /&gt;
&lt;br /&gt;
  @impl true&lt;br /&gt;
  def init(state) do&lt;br /&gt;
    # Start the timer immediately&lt;br /&gt;
    schedule_tick()&lt;br /&gt;
    {:ok, state}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  @impl true&lt;br /&gt;
  def handle_info(:tick, state) do&lt;br /&gt;
    # Log to console&lt;br /&gt;
    message = &amp;quot;Timer tick at #{Time.utc_now()}&amp;quot;&lt;br /&gt;
    IO.puts(message)&lt;br /&gt;
    Logger.info(message)&lt;br /&gt;
&lt;br /&gt;
    # Broadcast to all subscribed LiveViews via PubSub&lt;br /&gt;
    Phoenix.PubSub.broadcast(App.PubSub, &amp;quot;events&amp;quot;, {:timer_update, message})&lt;br /&gt;
&lt;br /&gt;
    # Schedule the next tick&lt;br /&gt;
    schedule_tick()&lt;br /&gt;
&lt;br /&gt;
    {:noreply, state}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Private Functions&lt;br /&gt;
&lt;br /&gt;
  defp schedule_tick do&lt;br /&gt;
    Process.send_after(self(), :tick, @interval)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Key Concepts: ===&lt;br /&gt;
&lt;br /&gt;
'''GenServer Basics''':&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;use GenServer&amp;lt;/code&amp;gt; - Brings in GenServer behaviour&lt;br /&gt;
* &amp;lt;code&amp;gt;start_link/1&amp;lt;/code&amp;gt; - Called when the GenServer starts&lt;br /&gt;
* &amp;lt;code&amp;gt;init/1&amp;lt;/code&amp;gt; - Initializes state and starts the timer&lt;br /&gt;
&lt;br /&gt;
'''Timer Pattern''':&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;Process.send_after(self(), :tick, @interval)&amp;lt;/code&amp;gt; - Schedules a message to ourselves&lt;br /&gt;
* &amp;lt;code&amp;gt;handle_info(:tick, state)&amp;lt;/code&amp;gt; - Receives the :tick message and processes it&lt;br /&gt;
* We call &amp;lt;code&amp;gt;schedule_tick()&amp;lt;/code&amp;gt; again to create a recurring timer&lt;br /&gt;
&lt;br /&gt;
'''Broadcasting''':&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;Phoenix.PubSub.broadcast(App.PubSub, &amp;quot;events&amp;quot;, {:timer_update, message})&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;App.PubSub&amp;lt;/code&amp;gt; - The PubSub name (configured in application.ex)&lt;br /&gt;
** &amp;lt;code&amp;gt;&amp;quot;events&amp;quot;&amp;lt;/code&amp;gt; - The topic name (subscribers must use the same topic)&lt;br /&gt;
** &amp;lt;code&amp;gt;{:timer_update, message}&amp;lt;/code&amp;gt; - The message payload (a tuple with an atom tag)&lt;br /&gt;
&lt;br /&gt;
== Step 2: Register the GenServer in the Supervision Tree ==&lt;br /&gt;
&lt;br /&gt;
Edit &amp;lt;code&amp;gt;lib/app/application.ex&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;elixir&amp;quot;&amp;gt;&lt;br /&gt;
defmodule App.Application do&lt;br /&gt;
  @moduledoc false&lt;br /&gt;
&lt;br /&gt;
  use Application&lt;br /&gt;
&lt;br /&gt;
  @impl true&lt;br /&gt;
  def start(_type, _args) do&lt;br /&gt;
    children = [&lt;br /&gt;
      AppWeb.Telemetry,&lt;br /&gt;
      App.Repo,&lt;br /&gt;
      {DNSCluster, query: Application.get_env(:app, :dns_cluster_query) || :ignore},&lt;br /&gt;
      {Phoenix.PubSub, name: App.PubSub},&lt;br /&gt;
      # Start the timer server&lt;br /&gt;
      App.TimerServer,  # &amp;lt;- Add this line&lt;br /&gt;
      # Start to serve requests, typically the last entry&lt;br /&gt;
      AppWeb.Endpoint&lt;br /&gt;
    ]&lt;br /&gt;
&lt;br /&gt;
    opts = [strategy: :one_for_one, name: App.Supervisor]&lt;br /&gt;
    Supervisor.start_link(children, opts)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  @impl true&lt;br /&gt;
  def config_change(changed, _new, removed) do&lt;br /&gt;
    AppWeb.Endpoint.config_change(changed, removed)&lt;br /&gt;
    :ok&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Key Concepts: ===&lt;br /&gt;
&lt;br /&gt;
'''Supervision Tree''':&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;children&amp;lt;/code&amp;gt; list defines all processes that should start with the app&lt;br /&gt;
* The supervisor automatically starts, monitors, and restarts these processes if they crash&lt;br /&gt;
* &amp;lt;code&amp;gt;App.TimerServer&amp;lt;/code&amp;gt; uses the default child_spec (provided by &amp;lt;code&amp;gt;use GenServer&amp;lt;/code&amp;gt;)&lt;br /&gt;
* The supervisor will call &amp;lt;code&amp;gt;App.TimerServer.start_link/1&amp;lt;/code&amp;gt; at startup&lt;br /&gt;
&lt;br /&gt;
'''Supervisor Strategy''':&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;:one_for_one&amp;lt;/code&amp;gt; - If a child crashes, only that child is restarted (not siblings)&lt;br /&gt;
&lt;br /&gt;
== Step 3: Create PageLive (Subscribes to Timer Updates) ==&lt;br /&gt;
&lt;br /&gt;
Create &amp;lt;code&amp;gt;lib/app_web/live/page_live.ex&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;elixir&amp;quot;&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    if connected?(socket) do&lt;br /&gt;
      Phoenix.PubSub.subscribe(App.PubSub, &amp;quot;events&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
    {:ok, assign(socket, :last_message, &amp;quot;Waiting for timer...&amp;quot;)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_info(:my_message, socket) do&lt;br /&gt;
    IO.inspect(&amp;quot;handle_info received&amp;quot;)&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_info({:timer_update, message}, socket) do&lt;br /&gt;
    IO.puts(&amp;quot;PageLive received: #{message}&amp;quot;)&lt;br /&gt;
    {:noreply, assign(socket, :last_message, message)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    &amp;lt;div class=&amp;quot;p-8&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;h1 class=&amp;quot;text-2xl font-bold mb-4&amp;quot;&amp;gt;Timer Demo&amp;lt;/h1&amp;gt;&lt;br /&gt;
      &amp;lt;p class=&amp;quot;text-gray-700&amp;quot;&amp;gt;Last message: &amp;lt;%= @last_message %&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Key Concepts: ===&lt;br /&gt;
&lt;br /&gt;
'''mount/3 Lifecycle''':&lt;br /&gt;
&lt;br /&gt;
* Called when the LiveView initializes&lt;br /&gt;
* &amp;lt;code&amp;gt;connected?(socket)&amp;lt;/code&amp;gt; - Returns true only after the WebSocket connection is established&lt;br /&gt;
* We only subscribe after connection to avoid subscribing during the initial static HTML render&lt;br /&gt;
&lt;br /&gt;
'''PubSub Subscribe''':&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;Phoenix.PubSub.subscribe(App.PubSub, &amp;quot;events&amp;quot;)&amp;lt;/code&amp;gt; - Subscribes this LiveView process to the &amp;quot;events&amp;quot; topic&lt;br /&gt;
* Any messages broadcast to &amp;quot;events&amp;quot; will be sent to this process&lt;br /&gt;
&lt;br /&gt;
'''handle_info/2''':&lt;br /&gt;
&lt;br /&gt;
* Receives messages sent directly to the LiveView process&lt;br /&gt;
* Pattern matches on the message structure&lt;br /&gt;
* &amp;lt;code&amp;gt;{:timer_update, message}&amp;lt;/code&amp;gt; - Matches messages from TimerServer&lt;br /&gt;
* &amp;lt;code&amp;gt;:my_message&amp;lt;/code&amp;gt; - Matches messages from HomeLive (see next step)&lt;br /&gt;
&lt;br /&gt;
'''Socket Assigns''':&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;assign(socket, :last_message, message)&amp;lt;/code&amp;gt; - Updates the socket state&lt;br /&gt;
* When assigns change, LiveView automatically re-renders the component&lt;br /&gt;
* Access in template with &amp;lt;code&amp;gt;@last_message&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Step 4: Create HomeLive (Triggers Manual Messages) ==&lt;br /&gt;
&lt;br /&gt;
Create &amp;lt;code&amp;gt;lib/app_web/live/home_live.ex&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;elixir&amp;quot;&amp;gt;&lt;br /&gt;
defmodule AppWeb.HomeLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    {:ok, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;trigger_page&amp;quot;, _params, socket) do&lt;br /&gt;
    Phoenix.PubSub.broadcast(App.PubSub, &amp;quot;events&amp;quot;, :my_message)&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    &amp;lt;button phx-click=&amp;quot;trigger_page&amp;quot;&amp;gt;Trigger Page handle_info&amp;lt;/button&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Key Concepts: ===&lt;br /&gt;
&lt;br /&gt;
'''handle_event/3''':&lt;br /&gt;
&lt;br /&gt;
* Receives events from the client (user interactions)&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;quot;trigger_page&amp;quot;&amp;lt;/code&amp;gt; - Matches the &amp;lt;code&amp;gt;phx-click&amp;lt;/code&amp;gt; attribute value in the button&lt;br /&gt;
* Broadcasts &amp;lt;code&amp;gt;:my_message&amp;lt;/code&amp;gt; to the &amp;quot;events&amp;quot; topic&lt;br /&gt;
&lt;br /&gt;
'''phx-click Binding''':&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;phx-click=&amp;quot;trigger_page&amp;quot;&amp;lt;/code&amp;gt; - Sends a &amp;quot;trigger_page&amp;quot; event to the server when clicked&lt;br /&gt;
* The LiveView automatically handles the client-server communication&lt;br /&gt;
&lt;br /&gt;
'''Cross-LiveView Communication''':&lt;br /&gt;
&lt;br /&gt;
* HomeLive broadcasts a message via PubSub&lt;br /&gt;
* PageLive receives it in &amp;lt;code&amp;gt;handle_info(:my_message, socket)&amp;lt;/code&amp;gt;&lt;br /&gt;
* This demonstrates how separate LiveView processes can communicate&lt;br /&gt;
&lt;br /&gt;
== How It All Works Together ==&lt;br /&gt;
&lt;br /&gt;
=== The Flow: ===&lt;br /&gt;
&lt;br /&gt;
# '''Application Starts''':&lt;br /&gt;
#* Supervisor starts all children including &amp;lt;code&amp;gt;App.TimerServer&amp;lt;/code&amp;gt;&lt;br /&gt;
#* TimerServer's &amp;lt;code&amp;gt;init/1&amp;lt;/code&amp;gt; schedules the first tick&lt;br /&gt;
# '''User Visits PageLive''':&lt;br /&gt;
#* &amp;lt;code&amp;gt;mount/3&amp;lt;/code&amp;gt; is called&lt;br /&gt;
#* After WebSocket connects, subscribes to &amp;quot;events&amp;quot; topic&lt;br /&gt;
#* Initial state shows &amp;quot;Waiting for timer...&amp;quot;&lt;br /&gt;
# '''Every 3 Seconds''':&lt;br /&gt;
#* TimerServer receives &amp;lt;code&amp;gt;:tick&amp;lt;/code&amp;gt; via &amp;lt;code&amp;gt;handle_info&amp;lt;/code&amp;gt;&lt;br /&gt;
#* Broadcasts &amp;lt;code&amp;gt;{:timer_update, message}&amp;lt;/code&amp;gt; to &amp;quot;events&amp;quot; topic&lt;br /&gt;
#* PageLive receives the message in its &amp;lt;code&amp;gt;handle_info&amp;lt;/code&amp;gt;&lt;br /&gt;
#* Updates &amp;lt;code&amp;gt;@last_message&amp;lt;/code&amp;gt; assign&lt;br /&gt;
#* LiveView automatically re-renders with new message&lt;br /&gt;
# '''User Clicks Button in HomeLive''':&lt;br /&gt;
#* Browser sends &amp;quot;trigger_page&amp;quot; event to server&lt;br /&gt;
#* &amp;lt;code&amp;gt;handle_event(&amp;quot;trigger_page&amp;quot;, ...)&amp;lt;/code&amp;gt; broadcasts &amp;lt;code&amp;gt;:my_message&amp;lt;/code&amp;gt;&lt;br /&gt;
#* PageLive's &amp;lt;code&amp;gt;handle_info(:my_message, ...)&amp;lt;/code&amp;gt; receives it&lt;br /&gt;
#* Logs to console&lt;br /&gt;
&lt;br /&gt;
=== Message Flow Diagram: ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
┌─────────────────┐&lt;br /&gt;
│  TimerServer    │&lt;br /&gt;
│                 │&lt;br /&gt;
│  Every 3s:      │&lt;br /&gt;
│  broadcast()    │&lt;br /&gt;
└────────┬────────┘&lt;br /&gt;
         │&lt;br /&gt;
         ├─────────────────────┐&lt;br /&gt;
         │                     │&lt;br /&gt;
         ▼                     ▼&lt;br /&gt;
┌─────────────────┐   ┌─────────────────┐&lt;br /&gt;
│   PageLive      │   │   HomeLive      │&lt;br /&gt;
│   (subscribed)  │   │   (not sub'd)   │&lt;br /&gt;
│                 │   │                 │&lt;br /&gt;
│   handle_info   │   │   Button click  │&lt;br /&gt;
│   updates UI    │◄──┤   broadcast()   │&lt;br /&gt;
└─────────────────┘   └─────────────────┘&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Key Takeaways ==&lt;br /&gt;
&lt;br /&gt;
=== When to Use GenServer: ===&lt;br /&gt;
&lt;br /&gt;
* Background tasks that need to run continuously&lt;br /&gt;
* Maintaining state across requests&lt;br /&gt;
* Scheduled/periodic operations&lt;br /&gt;
* As a single source of truth for application state&lt;br /&gt;
&lt;br /&gt;
=== When to Use PubSub: ===&lt;br /&gt;
&lt;br /&gt;
* Broadcasting to multiple subscribers&lt;br /&gt;
* Decoupling components (sender doesn't know about receivers)&lt;br /&gt;
* Real-time updates to LiveViews&lt;br /&gt;
* Cross-process communication&lt;br /&gt;
&lt;br /&gt;
=== When to Use handle_info: ===&lt;br /&gt;
&lt;br /&gt;
* Receiving PubSub messages in LiveView&lt;br /&gt;
* Receiving messages from GenServers&lt;br /&gt;
* Receiving Process messages (like our :tick)&lt;br /&gt;
* Any asynchronous message delivery&lt;br /&gt;
&lt;br /&gt;
=== LiveView Mount Connected Check: ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;elixir&amp;quot;&amp;gt;&lt;br /&gt;
if connected?(socket) do&lt;br /&gt;
  Phoenix.PubSub.subscribe(App.PubSub, &amp;quot;events&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This prevents subscribing during initial static render, only subscribing once the WebSocket connects.&lt;br /&gt;
&lt;br /&gt;
== Running the App ==&lt;br /&gt;
&lt;br /&gt;
# Start the Phoenix server:&lt;br /&gt;
#: &amp;lt;code&amp;gt;mix phx.server&amp;lt;/code&amp;gt;&lt;br /&gt;
# Visit http://localhost:4000 to see PageLive&lt;br /&gt;
#* Should see timer updates every 3 seconds&lt;br /&gt;
# Open HomeLive in another tab&lt;br /&gt;
#* Click the button to trigger a manual message to PageLive&lt;br /&gt;
# Check the terminal logs&lt;br /&gt;
#* See TimerServer broadcasting messages&lt;br /&gt;
#* See PageLive receiving messages&lt;br /&gt;
&lt;br /&gt;
== Extending This Pattern ==&lt;br /&gt;
&lt;br /&gt;
You can extend this pattern for:&lt;br /&gt;
&lt;br /&gt;
* Real-time dashboards&lt;br /&gt;
* Chat applications&lt;br /&gt;
* Notifications systems&lt;br /&gt;
* Live data feeds&lt;br /&gt;
* Multiplayer games&lt;br /&gt;
* Collaborative editing tools&lt;br /&gt;
&lt;br /&gt;
The combination of GenServer for state management and PubSub for broadcasting makes Phoenix incredibly powerful for real-time applications.&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>http://elixirblocks.com/index.php?title=Live_view_and_handle_info&amp;diff=1915</id>
		<title>Live view and handle info</title>
		<link rel="alternate" type="text/html" href="http://elixirblocks.com/index.php?title=Live_view_and_handle_info&amp;diff=1915"/>
		<updated>2026-01-29T00:11:11Z</updated>

		<summary type="html">&lt;p&gt;Admin: Created page with &amp;quot;= Phoenix LiveView handle_info Guide for Web Developers =  == What is handle_info? ==  handle_info is Phoenix LiveView's way of handling messages sent to the LiveView process from outside normal user interactions (like clicks). It's your LiveView's inbox for asynchronous events.  In traditional web development, everything is request-response: user clicks, server responds, done. But LiveView processes are long-running and can receive messages from other parts of your syst...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Phoenix LiveView handle_info Guide for Web Developers =&lt;br /&gt;
&lt;br /&gt;
== What is handle_info? ==&lt;br /&gt;
&lt;br /&gt;
handle_info is Phoenix LiveView's way of handling messages sent to the LiveView process from outside normal user interactions (like clicks). It's your LiveView's inbox for asynchronous events.&lt;br /&gt;
&lt;br /&gt;
In traditional web development, everything is request-response: user clicks, server responds, done. But LiveView processes are long-running and can receive messages from other parts of your system while they're alive.&lt;br /&gt;
&lt;br /&gt;
== Basic Syntax ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;elixir&amp;quot;&amp;gt;&lt;br /&gt;
def handle_info(message, socket) do&lt;br /&gt;
  # Process the message&lt;br /&gt;
  # Update socket state if needed&lt;br /&gt;
  {:noreply, socket}&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Example 1: Timer (sending to self) ==&lt;br /&gt;
&lt;br /&gt;
The simplest way to trigger handle_info - send a message to yourself:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;elixir&amp;quot;&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    Process.send_after(self(), :refresh, 5000)&lt;br /&gt;
    {:ok, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_info(:refresh, socket) do&lt;br /&gt;
    IO.inspect(&amp;quot;Message received after 5 seconds!&amp;quot;)&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    Page&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Example 2: Sending Between LiveViews with PubSub ==&lt;br /&gt;
&lt;br /&gt;
'''This is the recommended way''' to send messages between LiveViews.&lt;br /&gt;
&lt;br /&gt;
=== In PageLive (the receiver): ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;elixir&amp;quot;&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    if connected?(socket) do&lt;br /&gt;
      Phoenix.PubSub.subscribe(App.PubSub, &amp;quot;events&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
    {:ok, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_info(:my_message, socket) do&lt;br /&gt;
    IO.inspect(&amp;quot;handle_info received!&amp;quot;)&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    Page&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== In HomeLive (the sender): ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;elixir&amp;quot;&amp;gt;&lt;br /&gt;
defmodule AppWeb.HomeLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    {:ok, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;trigger_page&amp;quot;, _params, socket) do&lt;br /&gt;
    Phoenix.PubSub.broadcast(App.PubSub, &amp;quot;events&amp;quot;, :my_message)&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    &amp;lt;button phx-click=&amp;quot;trigger_page&amp;quot;&amp;gt;Trigger Page handle_info&amp;lt;/button&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Why do you need both subscribe AND broadcast? ===&lt;br /&gt;
&lt;br /&gt;
* '''Subscribe''' = &amp;quot;I want to listen to messages on the 'events' topic&amp;quot;&lt;br /&gt;
* '''Broadcast''' = &amp;quot;Send this message to everyone listening to 'events'&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Without subscribe, the LiveView won't receive broadcasts. Think of it like tuning a radio to a channel - you must tune in (subscribe) before you can hear what's being transmitted (broadcast).&lt;br /&gt;
&lt;br /&gt;
=== PubSub works with multiple LiveViews ===&lt;br /&gt;
&lt;br /&gt;
If you have 3 PageLive tabs open, all 3 will receive the broadcast. That's a feature, not a bug.&lt;br /&gt;
&lt;br /&gt;
== Example 3: Process Registration (not recommended) ==&lt;br /&gt;
&lt;br /&gt;
You can register a LiveView process with a name and send directly to it:&lt;br /&gt;
&lt;br /&gt;
=== In PageLive: ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;elixir&amp;quot;&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    if connected?(socket) do&lt;br /&gt;
      Process.register(self(), :page_live_process)&lt;br /&gt;
    end&lt;br /&gt;
    {:ok, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_info(:my_message, socket) do&lt;br /&gt;
    IO.inspect(&amp;quot;handle_info received!&amp;quot;)&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    Page&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== In HomeLive: ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;elixir&amp;quot;&amp;gt;&lt;br /&gt;
defmodule AppWeb.HomeLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    {:ok, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;send_to_page&amp;quot;, _params, socket) do&lt;br /&gt;
    send(:page_live_process, :my_message)&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    &amp;lt;button phx-click=&amp;quot;send_to_page&amp;quot;&amp;gt;Send to Page&amp;lt;/button&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Problems with this approach: ===&lt;br /&gt;
&lt;br /&gt;
* Only works with ONE PageLive instance at a time&lt;br /&gt;
* Crashes if name is already taken&lt;br /&gt;
* Requires error handling bloat&lt;br /&gt;
* PageLive must be mounted first&lt;br /&gt;
&lt;br /&gt;
'''Use PubSub instead''' - it's simpler and more robust.&lt;br /&gt;
&lt;br /&gt;
== Common Sources of Messages ==&lt;br /&gt;
&lt;br /&gt;
handle_info receives messages from:&lt;br /&gt;
&lt;br /&gt;
# '''Timers''': &amp;lt;code&amp;gt;Process.send_after(self(), :tick, 1000)&amp;lt;/code&amp;gt;&lt;br /&gt;
# '''PubSub broadcasts''': &amp;lt;code&amp;gt;Phoenix.PubSub.broadcast(App.PubSub, &amp;quot;topic&amp;quot;, :msg)&amp;lt;/code&amp;gt;&lt;br /&gt;
# '''Other processes''': &amp;lt;code&amp;gt;send(liveview_pid, :msg)&amp;lt;/code&amp;gt;&lt;br /&gt;
# '''Tasks''': Background jobs completing&lt;br /&gt;
# '''GenServers''': Other parts of your application&lt;br /&gt;
&lt;br /&gt;
== Safety: Catch-all handle_info ==&lt;br /&gt;
&lt;br /&gt;
Always add a catch-all to prevent crashes from unexpected messages:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;elixir&amp;quot;&amp;gt;&lt;br /&gt;
def handle_info(msg, socket) do&lt;br /&gt;
  IO.warn(&amp;quot;Unhandled message: #{inspect(msg)}&amp;quot;)&lt;br /&gt;
  {:noreply, socket}&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Key Takeaways ==&lt;br /&gt;
&lt;br /&gt;
* handle_info handles asynchronous messages sent to your LiveView&lt;br /&gt;
* Use &amp;lt;code&amp;gt;send(self(), :msg)&amp;lt;/code&amp;gt; to send messages to yourself&lt;br /&gt;
* Use '''PubSub''' (not process registration) to send between LiveViews&lt;br /&gt;
* You must '''subscribe''' to a topic before you can receive broadcasts on that topic&lt;br /&gt;
* Always include a catch-all handle_info to handle unexpected messages&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>http://elixirblocks.com/index.php?title=Genserver&amp;diff=1914</id>
		<title>Genserver</title>
		<link rel="alternate" type="text/html" href="http://elixirblocks.com/index.php?title=Genserver&amp;diff=1914"/>
		<updated>2025-11-28T02:36:10Z</updated>

		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;mix new App --sup&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;app/lib/app.ex&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule App.Service do&lt;br /&gt;
  use GenServer&lt;br /&gt;
&lt;br /&gt;
  def start_link(state) do&lt;br /&gt;
    GenServer.start_link(__MODULE__, state, name: __MODULE__)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def init(state) do&lt;br /&gt;
     {:ok, state}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def get_state(pid) do&lt;br /&gt;
     GenServer.call(pid, :get_state)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_state(pid,state) do&lt;br /&gt;
     GenServer.call(pid, {:set_state, state})&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def handle_call(:get_state, _from, state) do&lt;br /&gt;
     {:reply, state, state}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def handle_call({:set_state, new_state}, _from, state)do&lt;br /&gt;
    {:reply,state,[new_state | state]}&lt;br /&gt;
  end&lt;br /&gt;
   &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
defmodule App.Supervisor do&lt;br /&gt;
  use Supervisor&lt;br /&gt;
&lt;br /&gt;
  def start do&lt;br /&gt;
    Supervisor.start_link(__MODULE__, [])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def init(_) do&lt;br /&gt;
     children = [&lt;br /&gt;
      {App.Service,[]}&lt;br /&gt;
     ]&lt;br /&gt;
  Supervisor.init(children, strategy: :one_for_one)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# App.Supervisor.start()&lt;br /&gt;
# # IO.inspect x&lt;br /&gt;
&lt;br /&gt;
# pid = Process.whereis(App.Service)&lt;br /&gt;
&lt;br /&gt;
# # The follwing is nil&lt;br /&gt;
# IO.inspect pid  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# Process.exit(pid, :kill)&lt;br /&gt;
# IO.inspect &amp;quot;______________&amp;quot;&lt;br /&gt;
# pid = Process.whereis(App.Service)&lt;br /&gt;
# # IO.inspect &amp;quot;_____&amp;quot;&lt;br /&gt;
# IO.inspect Process.whereis(App.Service)&lt;br /&gt;
&lt;br /&gt;
# App.Service.get_state(pid)&lt;br /&gt;
# App.Service.set_state(pid, &amp;quot;we are the world&amp;quot;)&lt;br /&gt;
# App.Service.set_state(pid, &amp;quot;hurrrray&amp;quot;)&lt;br /&gt;
# IO.inspect App.Service.get_state(pid)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;mix.exs&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule App.MixProject do&lt;br /&gt;
  use Mix.Project&lt;br /&gt;
&lt;br /&gt;
  def project do&lt;br /&gt;
    [&lt;br /&gt;
      app: :app,&lt;br /&gt;
      version: &amp;quot;0.1.0&amp;quot;,&lt;br /&gt;
      elixir: &amp;quot;~&amp;gt; 1.14&amp;quot;,&lt;br /&gt;
      start_permanent: Mix.env() == :prod,&lt;br /&gt;
      deps: deps()&lt;br /&gt;
    ]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Run &amp;quot;mix help compile.app&amp;quot; to learn about applications.&lt;br /&gt;
  def application do&lt;br /&gt;
    [&lt;br /&gt;
      extra_applications: [:logger],&lt;br /&gt;
      mod: {App.Application, []}&lt;br /&gt;
    ]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Run &amp;quot;mix help deps&amp;quot; to learn about dependencies.&lt;br /&gt;
  defp deps do&lt;br /&gt;
    [&lt;br /&gt;
      # {:dep_from_hexpm, &amp;quot;~&amp;gt; 0.3.0&amp;quot;},&lt;br /&gt;
      # {:dep_from_git, git: &amp;quot;https://github.com/elixir-lang/my_dep.git&amp;quot;, tag: &amp;quot;0.1.0&amp;quot;}&lt;br /&gt;
    ]&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;application.exs&amp;lt;b/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule App.Application do&lt;br /&gt;
  # See https://hexdocs.pm/elixir/Application.html&lt;br /&gt;
  # for more information on OTP Applications&lt;br /&gt;
  @moduledoc false&lt;br /&gt;
&lt;br /&gt;
  use Application&lt;br /&gt;
&lt;br /&gt;
  @impl true&lt;br /&gt;
  def start(_type, _args) do&lt;br /&gt;
    children = [&lt;br /&gt;
      # Starts a worker by calling: App.Worker.start_link(arg)&lt;br /&gt;
      {App.Service, []}&lt;br /&gt;
    ]&lt;br /&gt;
&lt;br /&gt;
    opts = [strategy: :one_for_one, name: App.Supervisor]&lt;br /&gt;
    Supervisor.start_link(children, opts)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__________________________________________________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Understanding Elixir OTP: GenServer and Supervisors =&lt;br /&gt;
&lt;br /&gt;
This tutorial explains the provided code, which implements a classic Elixir pattern: a stateful worker (&amp;lt;code&amp;gt;GenServer&amp;lt;/code&amp;gt;) monitored by a &amp;lt;code&amp;gt;Supervisor&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== 1. The Big Picture ==&lt;br /&gt;
&lt;br /&gt;
The goal of this application is to maintain a list of items (state) in memory.&lt;br /&gt;
&lt;br /&gt;
* '''The Service:''' Holds the state.&lt;br /&gt;
* '''The Supervisor:''' Watches the Service. If the Service crashes (or is killed), the Supervisor restarts it immediately.&lt;br /&gt;
* '''The Application:''' The entry point that tells the VM what to start when you run &amp;lt;code&amp;gt;iex -S mix&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== 2. The Worker: App.Service ==&lt;br /&gt;
&lt;br /&gt;
Located in &amp;lt;code&amp;gt;app/lib/app.ex&amp;lt;/code&amp;gt;, this module is a '''GenServer''' (Generic Server). It splits logic into two parts: the '''Client API''' (helper functions you call) and the '''Server Callbacks''' (logic running inside the process).&lt;br /&gt;
&lt;br /&gt;
=== The Code Breakdown ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;elixir&amp;quot;&amp;gt;&lt;br /&gt;
defmodule App.Service do&lt;br /&gt;
  use GenServer&lt;br /&gt;
&lt;br /&gt;
  # 1. Start the process&lt;br /&gt;
  def start_link(state) do&lt;br /&gt;
    # __MODULE__ is &amp;quot;App.Service&amp;quot;. We register the process under this name&lt;br /&gt;
    # so we don't have to track the PID manually.&lt;br /&gt;
    GenServer.start_link(__MODULE__, state, name: __MODULE__)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # 2. Initialize State&lt;br /&gt;
  def init(state) do&lt;br /&gt;
     {:ok, state}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # --- Client API ---&lt;br /&gt;
&lt;br /&gt;
  def get_state(pid) do&lt;br /&gt;
     GenServer.call(pid, :get_state)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_state(pid, state) do&lt;br /&gt;
     GenServer.call(pid, {:set_state, state})&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # --- Server Callbacks ---&lt;br /&gt;
&lt;br /&gt;
  # Handling get_state&lt;br /&gt;
  def handle_call(:get_state, _from, state) do&lt;br /&gt;
     # Return: {:reply, response_to_client, internal_state}&lt;br /&gt;
     {:reply, state, state}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Handling set_state&lt;br /&gt;
  def handle_call({:set_state, new_item}, _from, current_list) do&lt;br /&gt;
    # Logic: Prepend the new_item to the current_list&lt;br /&gt;
    new_state = [new_item | current_list]&lt;br /&gt;
    &lt;br /&gt;
    # Note: You are returning 'current_list' (the old state) to the caller,&lt;br /&gt;
    # but saving 'new_state' internally.&lt;br /&gt;
    {:reply, current_list, new_state}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Key Takeaway ===&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;handle_call&amp;lt;/code&amp;gt; for &amp;lt;code&amp;gt;:set_state&amp;lt;/code&amp;gt; has a specific behavior:&lt;br /&gt;
&lt;br /&gt;
# It receives a new item.&lt;br /&gt;
# It replies with the '''old''' list.&lt;br /&gt;
# It updates its internal state to the '''new''' list (with the item prepended).&lt;br /&gt;
&lt;br /&gt;
== 3. The Entry Point: App.Application ==&lt;br /&gt;
&lt;br /&gt;
In &amp;lt;code&amp;gt;application.exs&amp;lt;/code&amp;gt;, you defined the application startup logic. This is triggered because &amp;lt;code&amp;gt;mix.exs&amp;lt;/code&amp;gt; has &amp;lt;code&amp;gt;mod: {App.Application, []}&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;elixir&amp;quot;&amp;gt;&lt;br /&gt;
defmodule App.Application do&lt;br /&gt;
  use Application&lt;br /&gt;
&lt;br /&gt;
  def start(_type, _args) do&lt;br /&gt;
    children = [&lt;br /&gt;
      # This tells the Supervisor to start App.Service with an empty list [] as initial state&lt;br /&gt;
      {App.Service, []}&lt;br /&gt;
    ]&lt;br /&gt;
&lt;br /&gt;
    opts = [strategy: :one_for_one, name: App.Supervisor]&lt;br /&gt;
    Supervisor.start_link(children, opts)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Note regarding &amp;lt;code&amp;gt;App.Supervisor&amp;lt;/code&amp;gt;''':&lt;br /&gt;
In your &amp;lt;code&amp;gt;app.ex&amp;lt;/code&amp;gt; file, you manually defined a module named &amp;lt;code&amp;gt;App.Supervisor&amp;lt;/code&amp;gt;. However, your &amp;lt;code&amp;gt;App.Application&amp;lt;/code&amp;gt; '''is ignored that module''' and starting a supervisor directly using &amp;lt;code&amp;gt;Supervisor.start_link/2&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;App.Service&amp;lt;/code&amp;gt; is currently being supervised directly by the Application root supervisor.&lt;br /&gt;
&lt;br /&gt;
== 4. Interactive Tutorial: Testing Fault Tolerance ==&lt;br /&gt;
&lt;br /&gt;
Now, let's look at the commented-out script at the bottom of your file. This demonstrates the power of OTP.&lt;br /&gt;
&lt;br /&gt;
Open your terminal in the project folder and run:&lt;br /&gt;
 iex -S mix&lt;br /&gt;
&lt;br /&gt;
=== Step 1: Verify the Service is running ===&lt;br /&gt;
&lt;br /&gt;
Because of &amp;lt;code&amp;gt;App.Application&amp;lt;/code&amp;gt;, the service starts automatically.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;elixir&amp;quot;&amp;gt;&lt;br /&gt;
# Check if the process exists by looking up its name&lt;br /&gt;
pid = Process.whereis(App.Service)&lt;br /&gt;
# Output: #PID&amp;lt;0.152.0&amp;gt; (The ID will vary)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Step 2: Manipulate State ===&lt;br /&gt;
&lt;br /&gt;
Let's use the API functions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;elixir&amp;quot;&amp;gt;&lt;br /&gt;
# Get initial state (defined as [] in App.Application)&lt;br /&gt;
App.Service.get_state(pid)&lt;br /&gt;
# Output: []&lt;br /&gt;
&lt;br /&gt;
# Add an item&lt;br /&gt;
App.Service.set_state(pid, &amp;quot;we are the world&amp;quot;)&lt;br /&gt;
# Output: []  &amp;lt;-- Rembember, handle_call returns the OLD state&lt;br /&gt;
&lt;br /&gt;
# Add another&lt;br /&gt;
App.Service.set_state(pid, &amp;quot;hurray&amp;quot;)&lt;br /&gt;
# Output: [&amp;quot;we are the world&amp;quot;]&lt;br /&gt;
&lt;br /&gt;
# Check current state&lt;br /&gt;
App.Service.get_state(pid)&lt;br /&gt;
# Output: [&amp;quot;hurray&amp;quot;, &amp;quot;we are the world&amp;quot;]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Step 3: The &amp;quot;Let it Crash&amp;quot; Test ===&lt;br /&gt;
&lt;br /&gt;
This is the most important part of the tutorial. We will kill the process and watch the Supervisor bring it back to life.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;elixir&amp;quot;&amp;gt;&lt;br /&gt;
# 1. Get the current PID&lt;br /&gt;
pid = Process.whereis(App.Service)&lt;br /&gt;
&lt;br /&gt;
# 2. Kill the process forcefully&lt;br /&gt;
Process.exit(pid, :kill)&lt;br /&gt;
&lt;br /&gt;
# 3. Check if it's alive&lt;br /&gt;
new_pid = Process.whereis(App.Service)&lt;br /&gt;
&lt;br /&gt;
# 4. Compare&lt;br /&gt;
pid == new_pid&lt;br /&gt;
# Output: false&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''What happened?'''&lt;br /&gt;
&lt;br /&gt;
# You killed the process.&lt;br /&gt;
# The Supervisor noticed the child died.&lt;br /&gt;
# The Supervisor restarted &amp;lt;code&amp;gt;App.Service.start_link([])&amp;lt;/code&amp;gt; immediately.&lt;br /&gt;
# The &amp;lt;code&amp;gt;new_pid&amp;lt;/code&amp;gt; is different because it is a brand new process.&lt;br /&gt;
# '''Important:''' The state reset to &amp;lt;code&amp;gt;[]&amp;lt;/code&amp;gt; because the process memory was wiped when it died. (To keep state across restarts, you would need a database or ETS table).&lt;br /&gt;
&lt;br /&gt;
== Summary ==&lt;br /&gt;
&lt;br /&gt;
# '''&amp;lt;code&amp;gt;mix.exs&amp;lt;/code&amp;gt;''' defines the entry point (&amp;lt;code&amp;gt;App.Application&amp;lt;/code&amp;gt;).&lt;br /&gt;
# '''&amp;lt;code&amp;gt;App.Application&amp;lt;/code&amp;gt;''' starts a Supervisor.&lt;br /&gt;
# '''The Supervisor''' starts &amp;lt;code&amp;gt;App.Service&amp;lt;/code&amp;gt;.&lt;br /&gt;
# '''&amp;lt;code&amp;gt;App.Service&amp;lt;/code&amp;gt;''' holds state in a loop.&lt;br /&gt;
# If &amp;lt;code&amp;gt;App.Service&amp;lt;/code&amp;gt; dies, the Supervisor restarts it fresh.&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>http://elixirblocks.com/index.php?title=How_to_Create_a_Basic_PubSub_Application&amp;diff=1913</id>
		<title>How to Create a Basic PubSub Application</title>
		<link rel="alternate" type="text/html" href="http://elixirblocks.com/index.php?title=How_to_Create_a_Basic_PubSub_Application&amp;diff=1913"/>
		<updated>2025-09-01T18:31:53Z</updated>

		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{In progress}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==In LiveView == &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   def mount(_params, _session, socket) do&lt;br /&gt;
     Testbeds.subscribe()&lt;br /&gt;
     {:ok, assign(socket, testbeds: Testbeds.list_testbeds())}&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
  def handle_info({TestBeds, [:testbed | _], _}, socket) do&lt;br /&gt;
     {:noreply, assign(socket, testbeds: TestBeds.list_testbeds())}&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== App/test_beds.ex ==&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@topic inspect(__MODULE__)&lt;br /&gt;
&lt;br /&gt;
def subscribe do&lt;br /&gt;
  Phoenix.PubSub.subscribe(App.PubSub, @topic)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
defp broadcast_change({:ok, result}, event) do&lt;br /&gt;
  Phoenix.PubSub.broadcast(App.PubSub, @topic, {__MODULE__, event, result})&lt;br /&gt;
&lt;br /&gt;
  {:ok, result}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ....&lt;br /&gt;
&lt;br /&gt;
  def create_testbed(attrs \\ %{}) do&lt;br /&gt;
    %Testbed{}&lt;br /&gt;
    |&amp;gt; Testbed.changeset(attrs)&lt;br /&gt;
    |&amp;gt; Repo.insert()&lt;br /&gt;
    |&amp;gt; broadcast_change([:testbed, :created])&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Example Without Database ==&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  &lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    if connected?(socket) do&lt;br /&gt;
      AppWeb.Endpoint.subscribe(topic)&lt;br /&gt;
    end&lt;br /&gt;
    {:ok, assign(socket, username: username, messages: [])}&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def handle_info(%{event: &amp;quot;message&amp;quot;, payload: message}, socket) do&lt;br /&gt;
    {:noreply, assign(socket, messages: socket.assigns.messages ++ [message])}&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def handle_event(&amp;quot;send&amp;quot;, %{&amp;quot;text&amp;quot; =&amp;gt; text}, socket) do&lt;br /&gt;
    AppWeb.Endpoint.broadcast(topic, &amp;quot;message&amp;quot;, %{text: text, name: socket.assigns.username})&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  defp username do&lt;br /&gt;
    &amp;quot;User #{:rand.uniform(100)}&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  defp topic do&lt;br /&gt;
    &amp;quot;chat&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns)do   &lt;br /&gt;
   ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
  &amp;lt;h1&amp;gt;ChatLive&amp;lt;/h1&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;messages&amp;quot; style=&amp;quot;border: 1px solid #eee; height: 400px; overflow: scroll; margin-bottom: 8px;&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;%= for m &amp;lt;- @messages do %&amp;gt;&lt;br /&gt;
      &amp;lt;p style=&amp;quot;margin: 2px;&amp;quot;&amp;gt;&amp;lt;b&amp;gt;&amp;lt;%= m.name %&amp;gt;&amp;lt;/b&amp;gt;: &amp;lt;%= m.text %&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;form phx-submit=&amp;quot;send&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;text&amp;quot; /&amp;gt;&lt;br /&gt;
    &amp;lt;button type=&amp;quot;submit&amp;quot;&amp;gt;Send&amp;lt;/button&amp;gt;&lt;br /&gt;
  &amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
# lib/app/counter.ex&lt;br /&gt;
defmodule Counter do&lt;br /&gt;
  use Agent&lt;br /&gt;
&lt;br /&gt;
  def start_link(initial_value) do&lt;br /&gt;
    Agent.start_link(fn -&amp;gt; initial_value end, name: __MODULE__)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def value do&lt;br /&gt;
    Agent.get(__MODULE__, &amp;amp; &amp;amp;1)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def increment do&lt;br /&gt;
    Agent.update(__MODULE__, &amp;amp;(&amp;amp;1 + 1))&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# lib/app_web/live/page_live.ex&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    Phoenix.PubSub.subscribe(App.PubSub, &amp;quot;the-topic&amp;quot;)&lt;br /&gt;
    &lt;br /&gt;
    # Get current value from the supervised Counter&lt;br /&gt;
    data = Counter.value()&lt;br /&gt;
    &lt;br /&gt;
    {:ok, assign(socket, data: data)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;increment&amp;quot;, _params, socket) do&lt;br /&gt;
    Counter.increment()&lt;br /&gt;
    new_data = Counter.value()&lt;br /&gt;
    Phoenix.PubSub.broadcast(App.PubSub, &amp;quot;the-topic&amp;quot;, new_data)&lt;br /&gt;
    {:noreply, assign(socket, data: new_data)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_info(new_data_from_broadcast, socket) do  # usually set with pattern match like {:data,thedata}&lt;br /&gt;
    IO.inspect new_data_from_broadcast&lt;br /&gt;
    {:noreply, assign(socket, data: new_data_from_broadcast)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    &amp;lt;div&amp;gt;&lt;br /&gt;
      &amp;lt;.button phx-click=&amp;quot;increment&amp;quot;&amp;gt;click me &amp;lt;/.button&amp;gt;&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;div&amp;gt;{@data}&amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>http://elixirblocks.com/index.php?title=Welcome_to_ElixirBlocks&amp;diff=1912</id>
		<title>Welcome to ElixirBlocks</title>
		<link rel="alternate" type="text/html" href="http://elixirblocks.com/index.php?title=Welcome_to_ElixirBlocks&amp;diff=1912"/>
		<updated>2025-08-31T05:08:45Z</updated>

		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Phoenix and Elixir Programming Wiki=&lt;br /&gt;
To view all Elixir tutorials and content just click [[Special:AllPages|Explore]]&lt;br /&gt;
&lt;br /&gt;
This is my personal web project where I document blocks of Elixir and Phoenix code that I find useful. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
def hello_world() do &lt;br /&gt;
  &amp;quot;hello world&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Special:UserLogin | LogIn or Create Account]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>http://elixirblocks.com/index.php?title=How_to_Fetch_a_GET_request_like_in_Javascript&amp;diff=1911</id>
		<title>How to Fetch a GET request like in Javascript</title>
		<link rel="alternate" type="text/html" href="http://elixirblocks.com/index.php?title=How_to_Fetch_a_GET_request_like_in_Javascript&amp;diff=1911"/>
		<updated>2025-08-29T01:02:41Z</updated>

		<summary type="html">&lt;p&gt;Admin: Created page with &amp;quot; &amp;lt;source&amp;gt; defmodule App do  # Install Req from hex   def fetch do        task =  Task.async(fn -&amp;gt; Req.get!(&amp;quot;https://api.github.com/repos/wojtekmach/req&amp;quot;) end)        Task.await(task)    end end &amp;lt;/source&amp;gt;&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule App do&lt;br /&gt;
 # Install Req from hex&lt;br /&gt;
  def fetch do&lt;br /&gt;
       task =  Task.async(fn -&amp;gt; Req.get!(&amp;quot;https://api.github.com/repos/wojtekmach/req&amp;quot;) end)&lt;br /&gt;
       Task.await(task)&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>http://elixirblocks.com/index.php?title=Liveview_Text_Search_and_Highlight_Example_App&amp;diff=1910</id>
		<title>Liveview Text Search and Highlight Example App</title>
		<link rel="alternate" type="text/html" href="http://elixirblocks.com/index.php?title=Liveview_Text_Search_and_Highlight_Example_App&amp;diff=1910"/>
		<updated>2025-07-31T14:58:30Z</updated>

		<summary type="html">&lt;p&gt;Admin: Created page with &amp;quot;&amp;lt;source&amp;gt; # lib/my_app_web/live/json_search_live.ex defmodule AppWeb.SandboxLive do   use AppWeb, :live_view    def mount(_params, _session, socket) do     {:ok, assign(socket, text: &amp;quot;Hello world! This is a test. Hello again!&amp;quot;, search: &amp;quot;&amp;quot;)}   end    def handle_event(&amp;quot;search_change&amp;quot;, %{&amp;quot;value&amp;quot; =&amp;gt; search}, socket) do     {:noreply, assign(socket, search: search)}   end    def handle_event(&amp;quot;text_change&amp;quot;, %{&amp;quot;value&amp;quot; =&amp;gt; text}, socket) do     {:noreply, assign(socket, text: text...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source&amp;gt;&lt;br /&gt;
# lib/my_app_web/live/json_search_live.ex&lt;br /&gt;
defmodule AppWeb.SandboxLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    {:ok, assign(socket, text: &amp;quot;Hello world! This is a test. Hello again!&amp;quot;, search: &amp;quot;&amp;quot;)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;search_change&amp;quot;, %{&amp;quot;value&amp;quot; =&amp;gt; search}, socket) do&lt;br /&gt;
    {:noreply, assign(socket, search: search)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;text_change&amp;quot;, %{&amp;quot;value&amp;quot; =&amp;gt; text}, socket) do&lt;br /&gt;
    {:noreply, assign(socket, text: text)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    &amp;lt;div class=&amp;quot;p-4&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;h1 class=&amp;quot;text-xl mb-4&amp;quot;&amp;gt;Search Test&amp;lt;/h1&amp;gt;&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;div class=&amp;quot;mb-4&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;input&lt;br /&gt;
          type=&amp;quot;text&amp;quot;&lt;br /&gt;
          value={@search}&lt;br /&gt;
          phx-keyup=&amp;quot;search_change&amp;quot;&lt;br /&gt;
          placeholder=&amp;quot;Search...&amp;quot;&lt;br /&gt;
          class=&amp;quot;w-full p-2 border&amp;quot;&lt;br /&gt;
        /&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;div class=&amp;quot;mb-4&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;textarea&lt;br /&gt;
          rows=&amp;quot;4&amp;quot;&lt;br /&gt;
          phx-keyup=&amp;quot;text_change&amp;quot;&lt;br /&gt;
          class=&amp;quot;w-full p-2 border&amp;quot;&lt;br /&gt;
        &amp;gt;&amp;lt;%= @text %&amp;gt;&amp;lt;/textarea&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;div class=&amp;quot;border p-4 bg-gray-100&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;%= if @search != &amp;quot;&amp;quot; do %&amp;gt;&lt;br /&gt;
          &amp;lt;%= raw(String.replace(@text, ~r/#{Regex.escape(@search)}/i, &amp;quot;&amp;lt;span style='background: yellow'&amp;gt;\\0&amp;lt;/span&amp;gt;&amp;quot;)) %&amp;gt;&lt;br /&gt;
        &amp;lt;% else %&amp;gt;&lt;br /&gt;
          &amp;lt;%= @text %&amp;gt;&lt;br /&gt;
        &amp;lt;% end %&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>http://elixirblocks.com/index.php?title=Postgres_Setup&amp;diff=1909</id>
		<title>Postgres Setup</title>
		<link rel="alternate" type="text/html" href="http://elixirblocks.com/index.php?title=Postgres_Setup&amp;diff=1909"/>
		<updated>2025-07-16T16:10:00Z</updated>

		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Windows==&lt;br /&gt;
Download and install postgres from:  https://www.enterprisedb.com/downloads/postgres-postgresql-downloads&lt;br /&gt;
&lt;br /&gt;
When complete , launch the SQL Shell (psql) prompt application.&lt;br /&gt;
&lt;br /&gt;
Press Enter for each item in the list except &amp;quot;password&amp;quot;. For password the default password is password.&lt;br /&gt;
Type the password and hit Enter.&lt;br /&gt;
&lt;br /&gt;
==Useful Commands ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Drop the existing database'''&lt;br /&gt;
&lt;br /&gt;
dropdb -h localhost -p 5432 -U testbed_admin_name database_name&lt;br /&gt;
&lt;br /&gt;
'''Create a fresh database'''&lt;br /&gt;
&lt;br /&gt;
createdb -h localhost -p 5432 -U testbed_admin_name database_name&lt;br /&gt;
&lt;br /&gt;
'''Now import the backup'''&lt;br /&gt;
&lt;br /&gt;
psql -h localhost -p 5432 -U testbed_admin_name -d database_name &amp;lt; database_backup.sql&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* h localhost - hostname&lt;br /&gt;
* p 5432 - port (default PostgreSQL port)&lt;br /&gt;
* U testbed_admin_name - username&lt;br /&gt;
* d database_name - database name&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>http://elixirblocks.com/index.php?title=Postgres_Setup&amp;diff=1908</id>
		<title>Postgres Setup</title>
		<link rel="alternate" type="text/html" href="http://elixirblocks.com/index.php?title=Postgres_Setup&amp;diff=1908"/>
		<updated>2025-07-16T16:09:25Z</updated>

		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Windows==&lt;br /&gt;
Download and install postgres from:  https://www.enterprisedb.com/downloads/postgres-postgresql-downloads&lt;br /&gt;
&lt;br /&gt;
When complete , launch the SQL Shell (psql) prompt application.&lt;br /&gt;
&lt;br /&gt;
Press Enter for each item in the list except &amp;quot;password&amp;quot;. For password the default password is password.&lt;br /&gt;
Type the password and hit Enter.&lt;br /&gt;
&lt;br /&gt;
==Useful Commands ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Drop the existing database'''&lt;br /&gt;
&lt;br /&gt;
dropdb -h localhost -p 5432 -U testbed_admin_name database_name&lt;br /&gt;
&lt;br /&gt;
'''Create a fresh database'''&lt;br /&gt;
&lt;br /&gt;
createdb -h localhost -p 5432 -U testbed_admin_name database_name&lt;br /&gt;
&lt;br /&gt;
'''Now import the backup'''&lt;br /&gt;
&lt;br /&gt;
psql -h localhost -p 5432 -U testbed_admin_name -d database_name &amp;lt; database_backup.sql&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-h localhost - hostname&lt;br /&gt;
&lt;br /&gt;
-p 5432 - port (default PostgreSQL port)&lt;br /&gt;
&lt;br /&gt;
-U testbed_admin_name - username&lt;br /&gt;
&lt;br /&gt;
-d database_name - database name&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>http://elixirblocks.com/index.php?title=Postgres_Setup&amp;diff=1907</id>
		<title>Postgres Setup</title>
		<link rel="alternate" type="text/html" href="http://elixirblocks.com/index.php?title=Postgres_Setup&amp;diff=1907"/>
		<updated>2025-07-16T16:09:12Z</updated>

		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Windows==&lt;br /&gt;
Download and install postgres from:  https://www.enterprisedb.com/downloads/postgres-postgresql-downloads&lt;br /&gt;
&lt;br /&gt;
When complete , launch the SQL Shell (psql) prompt application.&lt;br /&gt;
&lt;br /&gt;
Press Enter for each item in the list except &amp;quot;password&amp;quot;. For password the default password is password.&lt;br /&gt;
Type the password and hit Enter.&lt;br /&gt;
&lt;br /&gt;
==Useful Commands ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Drop the existing database'''&lt;br /&gt;
&lt;br /&gt;
dropdb -h localhost -p 5432 -U testbed_admin_name database_name&lt;br /&gt;
&lt;br /&gt;
'''Create a fresh database'''&lt;br /&gt;
&lt;br /&gt;
createdb -h localhost -p 5432 -U testbed_admin_name database_name&lt;br /&gt;
&lt;br /&gt;
'''Now import the backup'''&lt;br /&gt;
&lt;br /&gt;
psql -h localhost -p 5432 -U testbed_admin_name -d database_name &amp;lt; database_backup.sql&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-h localhost - hostname&lt;br /&gt;
-p 5432 - port (default PostgreSQL port)&lt;br /&gt;
-U testbed_admin_name - username&lt;br /&gt;
-d database_name - database name&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>http://elixirblocks.com/index.php?title=User:Admin&amp;diff=1906</id>
		<title>User:Admin</title>
		<link rel="alternate" type="text/html" href="http://elixirblocks.com/index.php?title=User:Admin&amp;diff=1906"/>
		<updated>2025-06-25T19:27:23Z</updated>

		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;from(a in Alert, where: a.timed_alert == true)&lt;br /&gt;
|&amp;gt; Repo.update_all(set: [enabled: false])&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.Sandbox do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    {:ok, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;start_task&amp;quot;, _params, socket) do&lt;br /&gt;
    Task.async(fn -&amp;gt; :hello_from_task end)&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_info({ref, result}, socket) do&lt;br /&gt;
    IO.inspect&amp;quot;________________________________________________________________________________&amp;quot;&lt;br /&gt;
    IO.inspect({:task_result_received, ref, result})&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_info(msg, socket) do&lt;br /&gt;
    # Optionally log or inspect the unhandled message if you're curious&lt;br /&gt;
    # IO.inspect({:unhandled_info, msg})&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    &amp;lt;div&amp;gt;&lt;br /&gt;
      &amp;lt;button phx-click=&amp;quot;start_task&amp;quot;&amp;gt;Start Task&amp;lt;/button&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Barebones&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.Sandbox do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    {:ok, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;start_task&amp;quot;, _params, socket) do&lt;br /&gt;
    Task.async(fn -&amp;gt; :hello_from_task end)&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_info({ref, result}, socket) do&lt;br /&gt;
    IO.inspect&amp;quot;________________________________________________________________________________&amp;quot;&lt;br /&gt;
    IO.inspect({:task_result_received, ref, result})&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_info({:DOWN, ref, :process, pid, reason}, socket) do&lt;br /&gt;
    IO.inspect({:task_completed, ref, pid, reason})&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    &amp;lt;div&amp;gt;&lt;br /&gt;
      &amp;lt;button phx-click=&amp;quot;start_task&amp;quot;&amp;gt;Start Task&amp;lt;/button&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Barebones&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Async claude ai example&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Explain to me the relationship between handle_info and making an async call&lt;br /&gt;
&lt;br /&gt;
The relationship between handle_info and making async calls in Phoenix LiveView is fundamental to understanding how to handle non-blocking operations in your application.&lt;br /&gt;
&lt;br /&gt;
When you make an asynchronous call in Elixir (like using Task.async), you're creating a separate process that runs independently from your LiveView process. This allows your LiveView to remain responsive while potentially time-consuming operations (like API calls) are happening.&lt;br /&gt;
&lt;br /&gt;
Here's how they work together:&lt;br /&gt;
&lt;br /&gt;
Async Operation Initiation: When you start an async operation using Task.async, it returns a reference to the task.&lt;br /&gt;
Message Passing: When the async task completes, it automatically sends a message back to the process that created it. This message contains the task reference and the result: {ref, result}.&lt;br /&gt;
handle_info Reception: The handle_info/2 callback in LiveView is what receives these messages. It's like a mailbox for your LiveView process that handles any messages not related to LiveView events.&lt;br /&gt;
Process Cleanup: After receiving the result, you typically call Process.demonitor(ref, [:flush]) to clean up process monitoring and prevent receiving a :DOWN message when the task process exits.&lt;br /&gt;
This pattern creates a complete async lifecycle:&lt;br /&gt;
&lt;br /&gt;
Start async task →&lt;br /&gt;
Task runs independently →&lt;br /&gt;
Task completes and sends message →&lt;br /&gt;
handle_info receives message →&lt;br /&gt;
Update LiveView state&lt;br /&gt;
In the example I provided, there's a clear separation of concerns:&lt;br /&gt;
&lt;br /&gt;
Task.async(fn -&amp;gt; api() end) starts the async operation&lt;br /&gt;
handle_info({ref, result}, socket) receives and processes the result&lt;br /&gt;
The LiveView remains responsive throughout the entire operation&lt;br /&gt;
This pattern is what makes LiveView capable of handling concurrent operations while maintaining a responsive UI for users.&lt;br /&gt;
________________________&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.Sandbox do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    # Schedule the API call to happen after mount&lt;br /&gt;
    if connected?(socket), do: Process.send_after(self(), :fetch_data, 0)&lt;br /&gt;
    {:ok, assign(socket, data: nil)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_info(:fetch_data, socket) do&lt;br /&gt;
    # Launch API call in separate process&lt;br /&gt;
    Task.async(fn -&amp;gt; api() end)&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_info({ref, result}, socket) when is_reference(ref) do&lt;br /&gt;
    # Clean up the DOWN message&lt;br /&gt;
    Process.demonitor(ref, [:flush])&lt;br /&gt;
    {:noreply, assign(socket, data: result)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def api do&lt;br /&gt;
    Req.request(url: &amp;quot;https://api.github.com/repos/wojtekmach/req&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    SANDBOX&lt;br /&gt;
    &amp;lt;%= if @data, do: inspect(@data) %&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
___________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 defmodule Heading do&lt;br /&gt;
   use Phoenix.Component&lt;br /&gt;
   def head(assigns) do&lt;br /&gt;
	   ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	     &amp;lt;p&amp;gt;Hello, &amp;lt;%= @headings %&amp;gt;!&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	   &amp;quot;&amp;quot;&amp;quot; &lt;br /&gt;
   end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
   use AppWeb, :live_view  &lt;br /&gt;
   import Heading&lt;br /&gt;
   def mount(_params, _session, socket)  do&lt;br /&gt;
	 {:ok, socket}  &lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
   def headings do &lt;br /&gt;
    [&amp;quot;one&amp;quot;,&amp;quot;two&amp;quot;,&amp;quot;three&amp;quot;]&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
   def render(assigns) do&lt;br /&gt;
	   ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	     &amp;lt;Heading.head  headings={headings()} /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	   &amp;quot;&amp;quot;&amp;quot; &lt;br /&gt;
   end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://app.studyraid.com/en/read/11967/381872/component-communication&lt;br /&gt;
&lt;br /&gt;
https://thepugautomatic.com/2020/08/communicating-between-liveviews-on-the-same-page/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
from(a in Article,&lt;br /&gt;
  order_by: [desc: a.inserted_at],  # Assuming 'inserted_at' is the timestamp for when the article was created or updated&lt;br /&gt;
  limit: 8&lt;br /&gt;
)&lt;br /&gt;
|&amp;gt; Repo.all()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.Landing do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  alias App.Testbeds&lt;br /&gt;
  alias App.Testbeds.Testbed&lt;br /&gt;
  alias App.Repo  # Ensure to alias Repo&lt;br /&gt;
  import Ecto.Query  # Import Ecto.Query to work with queries&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    # Default to ordering by name&lt;br /&gt;
    testbeds = Repo.all(from(t in Testbed, order_by: t.name))&lt;br /&gt;
&lt;br /&gt;
    # Assign the testbeds to the socket for rendering&lt;br /&gt;
    {:ok, assign(socket, testbeds: testbeds, sort: :name)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    &amp;lt;h1&amp;gt;Hello World! YAY&amp;lt;/h1&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;div&amp;gt;&lt;br /&gt;
      &amp;lt;!-- Buttons to toggle sorting --&amp;gt;&lt;br /&gt;
      &amp;lt;button phx-click=&amp;quot;sort_by_name&amp;quot;&amp;gt;Sort by Name&amp;lt;/button&amp;gt;&lt;br /&gt;
      &amp;lt;button phx-click=&amp;quot;sort_by_updated_at&amp;quot;&amp;gt;Sort by Updated By&amp;lt;/button&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;ul&amp;gt;&lt;br /&gt;
      &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
        &amp;lt;li&amp;gt;&amp;lt;%= testbed.name %&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;% end %&amp;gt;&lt;br /&gt;
    &amp;lt;/ul&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;sort_by_name&amp;quot;, _params, socket) do&lt;br /&gt;
    testbeds = Repo.all(from(t in Testbed, order_by: t.name))&lt;br /&gt;
    {:noreply, assign(socket, testbeds: testbeds, sort: :name)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;sort_by_updated_at&amp;quot;, _params, socket) do&lt;br /&gt;
    testbeds = Repo.all(from(t in Testbed, order_by: t.inserted_at))&lt;br /&gt;
    {:noreply, assign(socket, testbeds: testbeds, sort: :inserted_at)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
_______________________________________________________&lt;br /&gt;
&lt;br /&gt;
* Create a form with a post request. &lt;br /&gt;
* Create the route needed for that request&lt;br /&gt;
* Create the controller needed for that route&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Form==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;.form action={~p&amp;quot;/todos&amp;quot;} method=&amp;quot;post&amp;quot; class=&amp;quot;mt-10 space-y-8&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    &amp;lt;label for=&amp;quot;contact_name&amp;quot; class=&amp;quot;block text-sm font-semibold leading-6 text-zinc-800&amp;quot;&amp;gt;&lt;br /&gt;
      Name&lt;br /&gt;
    &amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;input&lt;br /&gt;
      id=&amp;quot;todo&amp;quot;&lt;br /&gt;
      type=&amp;quot;text&amp;quot;&lt;br /&gt;
      name=&amp;quot;todo&amp;quot;&lt;br /&gt;
      class=&amp;quot;mt-2 block w-full rounded-lg text-zinc-900 focus:ring-0 sm:text-sm sm:leading-6 border-zinc-300 focus:border-zinc-400&amp;quot;&lt;br /&gt;
    /&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;button&lt;br /&gt;
    type=&amp;quot;submit&amp;quot;&lt;br /&gt;
    class=&amp;quot;rounded-lg bg-zinc-900 hover:bg-zinc-700 py-2 px-3 text-sm font-semibold leading-6 text-white active:text-white/80&amp;quot;&lt;br /&gt;
  &amp;gt;&lt;br /&gt;
    Save Contact&lt;br /&gt;
  &amp;lt;/button&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/.form&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Controller==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# In your TodoController&lt;br /&gt;
defmodule AppWeb.TodoController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  # Action to handle the form submission (POST request)&lt;br /&gt;
  def create(conn, %{&amp;quot;todo&amp;quot; =&amp;gt; todo_name}) do&lt;br /&gt;
    # Here you can handle the form data (e.g., save it to the database)&lt;br /&gt;
    IO.puts(&amp;quot;Received Todo: #{todo_name}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    # For now, let's just redirect to the home page&lt;br /&gt;
    conn&lt;br /&gt;
    |&amp;gt; put_flash(:info, &amp;quot;Todo saved!&amp;quot;)&lt;br /&gt;
    |&amp;gt; redirect(to: &amp;quot;/&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
________________________________________________________&lt;br /&gt;
&lt;br /&gt;
# CRUD Forms&lt;br /&gt;
&lt;br /&gt;
To understand CRUD forms you will need to understand the following concepts. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Ecto Schema&lt;br /&gt;
* Ecto Context&lt;br /&gt;
* Form Basics&lt;br /&gt;
* form/1&lt;br /&gt;
* simple_form/1&lt;br /&gt;
* changesets&lt;br /&gt;
&lt;br /&gt;
We are not going to go in order. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The Context provides CRUD functions for the chosen data schema. Phoenix contexts define the interface through which other parts of the codebase can interact with the app layer.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_______________________&lt;br /&gt;
* Create routes&lt;br /&gt;
* create page with form (submit get request)&lt;br /&gt;
&lt;br /&gt;
(ecto schema, context, changesets)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_______________________________________________________&lt;br /&gt;
In that case, you really should switch it to prod mode. Instead of doing all that above with the &amp;quot;config/secret.exs&amp;quot; file, create the &amp;quot;.env&amp;quot; in the project root, then add DotenvParser.load_file(&amp;quot;.env&amp;quot;) to &amp;quot;config/runtime.exs&amp;quot; as the first line inside the if config_env() == :prod do. In the .env file, set the DATABASE_URL and SECRET_KEY_BASE. Then run it as MIX_ENV=prod mix phx.server.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def get_titles do&lt;br /&gt;
    urls = [&lt;br /&gt;
      &amp;quot;https://cointelegraph.com/rss&amp;quot;,&lt;br /&gt;
      &amp;quot;https://chaski.huffpost.com/us/auto/vertical/us-news&amp;quot;&lt;br /&gt;
      # Add more RSS feed URLs here&lt;br /&gt;
    ]&lt;br /&gt;
&lt;br /&gt;
    urls&lt;br /&gt;
    |&amp;gt; Enum.map(fn url -&amp;gt;&lt;br /&gt;
      with {:ok, feed} &amp;lt;- ElixirRss.fetch_and_parse(url) do&lt;br /&gt;
        Enum.map(feed.entries, &amp;amp; &amp;amp;1.title)&lt;br /&gt;
      else&lt;br /&gt;
        {:error, reason} -&amp;gt; {:error, reason}&lt;br /&gt;
      end&lt;br /&gt;
    end)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule App do&lt;br /&gt;
&lt;br /&gt;
  def get_titles() do&lt;br /&gt;
    data = [&lt;br /&gt;
      &amp;quot;https://cointelegraph.com/rss&amp;quot;,&lt;br /&gt;
      &amp;quot;https://chaski.huffpost.com/us/auto/vertical/us-news&amp;quot;&lt;br /&gt;
      # Add more RSS feed URLs here&lt;br /&gt;
    ]&lt;br /&gt;
&lt;br /&gt;
    data&lt;br /&gt;
    |&amp;gt; Enum.map(fn url -&amp;gt;&lt;br /&gt;
      case ElixirRss.fetch_and_parse(url) do&lt;br /&gt;
        {:ok, feed} -&amp;gt; feed.entries |&amp;gt; Enum.map(fn entry -&amp;gt; entry end)&lt;br /&gt;
        {:error, reason} -&amp;gt; {:error, reason}&lt;br /&gt;
      end&lt;br /&gt;
    end)&lt;br /&gt;
    |&amp;gt; Enum.map(fn entry_list -&amp;gt;&lt;br /&gt;
      entry_list&lt;br /&gt;
      |&amp;gt; Enum.map(fn entry -&amp;gt; entry.title end)&lt;br /&gt;
    end)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def hello do&lt;br /&gt;
    rss_feeds = [&lt;br /&gt;
      &amp;quot;https://cointelegraph.com/rss&amp;quot;,&lt;br /&gt;
      &amp;quot;https://chaski.huffpost.com/us/auto/vertical/us-news&amp;quot;&lt;br /&gt;
      # Add more RSS feed URLs here&lt;br /&gt;
    ]&lt;br /&gt;
&lt;br /&gt;
    rss_feeds&lt;br /&gt;
    |&amp;gt; Enum.map(fn url -&amp;gt;&lt;br /&gt;
      case ElixirRss.fetch_and_parse(url) do&lt;br /&gt;
        {:ok, feed} -&amp;gt; feed.entries |&amp;gt; Enum.map(fn entry -&amp;gt; entry end)&lt;br /&gt;
        {:error, reason} -&amp;gt; {:error, reason}&lt;br /&gt;
      end&lt;br /&gt;
    end)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    if connected?(socket) do&lt;br /&gt;
      Phoenix.PubSub.subscribe(App.PubSub, &amp;quot;message&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
    {:ok, assign(socket, message_item: &amp;quot;different&amp;quot;)}&lt;br /&gt;
  end&lt;br /&gt;
  def handle_info({:pubsub_transmission, text}, socket) do&lt;br /&gt;
    IO.inspect &amp;quot;pub sub working&amp;quot;&lt;br /&gt;
    {:noreply, assign(socket, message_item: text)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def loop(data) do&lt;br /&gt;
     IO.inspect data&lt;br /&gt;
     if data &amp;gt; 0 do&lt;br /&gt;
      IO.inspect &amp;quot;notify&amp;quot;&lt;br /&gt;
      # run code to compare files, loop. If different run pubsub code below&lt;br /&gt;
      :timer.sleep(2000)&lt;br /&gt;
      loop(data-1)&lt;br /&gt;
&lt;br /&gt;
     end&lt;br /&gt;
     if data &amp;lt;= 0 do&lt;br /&gt;
&lt;br /&gt;
      Phoenix.PubSub.broadcast(App.PubSub, &amp;quot;message&amp;quot;, {:pubsub_transmission, &amp;quot;data&amp;quot;})&lt;br /&gt;
      &amp;quot;done&amp;quot;&lt;br /&gt;
     end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;change-text&amp;quot;, _params, socket) do&lt;br /&gt;
    spawn(fn -&amp;gt; loop(3) end)&lt;br /&gt;
    {:noreply, assign(socket, message_item: &amp;quot;START&amp;quot; )}&lt;br /&gt;
  end&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
&lt;br /&gt;
    # AppWeb.PageLive.loop(&amp;quot;xxx&amp;quot;)&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    SANDBOX&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;.button phx-click=&amp;quot;change-text&amp;quot; value={@message_item}&amp;gt;CLICK ME&amp;lt;/.button&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;%= @message_item %&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
elixir :   1.16.2&lt;br /&gt;
&lt;br /&gt;
Erl:   20&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# PostGres&lt;br /&gt;
Created Saturday 18 February 2023&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Launch [PostGres](#PostGres) from Terminal&lt;br /&gt;
------------------------------------------&lt;br /&gt;
sudo -u postgres psql&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Set User Permission&lt;br /&gt;
-------------------&lt;br /&gt;
&amp;lt;https://commandprompt.com/education/how-to-create-a-superuser-in-postgresql/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ALTER USER user_name WITH PASSWORD 'new_password';&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Run Post Gres Commands&lt;br /&gt;
----------------------&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
sudo -i -u postgres&lt;br /&gt;
psql&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Create and Delete Database&lt;br /&gt;
&lt;br /&gt;
CREATE DATABASE name;&lt;br /&gt;
DROP DATABASE name;&lt;br /&gt;
## View user list&lt;br /&gt;
&lt;br /&gt;
\du&lt;br /&gt;
&lt;br /&gt;
 View all databases&lt;br /&gt;
&lt;br /&gt;
postgres=# \l&lt;br /&gt;
&lt;br /&gt;
 Change databases&lt;br /&gt;
&lt;br /&gt;
postgres=# \c    name-of-database&lt;br /&gt;
&lt;br /&gt;
View Tables&lt;br /&gt;
&lt;br /&gt;
After you change databases and are selected on one of them do this:&lt;br /&gt;
&lt;br /&gt;
\dt&lt;br /&gt;
&lt;br /&gt;
SELECT * FROM mytablename;&lt;br /&gt;
&lt;br /&gt;
EMPTY TABLE&lt;br /&gt;
DELETE FROM name-of-table&lt;br /&gt;
&lt;br /&gt;
CREATE TABLE&lt;br /&gt;
&lt;br /&gt;
CREATE TABLE table_name(&lt;br /&gt;
   column1 datatype,&lt;br /&gt;
   column2 datatype,&lt;br /&gt;
   column3 datatype,&lt;br /&gt;
   .....&lt;br /&gt;
   columnN datatype,&lt;br /&gt;
   PRIMARY KEY( one or more columns )&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
INSERT&lt;br /&gt;
&lt;br /&gt;
INSERT INTO ITEMS(id, name) VALUES(1,'htvjbjbgni');     Strings are single quote&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Roadmap==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.ItemsLive do&lt;br /&gt;
    use AppWeb, :live_view  &lt;br /&gt;
    def mount(_params, _session, socket)  do&lt;br /&gt;
      {:ok, assign(socket, switches: [&amp;quot;grindy&amp;quot;,&amp;quot;sonic&amp;quot;,&amp;quot;ogre&amp;quot;])}  &lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    def handle_event(&amp;quot;run&amp;quot;,_params,socket) do  &lt;br /&gt;
        &lt;br /&gt;
        IO.inspect &amp;quot;DOWNLOAD VIA SSH&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        {:noreply, redirect(socket, to: &amp;quot;/download&amp;quot;)}&lt;br /&gt;
&lt;br /&gt;
    end&lt;br /&gt;
   &lt;br /&gt;
&lt;br /&gt;
    def render(assigns) do&lt;br /&gt;
        &lt;br /&gt;
        ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        &amp;lt;ul&amp;gt;&lt;br /&gt;
        &amp;lt;%= for switch &amp;lt;- @switches do %&amp;gt;&lt;br /&gt;
         &amp;lt;a phx-submit=&amp;quot;click&amp;quot; href=&amp;quot;/download&amp;quot;&amp;gt;  &amp;lt;li&amp;gt; &amp;lt;%= switch %&amp;gt;  &amp;lt;/li&amp;gt; &amp;lt;/a&amp;gt;&lt;br /&gt;
&lt;br /&gt;
        &amp;lt;%end%&amp;gt;&lt;br /&gt;
        &amp;lt;/ul&amp;gt;&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot; &lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Notes==&lt;br /&gt;
List of Switches and the option to select the one needed.&lt;br /&gt;
Button to download JSON file.&lt;br /&gt;
Drag and Drop Palette to upload JSON file.&lt;br /&gt;
&lt;br /&gt;
After JSON file is uploaded a button titled &amp;quot;Make Active&amp;quot; is available.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://medium.com/@fraiha26/pushing-events-to-livecomponents-from-js-hooks-w-phoenix-elixir-d5544d4c3dfa&lt;br /&gt;
&lt;br /&gt;
Changeset notes and forms&lt;br /&gt;
&lt;br /&gt;
NOTE: Use case statements for pattern matching&lt;br /&gt;
____________________________________________&lt;br /&gt;
&lt;br /&gt;
Create a basic &amp;lt;.form&amp;gt;&amp;lt;/form&amp;gt; without error handling&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&amp;lt;.form :let={f} for={@changeset}  action={~p&amp;quot;/items&amp;quot;} &amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;.input field={f[:title]} type=&amp;quot;text&amp;quot; label=&amp;quot;Title&amp;quot; /&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
  &amp;lt;.button&amp;gt;Save Item&amp;lt;/.button&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;/.form&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With error handling looks like this:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;.form :let={f} for={@changeset}  action={~p&amp;quot;/items&amp;quot;} &amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;.error :if={@changeset.action}&amp;gt;&lt;br /&gt;
    Oops, something went wrong! Please check the errors below.&lt;br /&gt;
  &amp;lt;/.error&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;.input field={f[:title]} type=&amp;quot;text&amp;quot; label=&amp;quot;Title&amp;quot; /&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
  &amp;lt;.button&amp;gt;Save Item&amp;lt;/.button&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;/.form&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Create the routes for render and post to endpoint.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The controller for the page render needs to pass in the changeset via ```Items.change_item(%Item{})```&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  def new(conn, _params) do&lt;br /&gt;
    changeset = Items.change_item(%Item{})&lt;br /&gt;
    render(conn, :new, changeset: changeset)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Post route without error handling&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  def create(conn, %{&amp;quot;item&amp;quot; =&amp;gt; item_params}) do&lt;br /&gt;
    case Items.create_item(item_params) do&lt;br /&gt;
      {:ok, item} -&amp;gt;&lt;br /&gt;
        conn&lt;br /&gt;
        |&amp;gt; put_flash(:info, &amp;quot;Item created successfully.&amp;quot;)&lt;br /&gt;
        |&amp;gt; redirect(to: ~p&amp;quot;/items/#{item}&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With error handling&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  def create(conn, %{&amp;quot;item&amp;quot; =&amp;gt; item_params}) do&lt;br /&gt;
    case Items.create_item(item_params) do&lt;br /&gt;
      {:ok, item} -&amp;gt;&lt;br /&gt;
        conn&lt;br /&gt;
        |&amp;gt; put_flash(:info, &amp;quot;Item created successfully.&amp;quot;)&lt;br /&gt;
        |&amp;gt; redirect(to: ~p&amp;quot;/items/#{item}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
      {:error, %Ecto.Changeset{} = changeset} -&amp;gt;&lt;br /&gt;
        render(conn, :new, changeset: changeset)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_____________________________________________&lt;br /&gt;
https://medium.com/@vincentlin/phoenix-very-simple-form-c4b121697fcb&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''home.html.heex'''&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&amp;lt;form action=&amp;quot;/submit&amp;quot; method=&amp;quot;post&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;label for=&amp;quot;name&amp;quot;&amp;gt;Name:&amp;lt;/label&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;input type=&amp;quot;text&amp;quot; id=&amp;quot;name&amp;quot; name=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;_csrf_token&amp;quot; value={@csrf_token} /&amp;gt;&lt;br /&gt;
  &amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Submit&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
page_controller.ex&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.PageController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  def home(conn, _params) do&lt;br /&gt;
    # The home page is often custom made,&lt;br /&gt;
&lt;br /&gt;
    csrf_token = Plug.CSRFProtection.get_csrf_token()&lt;br /&gt;
    render(conn, :home, csrf_token: csrf_token)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def submit(conn, _params) do&lt;br /&gt;
    # The home page is often custom made,&lt;br /&gt;
     IO.inspect(_params)&lt;br /&gt;
     IO.inspect &amp;quot;___________________________&amp;quot;&lt;br /&gt;
    csrf_token = Plug.CSRFProtection.get_csrf_token()&lt;br /&gt;
    render(conn, :home, csrf_token: csrf_token)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
router.ex&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  scope &amp;quot;/&amp;quot;, AppWeb do&lt;br /&gt;
    pipe_through :browser&lt;br /&gt;
    post &amp;quot;/submit&amp;quot;, PageController, :submit&lt;br /&gt;
    get &amp;quot;/&amp;quot;, PageController, :home&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ecto.Adapters.SQL.query(Repo, &amp;quot;select * from artists where id=1&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ecto cheatsheet:  https://hexdocs.pm/ecto/crud.html&lt;br /&gt;
__________________________________________________________________&lt;br /&gt;
Most programming languages give you the ability to set global state by creating globally scoped variables. Elixir does not do this. Instead, Elixir provides a tool called a &amp;quot;processes&amp;quot; to persist  state. Elixir applications are composed of these &amp;quot;processes&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
Processes by themselves are complicated to use, thus Elixir provides abstractions to make working with processes easier. One of these abstractions is called a GenServer.&lt;br /&gt;
&lt;br /&gt;
GenServers are not only used to store state, they are also used to invoke work independent of the main application process. &lt;br /&gt;
&lt;br /&gt;
==Creating a GenServer to Store State==&lt;br /&gt;
&lt;br /&gt;
To Create a GenServer, start by creating a basic Module that ''uses'' the GenServer module (image below)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule App do  &lt;br /&gt;
  use GenServer&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We now need to describe the actions we want to perform. Being that this is used to store state, we will use basic CRUD actions: Create, Read, Update, Delete. To begins, empty functions describing each action is created.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule App do&lt;br /&gt;
   def create do &lt;br /&gt;
&lt;br /&gt;
   end&lt;br /&gt;
   def read do &lt;br /&gt;
&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
   def update do  &lt;br /&gt;
&lt;br /&gt;
   end &lt;br /&gt;
&lt;br /&gt;
   def delete do &lt;br /&gt;
&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==What now?==&lt;br /&gt;
&lt;br /&gt;
To fill in the functions with the appropriate code we must first have a basic understanding of how GenServers are structured.&lt;br /&gt;
&lt;br /&gt;
GenServers are composed of the GenServer module invoking callbacks. The callbacks have built in names that you, as a developer have to use.&lt;br /&gt;
&lt;br /&gt;
These callbacks are named:&lt;br /&gt;
&lt;br /&gt;
* init&lt;br /&gt;
* handle_cast&lt;br /&gt;
* handle_call&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To demonstrate, here is an example :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{:ok, pid} = GenServer.start(ModuleNameOfGenServer, %{})&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above function named &amp;quot;start&amp;quot; calls the function named init in the Module below.&lt;br /&gt;
In GenServer syntax the name of the GenServer functions always invoke callbacks that are determined by the language. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule ModuleNameOfGenServer do&lt;br /&gt;
  # 1&lt;br /&gt;
  def init(state \\ %{}) do&lt;br /&gt;
    {:ok, state}&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is a list of the GenServer functions and their corresponding callbacks.&lt;br /&gt;
&lt;br /&gt;
* GenServer.start/1  --&amp;gt;       init/1&lt;br /&gt;
* GenServer.call/3   --&amp;gt;       def handle_call/3&lt;br /&gt;
* GenServer.cast/2   --&amp;gt;       handle_cast/2&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Start and Call ==&lt;br /&gt;
&lt;br /&gt;
Call and Cast can be used to perform the same operations. The &lt;br /&gt;
&lt;br /&gt;
__________________________________________________________&lt;br /&gt;
Genserver timed events&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule Go do&lt;br /&gt;
  use GenServer&lt;br /&gt;
&lt;br /&gt;
  def go() do&lt;br /&gt;
    GenServer.start_link(__MODULE__, [])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def init(list) do&lt;br /&gt;
    :timer.apply_interval(1000, __MODULE__, :add, [self(), &amp;quot;weeeee&amp;quot;])&lt;br /&gt;
    {:ok, list}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def view(pid) do&lt;br /&gt;
    GenServer.call(pid, :view)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_call(:view, _from, list) do&lt;br /&gt;
    {:reply, list, list}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def add(pid, new_item) do&lt;br /&gt;
    GenServer.call(pid, {:item, new_item})&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_call({:item, new_item}, _from, state) do&lt;br /&gt;
    result = [new_item] ++ state&lt;br /&gt;
    {:reply, result, result}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule ShoppingList do&lt;br /&gt;
  use GenServer&lt;br /&gt;
&lt;br /&gt;
  def start_link() do&lt;br /&gt;
    GenServer.start_link(ShoppingList, [])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def init(list) do&lt;br /&gt;
    {:ok, list}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def view(pid) do&lt;br /&gt;
    GenServer.call(pid, :view)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_call(:view, _from, list) do&lt;br /&gt;
    {:reply, list, list}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def add(pid, new_item) do&lt;br /&gt;
    GenServer.call(pid, {:item, new_item})&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_call({:item, new_item}, _from, state) do&lt;br /&gt;
    result = [new_item] ++ state&lt;br /&gt;
    {:reply, result, result}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://blog.appsignal.com/2018/06/12/elixir-alchemy-deconstructing-genservers.html&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule KeyValue do&lt;br /&gt;
  # 1&lt;br /&gt;
  def init(state \\ %{}) do&lt;br /&gt;
    {:ok, state}&lt;br /&gt;
  end&lt;br /&gt;
 &lt;br /&gt;
  # 2&lt;br /&gt;
  def handle_cast({:put, key, value}, state) do&lt;br /&gt;
    {:noreply, Map.put(state, key, value)}&lt;br /&gt;
  end&lt;br /&gt;
 &lt;br /&gt;
  # 3&lt;br /&gt;
  def handle_call({:get, key}, _from, state) do&lt;br /&gt;
    {:reply, Map.fetch!(state, key), state}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
# {:ok, pid} = GenServer.start(KeyValue, %{})&lt;br /&gt;
# GenServer.cast(pid, {:put, :foo, &amp;quot;bar&amp;quot;})&lt;br /&gt;
# GenServer.call(pid, {:get, :foo})&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Send messages via these functions wrapped in module functions .You can look at these are functions used to fire &amp;quot;GenServer Events&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
* start_link&lt;br /&gt;
* GenServer.call&lt;br /&gt;
* GenServer.cast&lt;br /&gt;
&lt;br /&gt;
The corresponding server functions that reply are:&lt;br /&gt;
&lt;br /&gt;
* init&lt;br /&gt;
* handle__call&lt;br /&gt;
* handle_cast&lt;br /&gt;
* &lt;br /&gt;
&lt;br /&gt;
These can be looked at as &amp;quot;listeners&amp;quot; - in JavaScript parlance. &lt;br /&gt;
__________________________________________&lt;br /&gt;
&lt;br /&gt;
If you have experience with programming languages other than Elixir the idea of GenServers may be very foreign and require a strong context shift to learn. This document is intended to simplify the concept.&lt;br /&gt;
&lt;br /&gt;
* What: GenServers are simply a way to hold state and/or invoke actions based on incoming events. &lt;br /&gt;
* when &lt;br /&gt;
* where&lt;br /&gt;
* why&lt;br /&gt;
* how&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
___________________________________________&lt;br /&gt;
GenServer timer example&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule Timer do&lt;br /&gt;
  use GenServer&lt;br /&gt;
&lt;br /&gt;
  def init(_) do&lt;br /&gt;
    :timer.send_interval(1000, :xyz)&lt;br /&gt;
    {:ok, 0}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_info(:xyz, state) do&lt;br /&gt;
    IO.inspect(state)&lt;br /&gt;
    {:noreply, state + 1}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
[&lt;br /&gt;
   {&lt;br /&gt;
     data:{&lt;br /&gt;
        creationTime,&lt;br /&gt;
        publishDate,&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
     featured:{&lt;br /&gt;
        setAmount,&lt;br /&gt;
        items:[]&lt;br /&gt;
     },&lt;br /&gt;
&lt;br /&gt;
     children:{&lt;br /&gt;
        setAmount,&lt;br /&gt;
        items:[]&lt;br /&gt;
     },&lt;br /&gt;
     links:{&lt;br /&gt;
        setAmount,&lt;br /&gt;
        items:[]&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
jason.encode / jason.decode&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  def run(num) do&lt;br /&gt;
&lt;br /&gt;
    Enum.each(0..99999, fn(_x) -&amp;gt;&lt;br /&gt;
      task = Task.async(fn -&amp;gt; num + _x end)&lt;br /&gt;
    IO.inspect Task.await(task)&lt;br /&gt;
  end)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enum.map(feed.entries, fn x -&amp;gt; %{url: x.url, title: x.title} end)&lt;br /&gt;
&lt;br /&gt;
App is split:&lt;br /&gt;
&lt;br /&gt;
App that captures RSS in UI and lets admin select stories. THere are settings to determine the number of FEATURED,CHILD and LINK stories.&lt;br /&gt;
News categories are horizontal and scrollable.&lt;br /&gt;
This exports a json doc with all RSS data for each story.&lt;br /&gt;
The &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
App that reads the json data. This app creates tables and is the front end.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://stephenbussey.com/tags/elixir.html&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule AppWeb.GroupLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  alias App.TestBeds&lt;br /&gt;
  alias App.Groups&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    {:ok, assign(socket, testbeds: TestBeds.list_testbeds(), groups: Groups.list_groups())}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;select-group&amp;quot;, params, socket)  do  &lt;br /&gt;
     group = App.Groups.get_group!(params[&amp;quot;group-id&amp;quot;])&lt;br /&gt;
     testbed = App.TestBeds.get_test_bed!(params[&amp;quot;testbed_id&amp;quot;])&lt;br /&gt;
     App.TestBeds.update_test_bed(testbed, %{group_id: group.id})&lt;br /&gt;
     {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def updated_groups(testbed_id)  do  &lt;br /&gt;
     testbed = App.TestBeds.get_test_bed!(testbed_id)&lt;br /&gt;
     groups = App.Groups.list_groups&lt;br /&gt;
     tail = Enum.filter(groups, fn(item)-&amp;gt; item.id !== testbed.group_id end)&lt;br /&gt;
     head = Enum.filter(groups, fn(item)-&amp;gt; item.id == testbed.group_id end)&lt;br /&gt;
            |&amp;gt;Enum.at(0)&lt;br /&gt;
    [head | tail]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        &amp;lt;%= for testbed &amp;lt;- Enum.sort_by(@testbeds , &amp;amp;(&amp;quot;#{&amp;amp;1.name}&amp;quot;), :asc)do %&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;grid grid-cols-4 gap-4 p-8 rounded shadow bg-white&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;h2&amp;gt; Name&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;%= testbed.name %&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;h2&amp;gt; Group&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div&amp;gt;&lt;br /&gt;
            &amp;lt;form phx-change=&amp;quot;select-group&amp;quot; name=&amp;quot;testbed_id&amp;quot;  &amp;gt;&lt;br /&gt;
               &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;testbed_id&amp;quot; value={testbed.id}/&amp;gt;&lt;br /&gt;
               &amp;lt;select id=&amp;quot;group-selection&amp;quot;  name=&amp;quot;group-id&amp;quot; class=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;%= for group &amp;lt;- updated_groups(testbed.id) do %&amp;gt;&lt;br /&gt;
                  &amp;lt;%= if group !== nil do %&amp;gt;&lt;br /&gt;
                      &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}&amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
                      &amp;lt;%else%&amp;gt;&lt;br /&gt;
                      &amp;lt;option value= {&amp;quot;Unassigned&amp;quot;}&amp;gt;NONE&amp;lt;/option&amp;gt;&lt;br /&gt;
                  &amp;lt;% end %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
               &amp;lt;/select&amp;gt;&lt;br /&gt;
            &amp;lt;/form&amp;gt;&lt;br /&gt;
          &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
       &amp;lt;% end %&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Developer Notes ==&lt;br /&gt;
===Groups Feature ===&lt;br /&gt;
To complete this feature do these things.&lt;br /&gt;
* Run through the steps in [http://elixirblocks.com/index.php?title=Create_Foreign_Key_Relationship_Between_Ecto_Tables  | this document] to create Group table.&lt;br /&gt;
* Groups have these fields  '''name: string''', '''description: string''' and '''color: string'''  &lt;br /&gt;
* Add unique constraint in migration file: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def change do&lt;br /&gt;
     create unique_index(:groups, [:name])&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Port over Group LiveView code (temporarily placed at discussion page).&lt;br /&gt;
* On completion '''possibly''', create a Group named '''No Group''' and set all Testbeds to it.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
________&lt;br /&gt;
https://blog.appsignal.com/2022/10/11/phoenix-liveview-018-new-special-html-attributes.html&lt;br /&gt;
https://blixtdev.com/whats-new-phoenix-1-7/&lt;br /&gt;
https://github.com/devato/inertia_phoenix&lt;br /&gt;
https://phoenixonrails.com/blog/you-can-stop-using-form-for-in-phoenix&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://samuelmullen.com/articles/phoenix_templates_rendering_and_layouts&lt;br /&gt;
&lt;br /&gt;
WorkFlow of Todo App in Both LiveView and DeadView.&lt;br /&gt;
&lt;br /&gt;
Note:&lt;br /&gt;
&lt;br /&gt;
Create foreign key data.&lt;br /&gt;
Create live view. List all testbeds and form to assign each a group by group-name.&lt;br /&gt;
&lt;br /&gt;
Repeat in dead view&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Mental model and data flows&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
home.html.heex&lt;br /&gt;
&amp;lt;a href=&amp;quot;/data&amp;quot; name=&amp;quot;we are the world&amp;quot; &amp;gt;  click me&amp;lt;/a&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;%= @message %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
page controller&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  def home(conn, _params) do&lt;br /&gt;
    IO.inspect _params&lt;br /&gt;
    render(conn, :home, message: &amp;quot;Hello&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
get &amp;quot;/:yay&amp;quot;, PageController, :index&lt;br /&gt;
&lt;br /&gt;
get &amp;quot;/&amp;quot;, PageController, :index&lt;br /&gt;
&lt;br /&gt;
* Explain control flow of &amp;quot;Dead Views&amp;quot; and the Generator HTML Control flow.&lt;br /&gt;
* Proper Way to use Modal&lt;br /&gt;
* How to give Focus to Fields in Modal (or other forms fields)&lt;br /&gt;
* &lt;br /&gt;
* &lt;br /&gt;
* How to Create Database Seed Data.&lt;br /&gt;
* How to structure code so controller code is in one file and HTML Heex is in another&lt;br /&gt;
* How to Use Generators in a Real World Project&lt;br /&gt;
* How to Work with Database Data via Basic Commands and Custom Change sets.&lt;br /&gt;
* How to Render Database Data to LiveView (via Context Commands).&lt;br /&gt;
* How to Create a Chat using PubSub.&lt;br /&gt;
* How to Create Event Handlers in LiveView&lt;br /&gt;
* How to Create a Dynamic Route from Scratch.&lt;br /&gt;
* How to Use Elixirs Template language&lt;br /&gt;
* How to Work with Modal&lt;br /&gt;
* How to Use CSS From Scratch (Without bundler)&lt;br /&gt;
* How to use JS hooks&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
______________________&lt;br /&gt;
https://studioindie.co/blog/heex-guide/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
get &amp;quot;/&amp;quot;, PageController, :some-atom    #This is the route. some-atom is the controller name&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  def some-atom(conn, _params) do                 # controller name&lt;br /&gt;
    # The home page is often custom made,&lt;br /&gt;
    # so skip the default app layout.&lt;br /&gt;
    render(conn, :some-atom, layout: false)      # :some-atom is template name&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Controllers page_html.ex contains &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageHTML do&lt;br /&gt;
  use AppWeb, :html&lt;br /&gt;
&lt;br /&gt;
  embed_templates &amp;quot;page_html/*&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''page_html''' is the name of the folder in '''Controllers/page_html'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Controllers/page_html/some-atom.html.heex  (this is the template) &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__________________________________________&lt;br /&gt;
Set all association with preload:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  def list_groups do&lt;br /&gt;
    Repo.all(Group)&lt;br /&gt;
     |&amp;gt; Repo.preload([:testbeds])&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Insert Child into Parent ===&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
App.get_group!(2) # arg is id&lt;br /&gt;
|&amp;gt; Ecto.build_assoc(:testbeds)&lt;br /&gt;
|&amp;gt; Repo.insert()&lt;br /&gt;
&lt;br /&gt;
Or&lt;br /&gt;
&lt;br /&gt;
group = App.get_group!(2) # arg is id&lt;br /&gt;
&lt;br /&gt;
testbeds = Ecto.build_assoc(group, :testbeds)&lt;br /&gt;
&lt;br /&gt;
App.Group.create_group(testbeds)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
group = App.Groups.get_group!(1)&lt;br /&gt;
thing = Ecto.build_assoc(group, :testbeds, name: &amp;quot;DUMB&amp;quot;)&lt;br /&gt;
alias App.{Repo}&lt;br /&gt;
Repo.insert(thing)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
avatar = %Avatar{nick_name: &amp;quot;Elixir&amp;quot;, pic_url: &amp;quot;http://elixir-lang.org/images/logo.png&amp;quot;}&lt;br /&gt;
user = %User{name: &amp;quot;John Doe&amp;quot;, email: &amp;quot;john.doe@example.com&amp;quot;, avatar: avatar}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://www.reddit.com/r/elixir/comments/oh318k/is_there_a_way_to_avoid_ectoassociationnotloaded/h4mmcfi/?utm_source=share&amp;amp;utm_medium=web3x&amp;amp;utm_name=web3xcss&amp;amp;utm_term=1&amp;amp;utm_content=share_button&lt;br /&gt;
&lt;br /&gt;
# Create Group Table&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
mix phx.gen.html Groups Group groups name:string  &lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Set the resources / &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
mix ecto.migrate&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For testbeds create a migration file and add this field:   group_id:references:groups&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
def change do&lt;br /&gt;
    alter table(:testbeds) do    # customize to your code&lt;br /&gt;
      add :group_id, references(:groups)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Update Groups Schema (Don't forget alias / has_many)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule App.Groups.Group do&lt;br /&gt;
	use Ecto.Schema&lt;br /&gt;
	import Ecto.Changeset&lt;br /&gt;
	alias App.Testbeds.Testbed   # Alias!&lt;br /&gt;
&lt;br /&gt;
	schema &amp;quot;posts&amp;quot; do&lt;br /&gt;
		field :body, :string&lt;br /&gt;
		field :title, :string&lt;br /&gt;
		has_many :testbeds, Testbed    # Has many&lt;br /&gt;
&lt;br /&gt;
		timestamps()&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	@doc false&lt;br /&gt;
	def changeset(post, attrs) do&lt;br /&gt;
		post&lt;br /&gt;
		|&amp;gt; cast(attrs, [:title, :body])&lt;br /&gt;
		|&amp;gt; validate_required([:title, :body])&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
TESTBEDS Schema&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule App.Testbeds.Testbed do&lt;br /&gt;
  use Ecto.Schema&lt;br /&gt;
  import Ecto.Changeset&lt;br /&gt;
  alias App.Groups.Group      # Alias&lt;br /&gt;
  schema &amp;quot;testbeds&amp;quot; do&lt;br /&gt;
    field :name, :string&lt;br /&gt;
    belongs_to :group, Group    # Belongs to&lt;br /&gt;
    timestamps()&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  @doc false&lt;br /&gt;
  def changeset(testbed, attrs) do&lt;br /&gt;
    testbed&lt;br /&gt;
    |&amp;gt; cast(attrs, [:name])&lt;br /&gt;
    |&amp;gt; validate_required([:name])&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
_____________________________________&lt;br /&gt;
Side notes.&lt;br /&gt;
&lt;br /&gt;
defmodule App.Repo.Migrations.CreateTestbeds do&lt;br /&gt;
  use Ecto.Migration&lt;br /&gt;
&lt;br /&gt;
  def change do&lt;br /&gt;
    create table(:testbeds) do&lt;br /&gt;
      add :name, :string&lt;br /&gt;
      add :group_id, references(:groups, on_delete: :nothing)&lt;br /&gt;
&lt;br /&gt;
      timestamps()&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    create index(:testbeds, [:group_id])&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
________________________________&lt;br /&gt;
&lt;br /&gt;
mix phx.gen.context Comments Comment comments name:string content:text post_id:references:posts&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
mix phx.gen.html Testbeds Testbed testbeds name:string  group_id:references:groups&lt;br /&gt;
&lt;br /&gt;
https://graffino.com/web-development/first-steps-in-elixir-and-phoenix-create-a-blog-prototype&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://blog.logrocket.com/getting-started-ecto-phoenix/&lt;br /&gt;
&lt;br /&gt;
https://serokell.io/blog/ecto-guide-for-beginners&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
mix phx.gen.html Testbeds Testbed testbeds name:string&lt;br /&gt;
&lt;br /&gt;
mix phx.gen.html Groups Group groups name:string&lt;br /&gt;
&lt;br /&gt;
Create migration for &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
mix ecto.gen.migration add_testbed_group_reference&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Migration:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  def change do&lt;br /&gt;
    alter table(:testbeds) do    # customize to your code&lt;br /&gt;
      add :group_id, references(:groups)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Manually Change:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule App.Group do&lt;br /&gt;
  use Ecto.Schema&lt;br /&gt;
&lt;br /&gt;
  schema &amp;quot;groups&amp;quot; do&lt;br /&gt;
    field :title, :string&lt;br /&gt;
    field :tagline, :string&lt;br /&gt;
    has_many :testbeds, App.Testbed&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
testbeds&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule App.Repo.Migrations.AddTextbedGroups do&lt;br /&gt;
  use Ecto.Migration&lt;br /&gt;
&lt;br /&gt;
  def change do&lt;br /&gt;
    create table(:testbeds) do&lt;br /&gt;
      add :name, :string&lt;br /&gt;
      add :group_id, references(:groups)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
# lib/app/testbeds.ex&lt;br /&gt;
&lt;br /&gt;
defmodule App.Testbed do&lt;br /&gt;
  use Ecto.Schema&lt;br /&gt;
&lt;br /&gt;
  schema &amp;quot;testbedss&amp;quot; do&lt;br /&gt;
    field :name, :string&lt;br /&gt;
    belongs_to :group, App.Group&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_____________________&lt;br /&gt;
&lt;br /&gt;
%App.TestBeds.TestBed{&lt;br /&gt;
  __meta__: #Ecto.Schema.Metadata&amp;lt;:loaded, &amp;quot;testbeds&amp;quot;&amp;gt;,&lt;br /&gt;
  id: 1,&lt;br /&gt;
  developer: &amp;quot;None&amp;quot;,&lt;br /&gt;
  name: &amp;quot;sdfsd&amp;quot;,&lt;br /&gt;
  owner: &amp;quot;sdfsddf&amp;quot;,&lt;br /&gt;
  note: &amp;quot;sdsfsddf&amp;quot;,&lt;br /&gt;
  status: &amp;quot;Available&amp;quot;,&lt;br /&gt;
  url: &amp;quot;sdf&amp;quot;,&lt;br /&gt;
  version: &amp;quot;ddf&amp;quot;,&lt;br /&gt;
  manager: &amp;quot;sf&amp;quot;,&lt;br /&gt;
  inserted_at: ~N[2023-08-21 13:45:39],&lt;br /&gt;
  updated_at: ~N[2023-08-21 13:45:44]&lt;br /&gt;
}&lt;br /&gt;
________________________________________________________________---&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.SendLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  &lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    {:ok, socket}&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  def handle_event(&amp;quot;send&amp;quot;, %{&amp;quot;text&amp;quot; =&amp;gt; text}, socket) do&lt;br /&gt;
&lt;br /&gt;
    AppWeb.Endpoint.broadcast(topic, &amp;quot;message&amp;quot;, text)&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  defp topic do&lt;br /&gt;
    &amp;quot;chat&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def render(assigns)do   &lt;br /&gt;
   ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
  &amp;lt;h1&amp;gt;Send Message&amp;lt;/h1&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;form phx-submit=&amp;quot;send&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;text&amp;quot; /&amp;gt;&lt;br /&gt;
    &amp;lt;button type=&amp;quot;submit&amp;quot;&amp;gt;Send&amp;lt;/button&amp;gt;&lt;br /&gt;
  &amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
______________________________________________________________&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.ReceiveLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  &lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    if connected?(socket) do&lt;br /&gt;
      AppWeb.Endpoint.subscribe(topic)&lt;br /&gt;
    end&lt;br /&gt;
    {:ok, assign(socket, messages: &amp;quot;&amp;quot;)}&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def handle_info(%{event: &amp;quot;message&amp;quot;, payload: message}, socket) do&lt;br /&gt;
    IO.inspect message&lt;br /&gt;
    {:noreply, assign(socket, messages: message)}&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  defp topic do&lt;br /&gt;
    &amp;quot;chat&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns)do   &lt;br /&gt;
   ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
  &amp;lt;h1&amp;gt;ChatLive&amp;lt;/h1&amp;gt;&lt;br /&gt;
  &amp;lt;%= @messages %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
______________________________________________________________&lt;br /&gt;
When you hover over a list of items this hook finds items with the same name and sets the opacity of all others to 0. You see all the items similar to the one you are hovering over.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
TestbedVersionHover: {&lt;br /&gt;
			// https://jsfiddle.net/IrvinDominin/7K2Z3/&lt;br /&gt;
            mounted() {&lt;br /&gt;
&lt;br /&gt;
                let rows = document.getElementsByClassName(&amp;quot;testbed-version&amp;quot;)&lt;br /&gt;
                // this.ele = element&lt;br /&gt;
				// rows = this.ele;&lt;br /&gt;
                &lt;br /&gt;
				for (var i = 0; i &amp;lt; rows.length; i++) {&lt;br /&gt;
					rows[i].onmouseenter = function (event) {&lt;br /&gt;
						for (var j = 0; j &amp;lt; rows.length; j++) {&lt;br /&gt;
							let preversion = this.textContent;&lt;br /&gt;
							let version = preversion.slice(0,5)&lt;br /&gt;
							let compareVersion = rows[j].textContent.slice(0,5)&lt;br /&gt;
							if (compareVersion === version) continue&lt;br /&gt;
							rows[j].className += &amp;quot; other&amp;quot;;&lt;br /&gt;
						}&lt;br /&gt;
					};&lt;br /&gt;
				&lt;br /&gt;
					rows[i].onmouseleave = function (event) {&lt;br /&gt;
						var hovers = document.getElementsByClassName('other');&lt;br /&gt;
						var len = hovers.length;&lt;br /&gt;
						for (var j = 0; j &amp;lt; len; j++) {&lt;br /&gt;
							hovers[0].className = hovers[0].className.replace(/\sother(\s|$)/, '');&lt;br /&gt;
						}&lt;br /&gt;
					};&lt;br /&gt;
				}&lt;br /&gt;
&lt;br /&gt;
                // this.ele.addEventListener(&amp;quot;click&amp;quot;, (e) =&amp;gt; {&lt;br /&gt;
                //     console.log(e.target)&lt;br /&gt;
                    &lt;br /&gt;
                // });&lt;br /&gt;
&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* How to Create Database Seed Data.&lt;br /&gt;
* How to structure code so controller code is in one file and HTML Heex is in another&lt;br /&gt;
* How to Use Generators in a Real World Project&lt;br /&gt;
* How to Work with Database Data via Basic Commands and Custom Change sets.&lt;br /&gt;
* How to Render Database Data to LiveView (via Context Commands).&lt;br /&gt;
* How to Create a Chat using PubSub.&lt;br /&gt;
* How to Create Event Handlers in LiveView&lt;br /&gt;
* How to Create a Dynamic Route from Scratch.&lt;br /&gt;
* How to Use Elixirs Template language&lt;br /&gt;
* How to Work with Modal&lt;br /&gt;
* How to Use CSS From Scratch (Without bundler)&lt;br /&gt;
* How to use JS hooks&lt;br /&gt;
* Dissect Table Component and Update it to Order List in Reverse.&lt;br /&gt;
&lt;br /&gt;
Selenium&lt;br /&gt;
https://www.builder.io/blog/debug-nodejs&lt;br /&gt;
&lt;br /&gt;
https://marketplace.visualstudio.com/items?itemName=ms-vscode.live-server#running-the-extension&lt;br /&gt;
&lt;br /&gt;
This was added recently (see microsoft/vscode#109276).&lt;br /&gt;
    1. Open the palette (Ctrl + Shift + P)&lt;br /&gt;
    2. Select &amp;quot;Simple Browser: Preview&amp;quot;&lt;br /&gt;
    3. Enter web address&lt;br /&gt;
&lt;br /&gt;
_______________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
const {By, Key, Builder} = require(&amp;quot;selenium-webdriver&amp;quot;);&lt;br /&gt;
const assert = require(&amp;quot;assert&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
require(&amp;quot;chromedriver&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
async function test_case(){&lt;br /&gt;
  let driver = await new Builder().forBrowser(&amp;quot;chrome&amp;quot;).build();&lt;br /&gt;
  await driver.get(&amp;quot;sie&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  await driver.findElement(By.name('password')).clear();&lt;br /&gt;
  await driver.findElement(By.name('identification')).clear();&lt;br /&gt;
  await driver.findElement(By.name('identification')).sendKeys(&amp;quot;bill&amp;quot;);&lt;br /&gt;
  await driver.findElement(By.name('password')).sendKeys(&amp;quot;password&amp;quot;, Key.RETURN);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 setTimeout(()=&amp;gt;{&lt;br /&gt;
   driver.findElement(By.className(&amp;quot;req_lan_license&amp;quot;)).click();&lt;br /&gt;
 },5000)&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageLive do &lt;br /&gt;
&lt;br /&gt;
  use AppWeb, :live_view  &lt;br /&gt;
  alias App.Testbeds &lt;br /&gt;
  def mount(_params, _session, socket)do   &lt;br /&gt;
     {:ok, assign(socket, testbeds: Testbeds.list_testbeds())}   &lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
    def button_event(&amp;quot;invoke_editing&amp;quot;) do&lt;br /&gt;
    %JS{}&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;active&amp;quot;, to: &amp;quot;#editing_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#editing_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#preview_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;active&amp;quot;, to: &amp;quot;#preview_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;active&amp;quot;, to: &amp;quot;#preview&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#preview&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#editing&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;active&amp;quot;, to: &amp;quot;#editing&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def button_event(&amp;quot;invoke_preview&amp;quot;) do&lt;br /&gt;
    %JS{}&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;active&amp;quot;, to: &amp;quot;#preview_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#preview_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#editing_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;active&amp;quot;, to: &amp;quot;#editing_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;active&amp;quot;, to: &amp;quot;#editing&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#editing&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#preview&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;active&amp;quot;, to: &amp;quot;#preview&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;send&amp;quot;, params, socket) do&lt;br /&gt;
    hide_modal(&amp;quot;notes-modal-0&amp;quot;)&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do  &lt;br /&gt;
     ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
		&amp;lt;.modal id={&amp;quot;notes-modal-#{testbed.id}&amp;quot;}&amp;gt;&lt;br /&gt;
		    &amp;lt;.button phx-click={button_event(&amp;quot;invoke_editing&amp;quot;)} id=&amp;quot;editing_button&amp;quot; class=&amp;quot;hidden&amp;quot;&amp;gt;&lt;br /&gt;
		      Preview&lt;br /&gt;
		    &amp;lt;/.button&amp;gt;&lt;br /&gt;
		    &amp;lt;.button phx-click={button_event(&amp;quot;invoke_preview&amp;quot;)} id=&amp;quot;preview_button&amp;quot;&amp;gt;&lt;br /&gt;
		      Edit Me&lt;br /&gt;
		    &amp;lt;/.button&amp;gt;&lt;br /&gt;
		    &amp;lt;div id=&amp;quot;editing&amp;quot;&amp;gt; PREVIEWING THE WORK&amp;lt;/div&amp;gt;&lt;br /&gt;
		    &amp;lt;form phx-submit = &amp;quot;send&amp;quot;   id=&amp;quot;preview&amp;quot; class=&amp;quot;hidden&amp;quot;&amp;gt;&lt;br /&gt;
		      &amp;lt;textarea value = {testbed.note}&amp;gt;&amp;lt;/textarea&amp;gt;&lt;br /&gt;
		      &amp;lt;.button type=&amp;quot;submit&amp;quot; phx-click={hide_modal(&amp;quot;notes-modal-#{testbed.id}&amp;quot;)}&amp;gt;SAVE WORK&amp;lt;/.button&amp;gt;&lt;br /&gt;
		    &amp;lt;/form&amp;gt;&lt;br /&gt;
		&amp;lt;/.modal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;%= if testbed.note do %&amp;gt;&lt;br /&gt;
      &amp;lt;div phx-click={show_modal(&amp;quot;notes-modal-#{testbed.id}&amp;quot;)}&amp;gt;READ ME  ...&amp;lt;%= testbed.note %&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
	   &lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
       &lt;br /&gt;
      &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
import {HfInference} from &amp;quot;@huggingface/inference&amp;quot;;&lt;br /&gt;
import dotenv from &amp;quot;dotenv&amp;quot;;&lt;br /&gt;
dotenv.config()&lt;br /&gt;
&lt;br /&gt;
const HF_ACCESS_TOKEN = process.env.HF_ACCESS_TOKEN&lt;br /&gt;
&lt;br /&gt;
const hf = new HfInference(HF_ACCESS_TOKEN);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*______Uncomment for this example______________________&lt;br /&gt;
&lt;br /&gt;
const model = &amp;quot;nlpconnect/vit-gpt2-image-captioning&amp;quot;;&lt;br /&gt;
const imageURL = &amp;quot;https://i.imgur.com/lTvb7Et.png&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
const response = await fetch(imageURL);&lt;br /&gt;
const imageBlob = await response.blob();&lt;br /&gt;
&lt;br /&gt;
const result  = await hf.imageToText({&lt;br /&gt;
	data: imageBlob,&lt;br /&gt;
	model: model,&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
_______________________________________________________*/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*________Another example ___________________*/&lt;br /&gt;
&lt;br /&gt;
const result = await hf.summarization({&lt;br /&gt;
	model: 'facebook/bart-large-cnn',&lt;br /&gt;
	inputs: &amp;quot;The role of a dumb man is to get smarter oogy bookie boo&amp;quot;,&lt;br /&gt;
	parameters:{&lt;br /&gt;
		max_length: 100&lt;br /&gt;
	}&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
console.log(result);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
________________________________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://fly.io/phoenix-files/sdeb-toggling-element/&lt;br /&gt;
https://www.youtube.com/watch?v=vBgZvQapqhs&lt;br /&gt;
&lt;br /&gt;
https://blog.testdouble.com/posts/2022-11-28-how-to-use-javascript-with-phoenix-liveview/&lt;br /&gt;
&lt;br /&gt;
https://hexdocs.pm/phoenix_live_view/0.19.3/Phoenix.Component.html&lt;br /&gt;
_______________________________________&lt;br /&gt;
https://www.smashingmagazine.com/2011/10/quick-look-math-animations-javascript/&lt;br /&gt;
* Depth first traversal&lt;br /&gt;
* Breadth first traversal&lt;br /&gt;
&lt;br /&gt;
https://dev.to/codesphere/10-algorithms-every-developer-should-learn-3lnm&lt;br /&gt;
&lt;br /&gt;
https://www.youtube.com/watch?v=fPz40W9mfCg&lt;br /&gt;
&lt;br /&gt;
__________________________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.GroupLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  alias App.TestBeds&lt;br /&gt;
  alias App.Groups&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    {:ok, assign(socket, testbeds: TestBeds.list_testbeds(), groups: Groups.list_groups())}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;select-group&amp;quot;, params, socket)  do  &lt;br /&gt;
         &lt;br /&gt;
       IO.inspect params&lt;br /&gt;
       {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div class=&amp;quot;grid grid-columns-2 grid-flow-col gap-4&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;column-1&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;%= testbed.name %&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;column-2&amp;quot;&amp;gt;    &lt;br /&gt;
            &amp;lt;form phx-change=&amp;quot;select-group&amp;quot;  &amp;gt;&lt;br /&gt;
               &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;testbed_id&amp;quot; value={testbed.id}/&amp;gt;&lt;br /&gt;
               &amp;lt;select id=&amp;quot;group-selection&amp;quot;  name=&amp;quot;group-id&amp;quot; &amp;gt;&lt;br /&gt;
                &amp;lt;%= for group &amp;lt;- @groups do %&amp;gt;&lt;br /&gt;
                  &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}  &amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
               &amp;lt;/select&amp;gt;&lt;br /&gt;
            &amp;lt;/form&amp;gt;&lt;br /&gt;
         &amp;lt;/div&amp;gt;&lt;br /&gt;
       &amp;lt;% end %&amp;gt;&lt;br /&gt;
   &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
____________________________&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.GroupLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  alias App.TestBeds&lt;br /&gt;
  alias App.Groups&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
&lt;br /&gt;
    {:ok, assign(socket, testbeds: TestBeds.list_testbeds(), groups: Groups.list_groups(), messages: [])}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;select-group&amp;quot;, params, socket)  do  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
      group = App.Groups.get_group!(params[&amp;quot;group-id&amp;quot;])&lt;br /&gt;
       # IO.inspect group&lt;br /&gt;
       testbed = App.TestBeds.get_test_bed!(params[&amp;quot;testbed_id&amp;quot;])&lt;br /&gt;
     &lt;br /&gt;
       App.TestBeds.update_test_bed(testbed, %{group_id: group.id})&lt;br /&gt;
         &lt;br /&gt;
    &lt;br /&gt;
       {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def updated_groups(testbed_id)  do  &lt;br /&gt;
       groups = App.Groups.list_groups&lt;br /&gt;
       tail = Enum.filter(groups, fn(item)-&amp;gt; item.id !== testbed_id end)&lt;br /&gt;
       head = Enum.filter(groups, fn(item)-&amp;gt; item.id == testbed_id end)&lt;br /&gt;
              |&amp;gt;Enum.at(0)&lt;br /&gt;
     [head | tail]&lt;br /&gt;
         &lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
 # def handle_event(&amp;quot;groups&amp;quot;, params, socket)do  &lt;br /&gt;
 #       selected_testbed = %{name: &amp;quot;my testbed name&amp;quot;, id: 3}&lt;br /&gt;
 #       groups = App.Groups.list_groups&lt;br /&gt;
 #       tail = Enum.filter(groups, fn(item)-&amp;gt; item.id !== selected_testbed.id end)&lt;br /&gt;
 #       head = Enum.filter(groups, fn(item)-&amp;gt; item.id == selected_testbed.id end)&lt;br /&gt;
 #              |&amp;gt;Enum.at(0)&lt;br /&gt;
         &lt;br /&gt;
 &lt;br /&gt;
 #       # result = Enum.filter([1, 2, 3], fn x -&amp;gt; x.id !== 1 end)&lt;br /&gt;
 #      IO.inspect [head | tail]&lt;br /&gt;
         &lt;br /&gt;
 #      #&lt;br /&gt;
 #      {:noreply, socket, assigns.message:}&lt;br /&gt;
 #  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    &lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
       &amp;lt;%!-- &amp;lt;div phx-click = &amp;quot;groups&amp;quot;&amp;gt;CLICK ME&amp;lt;/div&amp;gt; --%&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;grid grid-cols-4 gap-4 p-8 rounded shadow bg-white&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;h2&amp;gt; Name&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;%= testbed.name %&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;h2&amp;gt; Group&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;form phx-change=&amp;quot;select-group&amp;quot; name=&amp;quot;testbed_id&amp;quot;  &amp;gt;&lt;br /&gt;
               &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;testbed_id&amp;quot; value={testbed.id}/&amp;gt;&lt;br /&gt;
               &amp;lt;select id=&amp;quot;group-selection&amp;quot;  name=&amp;quot;group-id&amp;quot; class=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
                &amp;lt;%= for group &amp;lt;- updated_groups(testbed.id) do %&amp;gt;&lt;br /&gt;
                  &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}  &amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
                  &amp;lt;!-- Write code to reorder with testbed.group_id matching group_id --&amp;gt;&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
               &amp;lt;/select&amp;gt;&lt;br /&gt;
            &amp;lt;/form&amp;gt;&lt;br /&gt;
          &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
       &amp;lt;% end %&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_____________________________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
   use AppWeb, :live_view  &lt;br /&gt;
     alias App.Testbeds&lt;br /&gt;
  alias App.Groups&lt;br /&gt;
   def mount(_params, _session, socket)  do&lt;br /&gt;
	     {:ok, assign(socket, testbeds: Testbeds.list_testbeds(), groups: Groups.list_groups())}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
   def handle_event(&amp;quot;select-group&amp;quot;, params, socket)  do  &lt;br /&gt;
       group = App.Groups.get_group!(params[&amp;quot;group-id&amp;quot;])&lt;br /&gt;
       testbed = App.Testbeds.get_testbed!(params[&amp;quot;testbed_id&amp;quot;])&lt;br /&gt;
       result = App.Testbeds.update_testbed(testbed, %{group_id: group.id})&lt;br /&gt;
       IO.inspect result&lt;br /&gt;
      &lt;br /&gt;
       {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
    def updated_groups(testbed_id)  do  &lt;br /&gt;
       testbed = App.Testbeds.get_testbed!(testbed_id)&lt;br /&gt;
       groups = App.Groups.list_groups&lt;br /&gt;
       tail = Enum.filter(groups, fn(item)-&amp;gt; item.id !== testbed.group_id end)&lt;br /&gt;
       head = Enum.filter(groups, fn(item)-&amp;gt; item.id == testbed.group_id end)&lt;br /&gt;
              |&amp;gt;Enum.at(0)&lt;br /&gt;
 &lt;br /&gt;
       [head | tail]&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    &lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;grid grid-cols-4 gap-4 p-8 rounded shadow bg-white&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;h2&amp;gt; Name&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;%= testbed.name %&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;h2&amp;gt; Group&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;form phx-change=&amp;quot;select-group&amp;quot; name=&amp;quot;testbed_id&amp;quot;  &amp;gt;&lt;br /&gt;
               &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;testbed_id&amp;quot; value={testbed.id}/&amp;gt;&lt;br /&gt;
               &amp;lt;select id=&amp;quot;group-selection&amp;quot;  name=&amp;quot;group-id&amp;quot; class=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
                &amp;lt;%= for group &amp;lt;- updated_groups(testbed.id) do %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
                  &amp;lt;%!-- &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}&amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt; --%&amp;gt;&lt;br /&gt;
                  &amp;lt;!-- Write code to reorder with testbed.group_id matching group_id --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
                  &amp;lt;%= if group !== nil do %&amp;gt;&lt;br /&gt;
                      &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}&amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
       &lt;br /&gt;
                  &amp;lt;% end %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
               &amp;lt;/select&amp;gt;&lt;br /&gt;
            &amp;lt;/form&amp;gt;&lt;br /&gt;
          &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
       &amp;lt;% end %&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  has_many :testbeds, TestBed, on_delete: :restrict   # Has many&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://elixirforum.com/t/ecto-has-many-on-delete-protect/49550&lt;br /&gt;
&lt;br /&gt;
https://hexdocs.pm/ecto/Ecto.Changeset.html#unique_constraint/3&lt;br /&gt;
&lt;br /&gt;
____________________________________________________________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== How to Create a Mix Project and Use It in Another Mix Project ==&lt;br /&gt;
&lt;br /&gt;
To create and use a **Mix project** inside another **Mix project** in Elixir, follow the steps below:&lt;br /&gt;
&lt;br /&gt;
=== 1. Create a New Mix Project ===&lt;br /&gt;
&lt;br /&gt;
First, you need to create a new Mix project. Let's call this project `library_project`. Run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mix new library_project --module LibraryProject&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will create a new Elixir Mix project named `library_project`. The `--module` flag specifies the name of the module that will be created (in this case `LibraryProject`).&lt;br /&gt;
&lt;br /&gt;
The directory structure of `library_project` will look like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
library_project/&lt;br /&gt;
  |_ lib/&lt;br /&gt;
      |_ library_project.ex&lt;br /&gt;
  |_ mix.exs&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can then add some basic functionality inside the `library_project/lib/library_project.ex` file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule LibraryProject do&lt;br /&gt;
  def hello do&lt;br /&gt;
    IO.puts &amp;quot;Hello from LibraryProject!&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now, `library_project` is ready to be used by another Mix project.&lt;br /&gt;
&lt;br /&gt;
=== 2. Create a Second Mix Project ===&lt;br /&gt;
&lt;br /&gt;
Next, create the second Mix project where you want to use `library_project`. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mix new app_project --module AppProject&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will create another Elixir project called `app_project`.&lt;br /&gt;
&lt;br /&gt;
The directory structure for this project will look like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
app_project/&lt;br /&gt;
  |_ lib/&lt;br /&gt;
      |_ app_project.ex&lt;br /&gt;
  |_ mix.exs&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 3. Add `library_project` as a Dependency in `app_project` ===&lt;br /&gt;
&lt;br /&gt;
Now, you want to make `library_project` available in `app_project`. There are two main ways to do this:&lt;br /&gt;
&lt;br /&gt;
==== Option 1: Local Dependency (via `path`) ====&lt;br /&gt;
&lt;br /&gt;
If `library_project` is a local project (i.e., it's stored in a different directory), you can add it to the `mix.exs` of `app_project` as a local dependency by specifying the path to `library_project`.&lt;br /&gt;
&lt;br /&gt;
Edit the `mix.exs` of `app_project`:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule AppProject.MixProject do&lt;br /&gt;
  use Mix.Project&lt;br /&gt;
&lt;br /&gt;
  def project do&lt;br /&gt;
    [&lt;br /&gt;
      app: :app_project,&lt;br /&gt;
      version: &amp;quot;0.1.0&amp;quot;,&lt;br /&gt;
      elixir: &amp;quot;~&amp;gt; 1.14&amp;quot;,&lt;br /&gt;
      start_permanent: Mix.env() == :prod,&lt;br /&gt;
      deps: deps()&lt;br /&gt;
    ]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  defp deps do&lt;br /&gt;
    [&lt;br /&gt;
      {:library_project, path: &amp;quot;../library_project&amp;quot;}  # Add the local dependency&lt;br /&gt;
    ]&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here, `{:library_project, path: &amp;quot;../library_project&amp;quot;}` tells Mix to use the local `library_project` located in the `../library_project` directory (relative to `app_project`).&lt;br /&gt;
&lt;br /&gt;
After updating the `mix.exs`, run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd app_project&lt;br /&gt;
mix deps.get&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will fetch the dependency and compile `library_project`.&lt;br /&gt;
&lt;br /&gt;
==== Option 2: Publish and Fetch as a Hex Package ====&lt;br /&gt;
&lt;br /&gt;
If you want to use `library_project` as a package in another project (for example, by publishing it to **Hex.pm**, Elixir’s package manager), you need to publish it to Hex and then add it as a dependency.&lt;br /&gt;
&lt;br /&gt;
1. Publish `library_project` to Hex (if it's public or for your private use).&lt;br /&gt;
2. Add `library_project` to your `app_project`’s `mix.exs` dependencies:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defp deps do&lt;br /&gt;
  [&lt;br /&gt;
    {:library_project, &amp;quot;~&amp;gt; 0.1.0&amp;quot;}  # Specify the published version from Hex&lt;br /&gt;
  ]&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Run `mix deps.get` to fetch the package from Hex.&lt;br /&gt;
&lt;br /&gt;
=== 4. Use `library_project` in `app_project` ===&lt;br /&gt;
&lt;br /&gt;
Now, you can use the functionality from `library_project` inside your `app_project`. For example, in `app_project/lib/app_project.ex`, you can call the function from `library_project`:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule AppProject do&lt;br /&gt;
  def start do&lt;br /&gt;
    IO.puts &amp;quot;Starting app_project!&amp;quot;&lt;br /&gt;
    LibraryProject.hello()  # Call the function from the library_project&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 5. Run the App ===&lt;br /&gt;
&lt;br /&gt;
Finally, you can run your `app_project`:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd app_project&lt;br /&gt;
mix run -e &amp;quot;AppProject.start()&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will print:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Starting app_project!&lt;br /&gt;
Hello from LibraryProject!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Recap of the Process ==&lt;br /&gt;
1. **Create the `library_project`**: Use `mix new` to generate a library project.&lt;br /&gt;
2. **Create the `app_project`**: Create the second project where you will use the library.&lt;br /&gt;
3. **Add the `library_project` as a dependency**:&lt;br /&gt;
   - Use the `path` option to point to the local project or publish it to Hex for public access.&lt;br /&gt;
4. **Use the `library_project` in the `app_project`**: Call functions or use modules from the library inside the second project.&lt;br /&gt;
5. **Run the app**: Use `mix run` to execute the project.&lt;br /&gt;
&lt;br /&gt;
This way, you can reuse code from one Mix project in another by adding it as a dependency.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==z==&lt;br /&gt;
Overloaded functions are extremely common in Elixir applications. They are&lt;br /&gt;
regularly used for recursive functions and for changing behavior based on&lt;br /&gt;
configuration.&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>http://elixirblocks.com/index.php?title=LiveView_Web_API_Request_Example&amp;diff=1905</id>
		<title>LiveView Web API Request Example</title>
		<link rel="alternate" type="text/html" href="http://elixirblocks.com/index.php?title=LiveView_Web_API_Request_Example&amp;diff=1905"/>
		<updated>2025-05-10T07:00:43Z</updated>

		<summary type="html">&lt;p&gt;Admin: Created page with &amp;quot;&amp;lt;source&amp;gt; defmodule AppWeb.Sandbox do   use AppWeb, :live_view    def mount(_params, _session, socket) do     {:ok, socket}   end    def handle_event(&amp;quot;start_task&amp;quot;, _params, socket) do     Task.async(fn -&amp;gt; Req.get!(&amp;quot;https://api.github.com/repos/wojtekmach/req&amp;quot;) end)     {:noreply, socket}   end    def handle_info({ref, result}, socket) do     Process.demonitor(ref, [:flush])     IO.inspect&amp;quot;________________________________________________________________________________&amp;quot;...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.Sandbox do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    {:ok, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;start_task&amp;quot;, _params, socket) do&lt;br /&gt;
    Task.async(fn -&amp;gt; Req.get!(&amp;quot;https://api.github.com/repos/wojtekmach/req&amp;quot;) end)&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_info({ref, result}, socket) do&lt;br /&gt;
    Process.demonitor(ref, [:flush])&lt;br /&gt;
    IO.inspect&amp;quot;________________________________________________________________________________&amp;quot;&lt;br /&gt;
    IO.inspect({:task_result_received, ref, result})&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    &amp;lt;div&amp;gt;&lt;br /&gt;
      &amp;lt;button phx-click=&amp;quot;start_task&amp;quot;&amp;gt;Start Task&amp;lt;/button&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Barebones&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>http://elixirblocks.com/index.php?title=Phoenix_Handle_Info_Self_Example&amp;diff=1904</id>
		<title>Phoenix Handle Info Self Example</title>
		<link rel="alternate" type="text/html" href="http://elixirblocks.com/index.php?title=Phoenix_Handle_Info_Self_Example&amp;diff=1904"/>
		<updated>2025-05-10T05:15:31Z</updated>

		<summary type="html">&lt;p&gt;Admin: Created page with &amp;quot;&amp;lt;source&amp;gt; defmodule AppWeb.Sandbox do   use AppWeb, :live_view   require Logger    def mount(_params, _session, socket) do     {:ok, assign(socket, :count, 0)}   end    def handle_event(&amp;quot;increment&amp;quot;, _params, socket) do     # Send a message to ourselves after 1000 milliseconds (1 second)     Process.send_after(self(), :delayed_increment, 1000)     {:noreply, socket}   end    def handle_info(:delayed_increment, socket) do     new_count = socket.assigns.count + 1     Logger....&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.Sandbox do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  require Logger&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    {:ok, assign(socket, :count, 0)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;increment&amp;quot;, _params, socket) do&lt;br /&gt;
    # Send a message to ourselves after 1000 milliseconds (1 second)&lt;br /&gt;
    Process.send_after(self(), :delayed_increment, 1000)&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_info(:delayed_increment, socket) do&lt;br /&gt;
    new_count = socket.assigns.count + 1&lt;br /&gt;
    Logger.info(&amp;quot;Incrementing count to: #{new_count}&amp;quot;)&lt;br /&gt;
    {:noreply, assign(socket, :count, new_count)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    &amp;lt;div&amp;gt;&lt;br /&gt;
      &amp;lt;h2&amp;gt;Delayed Counter&amp;lt;/h2&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Count: &amp;lt;%= @count %&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;button phx-click=&amp;quot;increment&amp;quot;&amp;gt;Increment After Delay&amp;lt;/button&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>http://elixirblocks.com/index.php?title=Sort_Collection_Via_Event_Handler&amp;diff=1903</id>
		<title>Sort Collection Via Event Handler</title>
		<link rel="alternate" type="text/html" href="http://elixirblocks.com/index.php?title=Sort_Collection_Via_Event_Handler&amp;diff=1903"/>
		<updated>2025-04-17T20:17:14Z</updated>

		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.SandboxLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  alias App.TestBeds&lt;br /&gt;
  alias App.TestBeds.TestBed&lt;br /&gt;
  alias App.Repo&lt;br /&gt;
  import Ecto.Query&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
&lt;br /&gt;
    testbeds = Repo.all(from(t in TestBed, order_by: t.name))&lt;br /&gt;
    {:ok, assign(socket, testbeds: testbeds, sort_by: :name, sort_direction: :asc)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;toggle_sort_by_name&amp;quot;, _params, socket) do&lt;br /&gt;
&lt;br /&gt;
    current_direction = socket.assigns.sort_direction&lt;br /&gt;
&lt;br /&gt;
    new_direction = case current_direction do&lt;br /&gt;
      :asc -&amp;gt; :desc&lt;br /&gt;
      :desc -&amp;gt; :asc&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    # Build query based on sort direction&lt;br /&gt;
    query = case new_direction do&lt;br /&gt;
      :asc -&amp;gt; from(t in TestBed, order_by: t.name)&lt;br /&gt;
      :desc -&amp;gt; from(t in TestBed, order_by: [desc: t.name])&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    testbeds = Repo.all(query)&lt;br /&gt;
&lt;br /&gt;
    {:noreply, assign(socket, testbeds: testbeds, sort_by: :name, sort_direction: new_direction)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;div&amp;gt;&lt;br /&gt;
      &amp;lt;!-- Name header with click to toggle sort --&amp;gt;&lt;br /&gt;
      &amp;lt;button phx-click=&amp;quot;toggle_sort_by_name&amp;quot;&amp;gt;&lt;br /&gt;
        Sort by Name&lt;br /&gt;
        &amp;lt;%= if @sort_by == :name do %&amp;gt;&lt;br /&gt;
          &amp;lt;%= if @sort_direction == :asc do %&amp;gt;&lt;br /&gt;
            ▲&lt;br /&gt;
          &amp;lt;% else %&amp;gt;&lt;br /&gt;
            ▼&lt;br /&gt;
          &amp;lt;% end %&amp;gt;&lt;br /&gt;
        &amp;lt;% end %&amp;gt;&lt;br /&gt;
      &amp;lt;/button&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;ul&amp;gt;&lt;br /&gt;
      &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
        &amp;lt;li&amp;gt;&amp;lt;%= testbed.name %&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;% end %&amp;gt;&lt;br /&gt;
    &amp;lt;/ul&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>http://elixirblocks.com/index.php?title=Sort_Collection_Via_Event_Handler&amp;diff=1902</id>
		<title>Sort Collection Via Event Handler</title>
		<link rel="alternate" type="text/html" href="http://elixirblocks.com/index.php?title=Sort_Collection_Via_Event_Handler&amp;diff=1902"/>
		<updated>2025-04-17T19:55:06Z</updated>

		<summary type="html">&lt;p&gt;Admin: Created page with &amp;quot;&amp;lt;source&amp;gt;  defmodule AppWeb.SandboxLive do   use AppWeb, :live_view   alias App.TestBeds   alias App.TestBeds.TestBed   alias App.Repo   import Ecto.Query    def mount(_params, _session, socket) do      testbeds = Repo.all(from(t in TestBed, order_by: t.name))     {:ok, assign(socket, testbeds: testbeds, sort_by: :name, sort_direction: :asc)}   end    def handle_event(&amp;quot;toggle_sort_by_name&amp;quot;, _params, socket) do     current_direction = socket.assigns.sort_direction     new_...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.SandboxLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  alias App.TestBeds&lt;br /&gt;
  alias App.TestBeds.TestBed&lt;br /&gt;
  alias App.Repo&lt;br /&gt;
  import Ecto.Query&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
&lt;br /&gt;
    testbeds = Repo.all(from(t in TestBed, order_by: t.name))&lt;br /&gt;
    {:ok, assign(socket, testbeds: testbeds, sort_by: :name, sort_direction: :asc)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;toggle_sort_by_name&amp;quot;, _params, socket) do&lt;br /&gt;
    current_direction = socket.assigns.sort_direction&lt;br /&gt;
    new_direction = if current_direction == :asc, do: :desc, else: :asc&lt;br /&gt;
&lt;br /&gt;
    # Build query based on sort direction&lt;br /&gt;
    query = case new_direction do&lt;br /&gt;
      :asc -&amp;gt; from(t in TestBed, order_by: t.name)&lt;br /&gt;
      :desc -&amp;gt; from(t in TestBed, order_by: [desc: t.name])&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    testbeds = Repo.all(query)&lt;br /&gt;
&lt;br /&gt;
    {:noreply, assign(socket, testbeds: testbeds, sort_by: :name, sort_direction: new_direction)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;div&amp;gt;&lt;br /&gt;
      &amp;lt;!-- Name header with click to toggle sort --&amp;gt;&lt;br /&gt;
      &amp;lt;button phx-click=&amp;quot;toggle_sort_by_name&amp;quot;&amp;gt;&lt;br /&gt;
        Sort by Name&lt;br /&gt;
        &amp;lt;%= if @sort_by == :name do %&amp;gt;&lt;br /&gt;
          &amp;lt;%= if @sort_direction == :asc do %&amp;gt;&lt;br /&gt;
            ▲&lt;br /&gt;
          &amp;lt;% else %&amp;gt;&lt;br /&gt;
            ▼&lt;br /&gt;
          &amp;lt;% end %&amp;gt;&lt;br /&gt;
        &amp;lt;% end %&amp;gt;&lt;br /&gt;
      &amp;lt;/button&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;ul&amp;gt;&lt;br /&gt;
      &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
        &amp;lt;li&amp;gt;&amp;lt;%= testbed.name %&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;% end %&amp;gt;&lt;br /&gt;
    &amp;lt;/ul&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>http://elixirblocks.com/index.php?title=Live_View_Store_Data_in_URL_Params&amp;diff=1901</id>
		<title>Live View Store Data in URL Params</title>
		<link rel="alternate" type="text/html" href="http://elixirblocks.com/index.php?title=Live_View_Store_Data_in_URL_Params&amp;diff=1901"/>
		<updated>2025-04-16T15:24:45Z</updated>

		<summary type="html">&lt;p&gt;Admin: Created page with &amp;quot;&amp;lt;source&amp;gt; defmodule AppWeb.PageLive do   use AppWeb, :live_view    def mount(_params, _session, socket) do     {:ok, socket}   end    def handle_params(params, _uri, socket) do     count = String.to_integer(params[&amp;quot;count&amp;quot;] || &amp;quot;0&amp;quot;)     {:noreply, assign(socket, count: count)}   end    def handle_event(&amp;quot;increment&amp;quot;, _, socket) do     new_count = socket.assigns.count + 1     # Use ~p instead of Routes     {:noreply, push_patch(socket, to: ~p&amp;quot;/?count=#{new_count}&amp;quot;)}   end    d...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    {:ok, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_params(params, _uri, socket) do&lt;br /&gt;
    count = String.to_integer(params[&amp;quot;count&amp;quot;] || &amp;quot;0&amp;quot;)&lt;br /&gt;
    {:noreply, assign(socket, count: count)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;increment&amp;quot;, _, socket) do&lt;br /&gt;
    new_count = socket.assigns.count + 1&lt;br /&gt;
    # Use ~p instead of Routes&lt;br /&gt;
    {:noreply, push_patch(socket, to: ~p&amp;quot;/?count=#{new_count}&amp;quot;)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;decrement&amp;quot;, _, socket) do&lt;br /&gt;
    new_count = max(0, socket.assigns.count - 1)&lt;br /&gt;
    # Use ~p instead of Routes&lt;br /&gt;
    {:noreply, push_patch(socket, to: ~p&amp;quot;/?count=#{new_count}&amp;quot;)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    &amp;lt;div&amp;gt;&lt;br /&gt;
      &amp;lt;h1&amp;gt;Count: &amp;lt;%= @count %&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;
      &amp;lt;button phx-click=&amp;quot;decrement&amp;quot;&amp;gt;-&amp;lt;/button&amp;gt;&lt;br /&gt;
      &amp;lt;button phx-click=&amp;quot;increment&amp;quot;&amp;gt;+&amp;lt;/button&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>http://elixirblocks.com/index.php?title=How_to_Create_Nested_LiveView_Components&amp;diff=1900</id>
		<title>How to Create Nested LiveView Components</title>
		<link rel="alternate" type="text/html" href="http://elixirblocks.com/index.php?title=How_to_Create_Nested_LiveView_Components&amp;diff=1900"/>
		<updated>2025-04-08T00:33:35Z</updated>

		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This example demonstrates a nested LiveView component.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppxWeb.SandboxLive do&lt;br /&gt;
   use AppxWeb, :live_view  &lt;br /&gt;
   import MyComponent&lt;br /&gt;
   def mount(_params, _session, socket)  do&lt;br /&gt;
	 {:ok, socket}  &lt;br /&gt;
   end&lt;br /&gt;
   def render(assigns) do&lt;br /&gt;
	   ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
	      Hello World! YAY&lt;br /&gt;
	     &amp;lt;MyComponent.greet name=&amp;quot;Jane&amp;quot; /&amp;gt;&lt;br /&gt;
	   &amp;quot;&amp;quot;&amp;quot; &lt;br /&gt;
   end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule MyComponent do&lt;br /&gt;
   use Phoenix.Component&lt;br /&gt;
&lt;br /&gt;
   def greet(assigns) do&lt;br /&gt;
	   ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
	     &amp;lt;p&amp;gt;Hello, &amp;lt;%= @name %&amp;gt;!&amp;lt;/p&amp;gt;&lt;br /&gt;
	   &amp;quot;&amp;quot;&amp;quot; &lt;br /&gt;
   end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
An Example of a Button&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    socket = assign(socket, count: 0)&lt;br /&gt;
    {:ok, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
      # Event handler in the parent LiveView&lt;br /&gt;
  def handle_event(&amp;quot;increment&amp;quot;, _params, socket) do&lt;br /&gt;
       {:noreply, assign(socket, count: socket.assigns.count + 1)}&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    &amp;lt;div class=&amp;quot;container mx-auto p-4&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;h1 class=&amp;quot;text-xl font-bold mb-4&amp;quot;&amp;gt;Counter with Button Component&amp;lt;/h1&amp;gt;&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;div class=&amp;quot;mb-4&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;p&amp;gt;Current count: &amp;lt;span class=&amp;quot;font-bold&amp;quot;&amp;gt;&amp;lt;%= @count %&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;.simple_button on_click=&amp;quot;increment&amp;quot;&amp;gt;&lt;br /&gt;
        Increment Counter&lt;br /&gt;
      &amp;lt;/.simple_button&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#_________________________________________________________BUTTON&lt;br /&gt;
&lt;br /&gt;
  # Simplified button component &lt;br /&gt;
  def simple_button(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
      &amp;lt;button class=&amp;quot;btn btn-lg&amp;quot;    phx-click={@on_click} &amp;gt;    &lt;br /&gt;
      &amp;lt;%= render_slot(@inner_block) %&amp;gt;&lt;br /&gt;
      &amp;lt;/button&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
#___________________________________________________________END BUTTON&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>http://elixirblocks.com/index.php?title=User:Admin&amp;diff=1899</id>
		<title>User:Admin</title>
		<link rel="alternate" type="text/html" href="http://elixirblocks.com/index.php?title=User:Admin&amp;diff=1899"/>
		<updated>2025-04-02T20:42:17Z</updated>

		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.Sandbox do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    {:ok, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;start_task&amp;quot;, _params, socket) do&lt;br /&gt;
    Task.async(fn -&amp;gt; :hello_from_task end)&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_info({ref, result}, socket) do&lt;br /&gt;
    IO.inspect&amp;quot;________________________________________________________________________________&amp;quot;&lt;br /&gt;
    IO.inspect({:task_result_received, ref, result})&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_info(msg, socket) do&lt;br /&gt;
    # Optionally log or inspect the unhandled message if you're curious&lt;br /&gt;
    # IO.inspect({:unhandled_info, msg})&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    &amp;lt;div&amp;gt;&lt;br /&gt;
      &amp;lt;button phx-click=&amp;quot;start_task&amp;quot;&amp;gt;Start Task&amp;lt;/button&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Barebones&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.Sandbox do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    {:ok, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;start_task&amp;quot;, _params, socket) do&lt;br /&gt;
    Task.async(fn -&amp;gt; :hello_from_task end)&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_info({ref, result}, socket) do&lt;br /&gt;
    IO.inspect&amp;quot;________________________________________________________________________________&amp;quot;&lt;br /&gt;
    IO.inspect({:task_result_received, ref, result})&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_info({:DOWN, ref, :process, pid, reason}, socket) do&lt;br /&gt;
    IO.inspect({:task_completed, ref, pid, reason})&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    &amp;lt;div&amp;gt;&lt;br /&gt;
      &amp;lt;button phx-click=&amp;quot;start_task&amp;quot;&amp;gt;Start Task&amp;lt;/button&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Barebones&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Async claude ai example&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Explain to me the relationship between handle_info and making an async call&lt;br /&gt;
&lt;br /&gt;
The relationship between handle_info and making async calls in Phoenix LiveView is fundamental to understanding how to handle non-blocking operations in your application.&lt;br /&gt;
&lt;br /&gt;
When you make an asynchronous call in Elixir (like using Task.async), you're creating a separate process that runs independently from your LiveView process. This allows your LiveView to remain responsive while potentially time-consuming operations (like API calls) are happening.&lt;br /&gt;
&lt;br /&gt;
Here's how they work together:&lt;br /&gt;
&lt;br /&gt;
Async Operation Initiation: When you start an async operation using Task.async, it returns a reference to the task.&lt;br /&gt;
Message Passing: When the async task completes, it automatically sends a message back to the process that created it. This message contains the task reference and the result: {ref, result}.&lt;br /&gt;
handle_info Reception: The handle_info/2 callback in LiveView is what receives these messages. It's like a mailbox for your LiveView process that handles any messages not related to LiveView events.&lt;br /&gt;
Process Cleanup: After receiving the result, you typically call Process.demonitor(ref, [:flush]) to clean up process monitoring and prevent receiving a :DOWN message when the task process exits.&lt;br /&gt;
This pattern creates a complete async lifecycle:&lt;br /&gt;
&lt;br /&gt;
Start async task →&lt;br /&gt;
Task runs independently →&lt;br /&gt;
Task completes and sends message →&lt;br /&gt;
handle_info receives message →&lt;br /&gt;
Update LiveView state&lt;br /&gt;
In the example I provided, there's a clear separation of concerns:&lt;br /&gt;
&lt;br /&gt;
Task.async(fn -&amp;gt; api() end) starts the async operation&lt;br /&gt;
handle_info({ref, result}, socket) receives and processes the result&lt;br /&gt;
The LiveView remains responsive throughout the entire operation&lt;br /&gt;
This pattern is what makes LiveView capable of handling concurrent operations while maintaining a responsive UI for users.&lt;br /&gt;
________________________&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.Sandbox do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    # Schedule the API call to happen after mount&lt;br /&gt;
    if connected?(socket), do: Process.send_after(self(), :fetch_data, 0)&lt;br /&gt;
    {:ok, assign(socket, data: nil)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_info(:fetch_data, socket) do&lt;br /&gt;
    # Launch API call in separate process&lt;br /&gt;
    Task.async(fn -&amp;gt; api() end)&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_info({ref, result}, socket) when is_reference(ref) do&lt;br /&gt;
    # Clean up the DOWN message&lt;br /&gt;
    Process.demonitor(ref, [:flush])&lt;br /&gt;
    {:noreply, assign(socket, data: result)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def api do&lt;br /&gt;
    Req.request(url: &amp;quot;https://api.github.com/repos/wojtekmach/req&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    SANDBOX&lt;br /&gt;
    &amp;lt;%= if @data, do: inspect(@data) %&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
___________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 defmodule Heading do&lt;br /&gt;
   use Phoenix.Component&lt;br /&gt;
   def head(assigns) do&lt;br /&gt;
	   ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	     &amp;lt;p&amp;gt;Hello, &amp;lt;%= @headings %&amp;gt;!&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	   &amp;quot;&amp;quot;&amp;quot; &lt;br /&gt;
   end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
   use AppWeb, :live_view  &lt;br /&gt;
   import Heading&lt;br /&gt;
   def mount(_params, _session, socket)  do&lt;br /&gt;
	 {:ok, socket}  &lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
   def headings do &lt;br /&gt;
    [&amp;quot;one&amp;quot;,&amp;quot;two&amp;quot;,&amp;quot;three&amp;quot;]&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
   def render(assigns) do&lt;br /&gt;
	   ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	     &amp;lt;Heading.head  headings={headings()} /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	   &amp;quot;&amp;quot;&amp;quot; &lt;br /&gt;
   end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://app.studyraid.com/en/read/11967/381872/component-communication&lt;br /&gt;
&lt;br /&gt;
https://thepugautomatic.com/2020/08/communicating-between-liveviews-on-the-same-page/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
from(a in Article,&lt;br /&gt;
  order_by: [desc: a.inserted_at],  # Assuming 'inserted_at' is the timestamp for when the article was created or updated&lt;br /&gt;
  limit: 8&lt;br /&gt;
)&lt;br /&gt;
|&amp;gt; Repo.all()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.Landing do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  alias App.Testbeds&lt;br /&gt;
  alias App.Testbeds.Testbed&lt;br /&gt;
  alias App.Repo  # Ensure to alias Repo&lt;br /&gt;
  import Ecto.Query  # Import Ecto.Query to work with queries&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    # Default to ordering by name&lt;br /&gt;
    testbeds = Repo.all(from(t in Testbed, order_by: t.name))&lt;br /&gt;
&lt;br /&gt;
    # Assign the testbeds to the socket for rendering&lt;br /&gt;
    {:ok, assign(socket, testbeds: testbeds, sort: :name)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    &amp;lt;h1&amp;gt;Hello World! YAY&amp;lt;/h1&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;div&amp;gt;&lt;br /&gt;
      &amp;lt;!-- Buttons to toggle sorting --&amp;gt;&lt;br /&gt;
      &amp;lt;button phx-click=&amp;quot;sort_by_name&amp;quot;&amp;gt;Sort by Name&amp;lt;/button&amp;gt;&lt;br /&gt;
      &amp;lt;button phx-click=&amp;quot;sort_by_updated_at&amp;quot;&amp;gt;Sort by Updated By&amp;lt;/button&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;ul&amp;gt;&lt;br /&gt;
      &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
        &amp;lt;li&amp;gt;&amp;lt;%= testbed.name %&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;% end %&amp;gt;&lt;br /&gt;
    &amp;lt;/ul&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;sort_by_name&amp;quot;, _params, socket) do&lt;br /&gt;
    testbeds = Repo.all(from(t in Testbed, order_by: t.name))&lt;br /&gt;
    {:noreply, assign(socket, testbeds: testbeds, sort: :name)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;sort_by_updated_at&amp;quot;, _params, socket) do&lt;br /&gt;
    testbeds = Repo.all(from(t in Testbed, order_by: t.inserted_at))&lt;br /&gt;
    {:noreply, assign(socket, testbeds: testbeds, sort: :inserted_at)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
_______________________________________________________&lt;br /&gt;
&lt;br /&gt;
* Create a form with a post request. &lt;br /&gt;
* Create the route needed for that request&lt;br /&gt;
* Create the controller needed for that route&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Form==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;.form action={~p&amp;quot;/todos&amp;quot;} method=&amp;quot;post&amp;quot; class=&amp;quot;mt-10 space-y-8&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    &amp;lt;label for=&amp;quot;contact_name&amp;quot; class=&amp;quot;block text-sm font-semibold leading-6 text-zinc-800&amp;quot;&amp;gt;&lt;br /&gt;
      Name&lt;br /&gt;
    &amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;input&lt;br /&gt;
      id=&amp;quot;todo&amp;quot;&lt;br /&gt;
      type=&amp;quot;text&amp;quot;&lt;br /&gt;
      name=&amp;quot;todo&amp;quot;&lt;br /&gt;
      class=&amp;quot;mt-2 block w-full rounded-lg text-zinc-900 focus:ring-0 sm:text-sm sm:leading-6 border-zinc-300 focus:border-zinc-400&amp;quot;&lt;br /&gt;
    /&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;button&lt;br /&gt;
    type=&amp;quot;submit&amp;quot;&lt;br /&gt;
    class=&amp;quot;rounded-lg bg-zinc-900 hover:bg-zinc-700 py-2 px-3 text-sm font-semibold leading-6 text-white active:text-white/80&amp;quot;&lt;br /&gt;
  &amp;gt;&lt;br /&gt;
    Save Contact&lt;br /&gt;
  &amp;lt;/button&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/.form&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Controller==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# In your TodoController&lt;br /&gt;
defmodule AppWeb.TodoController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  # Action to handle the form submission (POST request)&lt;br /&gt;
  def create(conn, %{&amp;quot;todo&amp;quot; =&amp;gt; todo_name}) do&lt;br /&gt;
    # Here you can handle the form data (e.g., save it to the database)&lt;br /&gt;
    IO.puts(&amp;quot;Received Todo: #{todo_name}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    # For now, let's just redirect to the home page&lt;br /&gt;
    conn&lt;br /&gt;
    |&amp;gt; put_flash(:info, &amp;quot;Todo saved!&amp;quot;)&lt;br /&gt;
    |&amp;gt; redirect(to: &amp;quot;/&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
________________________________________________________&lt;br /&gt;
&lt;br /&gt;
# CRUD Forms&lt;br /&gt;
&lt;br /&gt;
To understand CRUD forms you will need to understand the following concepts. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Ecto Schema&lt;br /&gt;
* Ecto Context&lt;br /&gt;
* Form Basics&lt;br /&gt;
* form/1&lt;br /&gt;
* simple_form/1&lt;br /&gt;
* changesets&lt;br /&gt;
&lt;br /&gt;
We are not going to go in order. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The Context provides CRUD functions for the chosen data schema. Phoenix contexts define the interface through which other parts of the codebase can interact with the app layer.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_______________________&lt;br /&gt;
* Create routes&lt;br /&gt;
* create page with form (submit get request)&lt;br /&gt;
&lt;br /&gt;
(ecto schema, context, changesets)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_______________________________________________________&lt;br /&gt;
In that case, you really should switch it to prod mode. Instead of doing all that above with the &amp;quot;config/secret.exs&amp;quot; file, create the &amp;quot;.env&amp;quot; in the project root, then add DotenvParser.load_file(&amp;quot;.env&amp;quot;) to &amp;quot;config/runtime.exs&amp;quot; as the first line inside the if config_env() == :prod do. In the .env file, set the DATABASE_URL and SECRET_KEY_BASE. Then run it as MIX_ENV=prod mix phx.server.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def get_titles do&lt;br /&gt;
    urls = [&lt;br /&gt;
      &amp;quot;https://cointelegraph.com/rss&amp;quot;,&lt;br /&gt;
      &amp;quot;https://chaski.huffpost.com/us/auto/vertical/us-news&amp;quot;&lt;br /&gt;
      # Add more RSS feed URLs here&lt;br /&gt;
    ]&lt;br /&gt;
&lt;br /&gt;
    urls&lt;br /&gt;
    |&amp;gt; Enum.map(fn url -&amp;gt;&lt;br /&gt;
      with {:ok, feed} &amp;lt;- ElixirRss.fetch_and_parse(url) do&lt;br /&gt;
        Enum.map(feed.entries, &amp;amp; &amp;amp;1.title)&lt;br /&gt;
      else&lt;br /&gt;
        {:error, reason} -&amp;gt; {:error, reason}&lt;br /&gt;
      end&lt;br /&gt;
    end)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule App do&lt;br /&gt;
&lt;br /&gt;
  def get_titles() do&lt;br /&gt;
    data = [&lt;br /&gt;
      &amp;quot;https://cointelegraph.com/rss&amp;quot;,&lt;br /&gt;
      &amp;quot;https://chaski.huffpost.com/us/auto/vertical/us-news&amp;quot;&lt;br /&gt;
      # Add more RSS feed URLs here&lt;br /&gt;
    ]&lt;br /&gt;
&lt;br /&gt;
    data&lt;br /&gt;
    |&amp;gt; Enum.map(fn url -&amp;gt;&lt;br /&gt;
      case ElixirRss.fetch_and_parse(url) do&lt;br /&gt;
        {:ok, feed} -&amp;gt; feed.entries |&amp;gt; Enum.map(fn entry -&amp;gt; entry end)&lt;br /&gt;
        {:error, reason} -&amp;gt; {:error, reason}&lt;br /&gt;
      end&lt;br /&gt;
    end)&lt;br /&gt;
    |&amp;gt; Enum.map(fn entry_list -&amp;gt;&lt;br /&gt;
      entry_list&lt;br /&gt;
      |&amp;gt; Enum.map(fn entry -&amp;gt; entry.title end)&lt;br /&gt;
    end)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def hello do&lt;br /&gt;
    rss_feeds = [&lt;br /&gt;
      &amp;quot;https://cointelegraph.com/rss&amp;quot;,&lt;br /&gt;
      &amp;quot;https://chaski.huffpost.com/us/auto/vertical/us-news&amp;quot;&lt;br /&gt;
      # Add more RSS feed URLs here&lt;br /&gt;
    ]&lt;br /&gt;
&lt;br /&gt;
    rss_feeds&lt;br /&gt;
    |&amp;gt; Enum.map(fn url -&amp;gt;&lt;br /&gt;
      case ElixirRss.fetch_and_parse(url) do&lt;br /&gt;
        {:ok, feed} -&amp;gt; feed.entries |&amp;gt; Enum.map(fn entry -&amp;gt; entry end)&lt;br /&gt;
        {:error, reason} -&amp;gt; {:error, reason}&lt;br /&gt;
      end&lt;br /&gt;
    end)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    if connected?(socket) do&lt;br /&gt;
      Phoenix.PubSub.subscribe(App.PubSub, &amp;quot;message&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
    {:ok, assign(socket, message_item: &amp;quot;different&amp;quot;)}&lt;br /&gt;
  end&lt;br /&gt;
  def handle_info({:pubsub_transmission, text}, socket) do&lt;br /&gt;
    IO.inspect &amp;quot;pub sub working&amp;quot;&lt;br /&gt;
    {:noreply, assign(socket, message_item: text)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def loop(data) do&lt;br /&gt;
     IO.inspect data&lt;br /&gt;
     if data &amp;gt; 0 do&lt;br /&gt;
      IO.inspect &amp;quot;notify&amp;quot;&lt;br /&gt;
      # run code to compare files, loop. If different run pubsub code below&lt;br /&gt;
      :timer.sleep(2000)&lt;br /&gt;
      loop(data-1)&lt;br /&gt;
&lt;br /&gt;
     end&lt;br /&gt;
     if data &amp;lt;= 0 do&lt;br /&gt;
&lt;br /&gt;
      Phoenix.PubSub.broadcast(App.PubSub, &amp;quot;message&amp;quot;, {:pubsub_transmission, &amp;quot;data&amp;quot;})&lt;br /&gt;
      &amp;quot;done&amp;quot;&lt;br /&gt;
     end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;change-text&amp;quot;, _params, socket) do&lt;br /&gt;
    spawn(fn -&amp;gt; loop(3) end)&lt;br /&gt;
    {:noreply, assign(socket, message_item: &amp;quot;START&amp;quot; )}&lt;br /&gt;
  end&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
&lt;br /&gt;
    # AppWeb.PageLive.loop(&amp;quot;xxx&amp;quot;)&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    SANDBOX&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;.button phx-click=&amp;quot;change-text&amp;quot; value={@message_item}&amp;gt;CLICK ME&amp;lt;/.button&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;%= @message_item %&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
elixir :   1.16.2&lt;br /&gt;
&lt;br /&gt;
Erl:   20&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# PostGres&lt;br /&gt;
Created Saturday 18 February 2023&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Launch [PostGres](#PostGres) from Terminal&lt;br /&gt;
------------------------------------------&lt;br /&gt;
sudo -u postgres psql&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Set User Permission&lt;br /&gt;
-------------------&lt;br /&gt;
&amp;lt;https://commandprompt.com/education/how-to-create-a-superuser-in-postgresql/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ALTER USER user_name WITH PASSWORD 'new_password';&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Run Post Gres Commands&lt;br /&gt;
----------------------&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
sudo -i -u postgres&lt;br /&gt;
psql&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Create and Delete Database&lt;br /&gt;
&lt;br /&gt;
CREATE DATABASE name;&lt;br /&gt;
DROP DATABASE name;&lt;br /&gt;
## View user list&lt;br /&gt;
&lt;br /&gt;
\du&lt;br /&gt;
&lt;br /&gt;
 View all databases&lt;br /&gt;
&lt;br /&gt;
postgres=# \l&lt;br /&gt;
&lt;br /&gt;
 Change databases&lt;br /&gt;
&lt;br /&gt;
postgres=# \c    name-of-database&lt;br /&gt;
&lt;br /&gt;
View Tables&lt;br /&gt;
&lt;br /&gt;
After you change databases and are selected on one of them do this:&lt;br /&gt;
&lt;br /&gt;
\dt&lt;br /&gt;
&lt;br /&gt;
SELECT * FROM mytablename;&lt;br /&gt;
&lt;br /&gt;
EMPTY TABLE&lt;br /&gt;
DELETE FROM name-of-table&lt;br /&gt;
&lt;br /&gt;
CREATE TABLE&lt;br /&gt;
&lt;br /&gt;
CREATE TABLE table_name(&lt;br /&gt;
   column1 datatype,&lt;br /&gt;
   column2 datatype,&lt;br /&gt;
   column3 datatype,&lt;br /&gt;
   .....&lt;br /&gt;
   columnN datatype,&lt;br /&gt;
   PRIMARY KEY( one or more columns )&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
INSERT&lt;br /&gt;
&lt;br /&gt;
INSERT INTO ITEMS(id, name) VALUES(1,'htvjbjbgni');     Strings are single quote&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Roadmap==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.ItemsLive do&lt;br /&gt;
    use AppWeb, :live_view  &lt;br /&gt;
    def mount(_params, _session, socket)  do&lt;br /&gt;
      {:ok, assign(socket, switches: [&amp;quot;grindy&amp;quot;,&amp;quot;sonic&amp;quot;,&amp;quot;ogre&amp;quot;])}  &lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    def handle_event(&amp;quot;run&amp;quot;,_params,socket) do  &lt;br /&gt;
        &lt;br /&gt;
        IO.inspect &amp;quot;DOWNLOAD VIA SSH&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        {:noreply, redirect(socket, to: &amp;quot;/download&amp;quot;)}&lt;br /&gt;
&lt;br /&gt;
    end&lt;br /&gt;
   &lt;br /&gt;
&lt;br /&gt;
    def render(assigns) do&lt;br /&gt;
        &lt;br /&gt;
        ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        &amp;lt;ul&amp;gt;&lt;br /&gt;
        &amp;lt;%= for switch &amp;lt;- @switches do %&amp;gt;&lt;br /&gt;
         &amp;lt;a phx-submit=&amp;quot;click&amp;quot; href=&amp;quot;/download&amp;quot;&amp;gt;  &amp;lt;li&amp;gt; &amp;lt;%= switch %&amp;gt;  &amp;lt;/li&amp;gt; &amp;lt;/a&amp;gt;&lt;br /&gt;
&lt;br /&gt;
        &amp;lt;%end%&amp;gt;&lt;br /&gt;
        &amp;lt;/ul&amp;gt;&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot; &lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Notes==&lt;br /&gt;
List of Switches and the option to select the one needed.&lt;br /&gt;
Button to download JSON file.&lt;br /&gt;
Drag and Drop Palette to upload JSON file.&lt;br /&gt;
&lt;br /&gt;
After JSON file is uploaded a button titled &amp;quot;Make Active&amp;quot; is available.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://medium.com/@fraiha26/pushing-events-to-livecomponents-from-js-hooks-w-phoenix-elixir-d5544d4c3dfa&lt;br /&gt;
&lt;br /&gt;
Changeset notes and forms&lt;br /&gt;
&lt;br /&gt;
NOTE: Use case statements for pattern matching&lt;br /&gt;
____________________________________________&lt;br /&gt;
&lt;br /&gt;
Create a basic &amp;lt;.form&amp;gt;&amp;lt;/form&amp;gt; without error handling&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&amp;lt;.form :let={f} for={@changeset}  action={~p&amp;quot;/items&amp;quot;} &amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;.input field={f[:title]} type=&amp;quot;text&amp;quot; label=&amp;quot;Title&amp;quot; /&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
  &amp;lt;.button&amp;gt;Save Item&amp;lt;/.button&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;/.form&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With error handling looks like this:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;.form :let={f} for={@changeset}  action={~p&amp;quot;/items&amp;quot;} &amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;.error :if={@changeset.action}&amp;gt;&lt;br /&gt;
    Oops, something went wrong! Please check the errors below.&lt;br /&gt;
  &amp;lt;/.error&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;.input field={f[:title]} type=&amp;quot;text&amp;quot; label=&amp;quot;Title&amp;quot; /&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
  &amp;lt;.button&amp;gt;Save Item&amp;lt;/.button&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;/.form&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Create the routes for render and post to endpoint.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The controller for the page render needs to pass in the changeset via ```Items.change_item(%Item{})```&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  def new(conn, _params) do&lt;br /&gt;
    changeset = Items.change_item(%Item{})&lt;br /&gt;
    render(conn, :new, changeset: changeset)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Post route without error handling&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  def create(conn, %{&amp;quot;item&amp;quot; =&amp;gt; item_params}) do&lt;br /&gt;
    case Items.create_item(item_params) do&lt;br /&gt;
      {:ok, item} -&amp;gt;&lt;br /&gt;
        conn&lt;br /&gt;
        |&amp;gt; put_flash(:info, &amp;quot;Item created successfully.&amp;quot;)&lt;br /&gt;
        |&amp;gt; redirect(to: ~p&amp;quot;/items/#{item}&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With error handling&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  def create(conn, %{&amp;quot;item&amp;quot; =&amp;gt; item_params}) do&lt;br /&gt;
    case Items.create_item(item_params) do&lt;br /&gt;
      {:ok, item} -&amp;gt;&lt;br /&gt;
        conn&lt;br /&gt;
        |&amp;gt; put_flash(:info, &amp;quot;Item created successfully.&amp;quot;)&lt;br /&gt;
        |&amp;gt; redirect(to: ~p&amp;quot;/items/#{item}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
      {:error, %Ecto.Changeset{} = changeset} -&amp;gt;&lt;br /&gt;
        render(conn, :new, changeset: changeset)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_____________________________________________&lt;br /&gt;
https://medium.com/@vincentlin/phoenix-very-simple-form-c4b121697fcb&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''home.html.heex'''&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&amp;lt;form action=&amp;quot;/submit&amp;quot; method=&amp;quot;post&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;label for=&amp;quot;name&amp;quot;&amp;gt;Name:&amp;lt;/label&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;input type=&amp;quot;text&amp;quot; id=&amp;quot;name&amp;quot; name=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;_csrf_token&amp;quot; value={@csrf_token} /&amp;gt;&lt;br /&gt;
  &amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Submit&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
page_controller.ex&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.PageController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  def home(conn, _params) do&lt;br /&gt;
    # The home page is often custom made,&lt;br /&gt;
&lt;br /&gt;
    csrf_token = Plug.CSRFProtection.get_csrf_token()&lt;br /&gt;
    render(conn, :home, csrf_token: csrf_token)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def submit(conn, _params) do&lt;br /&gt;
    # The home page is often custom made,&lt;br /&gt;
     IO.inspect(_params)&lt;br /&gt;
     IO.inspect &amp;quot;___________________________&amp;quot;&lt;br /&gt;
    csrf_token = Plug.CSRFProtection.get_csrf_token()&lt;br /&gt;
    render(conn, :home, csrf_token: csrf_token)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
router.ex&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  scope &amp;quot;/&amp;quot;, AppWeb do&lt;br /&gt;
    pipe_through :browser&lt;br /&gt;
    post &amp;quot;/submit&amp;quot;, PageController, :submit&lt;br /&gt;
    get &amp;quot;/&amp;quot;, PageController, :home&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ecto.Adapters.SQL.query(Repo, &amp;quot;select * from artists where id=1&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ecto cheatsheet:  https://hexdocs.pm/ecto/crud.html&lt;br /&gt;
__________________________________________________________________&lt;br /&gt;
Most programming languages give you the ability to set global state by creating globally scoped variables. Elixir does not do this. Instead, Elixir provides a tool called a &amp;quot;processes&amp;quot; to persist  state. Elixir applications are composed of these &amp;quot;processes&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
Processes by themselves are complicated to use, thus Elixir provides abstractions to make working with processes easier. One of these abstractions is called a GenServer.&lt;br /&gt;
&lt;br /&gt;
GenServers are not only used to store state, they are also used to invoke work independent of the main application process. &lt;br /&gt;
&lt;br /&gt;
==Creating a GenServer to Store State==&lt;br /&gt;
&lt;br /&gt;
To Create a GenServer, start by creating a basic Module that ''uses'' the GenServer module (image below)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule App do  &lt;br /&gt;
  use GenServer&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We now need to describe the actions we want to perform. Being that this is used to store state, we will use basic CRUD actions: Create, Read, Update, Delete. To begins, empty functions describing each action is created.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule App do&lt;br /&gt;
   def create do &lt;br /&gt;
&lt;br /&gt;
   end&lt;br /&gt;
   def read do &lt;br /&gt;
&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
   def update do  &lt;br /&gt;
&lt;br /&gt;
   end &lt;br /&gt;
&lt;br /&gt;
   def delete do &lt;br /&gt;
&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==What now?==&lt;br /&gt;
&lt;br /&gt;
To fill in the functions with the appropriate code we must first have a basic understanding of how GenServers are structured.&lt;br /&gt;
&lt;br /&gt;
GenServers are composed of the GenServer module invoking callbacks. The callbacks have built in names that you, as a developer have to use.&lt;br /&gt;
&lt;br /&gt;
These callbacks are named:&lt;br /&gt;
&lt;br /&gt;
* init&lt;br /&gt;
* handle_cast&lt;br /&gt;
* handle_call&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To demonstrate, here is an example :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{:ok, pid} = GenServer.start(ModuleNameOfGenServer, %{})&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above function named &amp;quot;start&amp;quot; calls the function named init in the Module below.&lt;br /&gt;
In GenServer syntax the name of the GenServer functions always invoke callbacks that are determined by the language. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule ModuleNameOfGenServer do&lt;br /&gt;
  # 1&lt;br /&gt;
  def init(state \\ %{}) do&lt;br /&gt;
    {:ok, state}&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is a list of the GenServer functions and their corresponding callbacks.&lt;br /&gt;
&lt;br /&gt;
* GenServer.start/1  --&amp;gt;       init/1&lt;br /&gt;
* GenServer.call/3   --&amp;gt;       def handle_call/3&lt;br /&gt;
* GenServer.cast/2   --&amp;gt;       handle_cast/2&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Start and Call ==&lt;br /&gt;
&lt;br /&gt;
Call and Cast can be used to perform the same operations. The &lt;br /&gt;
&lt;br /&gt;
__________________________________________________________&lt;br /&gt;
Genserver timed events&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule Go do&lt;br /&gt;
  use GenServer&lt;br /&gt;
&lt;br /&gt;
  def go() do&lt;br /&gt;
    GenServer.start_link(__MODULE__, [])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def init(list) do&lt;br /&gt;
    :timer.apply_interval(1000, __MODULE__, :add, [self(), &amp;quot;weeeee&amp;quot;])&lt;br /&gt;
    {:ok, list}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def view(pid) do&lt;br /&gt;
    GenServer.call(pid, :view)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_call(:view, _from, list) do&lt;br /&gt;
    {:reply, list, list}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def add(pid, new_item) do&lt;br /&gt;
    GenServer.call(pid, {:item, new_item})&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_call({:item, new_item}, _from, state) do&lt;br /&gt;
    result = [new_item] ++ state&lt;br /&gt;
    {:reply, result, result}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule ShoppingList do&lt;br /&gt;
  use GenServer&lt;br /&gt;
&lt;br /&gt;
  def start_link() do&lt;br /&gt;
    GenServer.start_link(ShoppingList, [])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def init(list) do&lt;br /&gt;
    {:ok, list}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def view(pid) do&lt;br /&gt;
    GenServer.call(pid, :view)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_call(:view, _from, list) do&lt;br /&gt;
    {:reply, list, list}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def add(pid, new_item) do&lt;br /&gt;
    GenServer.call(pid, {:item, new_item})&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_call({:item, new_item}, _from, state) do&lt;br /&gt;
    result = [new_item] ++ state&lt;br /&gt;
    {:reply, result, result}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://blog.appsignal.com/2018/06/12/elixir-alchemy-deconstructing-genservers.html&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule KeyValue do&lt;br /&gt;
  # 1&lt;br /&gt;
  def init(state \\ %{}) do&lt;br /&gt;
    {:ok, state}&lt;br /&gt;
  end&lt;br /&gt;
 &lt;br /&gt;
  # 2&lt;br /&gt;
  def handle_cast({:put, key, value}, state) do&lt;br /&gt;
    {:noreply, Map.put(state, key, value)}&lt;br /&gt;
  end&lt;br /&gt;
 &lt;br /&gt;
  # 3&lt;br /&gt;
  def handle_call({:get, key}, _from, state) do&lt;br /&gt;
    {:reply, Map.fetch!(state, key), state}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
# {:ok, pid} = GenServer.start(KeyValue, %{})&lt;br /&gt;
# GenServer.cast(pid, {:put, :foo, &amp;quot;bar&amp;quot;})&lt;br /&gt;
# GenServer.call(pid, {:get, :foo})&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Send messages via these functions wrapped in module functions .You can look at these are functions used to fire &amp;quot;GenServer Events&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
* start_link&lt;br /&gt;
* GenServer.call&lt;br /&gt;
* GenServer.cast&lt;br /&gt;
&lt;br /&gt;
The corresponding server functions that reply are:&lt;br /&gt;
&lt;br /&gt;
* init&lt;br /&gt;
* handle__call&lt;br /&gt;
* handle_cast&lt;br /&gt;
* &lt;br /&gt;
&lt;br /&gt;
These can be looked at as &amp;quot;listeners&amp;quot; - in JavaScript parlance. &lt;br /&gt;
__________________________________________&lt;br /&gt;
&lt;br /&gt;
If you have experience with programming languages other than Elixir the idea of GenServers may be very foreign and require a strong context shift to learn. This document is intended to simplify the concept.&lt;br /&gt;
&lt;br /&gt;
* What: GenServers are simply a way to hold state and/or invoke actions based on incoming events. &lt;br /&gt;
* when &lt;br /&gt;
* where&lt;br /&gt;
* why&lt;br /&gt;
* how&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
___________________________________________&lt;br /&gt;
GenServer timer example&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule Timer do&lt;br /&gt;
  use GenServer&lt;br /&gt;
&lt;br /&gt;
  def init(_) do&lt;br /&gt;
    :timer.send_interval(1000, :xyz)&lt;br /&gt;
    {:ok, 0}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_info(:xyz, state) do&lt;br /&gt;
    IO.inspect(state)&lt;br /&gt;
    {:noreply, state + 1}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
[&lt;br /&gt;
   {&lt;br /&gt;
     data:{&lt;br /&gt;
        creationTime,&lt;br /&gt;
        publishDate,&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
     featured:{&lt;br /&gt;
        setAmount,&lt;br /&gt;
        items:[]&lt;br /&gt;
     },&lt;br /&gt;
&lt;br /&gt;
     children:{&lt;br /&gt;
        setAmount,&lt;br /&gt;
        items:[]&lt;br /&gt;
     },&lt;br /&gt;
     links:{&lt;br /&gt;
        setAmount,&lt;br /&gt;
        items:[]&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
jason.encode / jason.decode&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  def run(num) do&lt;br /&gt;
&lt;br /&gt;
    Enum.each(0..99999, fn(_x) -&amp;gt;&lt;br /&gt;
      task = Task.async(fn -&amp;gt; num + _x end)&lt;br /&gt;
    IO.inspect Task.await(task)&lt;br /&gt;
  end)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enum.map(feed.entries, fn x -&amp;gt; %{url: x.url, title: x.title} end)&lt;br /&gt;
&lt;br /&gt;
App is split:&lt;br /&gt;
&lt;br /&gt;
App that captures RSS in UI and lets admin select stories. THere are settings to determine the number of FEATURED,CHILD and LINK stories.&lt;br /&gt;
News categories are horizontal and scrollable.&lt;br /&gt;
This exports a json doc with all RSS data for each story.&lt;br /&gt;
The &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
App that reads the json data. This app creates tables and is the front end.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://stephenbussey.com/tags/elixir.html&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule AppWeb.GroupLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  alias App.TestBeds&lt;br /&gt;
  alias App.Groups&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    {:ok, assign(socket, testbeds: TestBeds.list_testbeds(), groups: Groups.list_groups())}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;select-group&amp;quot;, params, socket)  do  &lt;br /&gt;
     group = App.Groups.get_group!(params[&amp;quot;group-id&amp;quot;])&lt;br /&gt;
     testbed = App.TestBeds.get_test_bed!(params[&amp;quot;testbed_id&amp;quot;])&lt;br /&gt;
     App.TestBeds.update_test_bed(testbed, %{group_id: group.id})&lt;br /&gt;
     {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def updated_groups(testbed_id)  do  &lt;br /&gt;
     testbed = App.TestBeds.get_test_bed!(testbed_id)&lt;br /&gt;
     groups = App.Groups.list_groups&lt;br /&gt;
     tail = Enum.filter(groups, fn(item)-&amp;gt; item.id !== testbed.group_id end)&lt;br /&gt;
     head = Enum.filter(groups, fn(item)-&amp;gt; item.id == testbed.group_id end)&lt;br /&gt;
            |&amp;gt;Enum.at(0)&lt;br /&gt;
    [head | tail]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        &amp;lt;%= for testbed &amp;lt;- Enum.sort_by(@testbeds , &amp;amp;(&amp;quot;#{&amp;amp;1.name}&amp;quot;), :asc)do %&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;grid grid-cols-4 gap-4 p-8 rounded shadow bg-white&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;h2&amp;gt; Name&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;%= testbed.name %&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;h2&amp;gt; Group&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div&amp;gt;&lt;br /&gt;
            &amp;lt;form phx-change=&amp;quot;select-group&amp;quot; name=&amp;quot;testbed_id&amp;quot;  &amp;gt;&lt;br /&gt;
               &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;testbed_id&amp;quot; value={testbed.id}/&amp;gt;&lt;br /&gt;
               &amp;lt;select id=&amp;quot;group-selection&amp;quot;  name=&amp;quot;group-id&amp;quot; class=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;%= for group &amp;lt;- updated_groups(testbed.id) do %&amp;gt;&lt;br /&gt;
                  &amp;lt;%= if group !== nil do %&amp;gt;&lt;br /&gt;
                      &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}&amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
                      &amp;lt;%else%&amp;gt;&lt;br /&gt;
                      &amp;lt;option value= {&amp;quot;Unassigned&amp;quot;}&amp;gt;NONE&amp;lt;/option&amp;gt;&lt;br /&gt;
                  &amp;lt;% end %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
               &amp;lt;/select&amp;gt;&lt;br /&gt;
            &amp;lt;/form&amp;gt;&lt;br /&gt;
          &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
       &amp;lt;% end %&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Developer Notes ==&lt;br /&gt;
===Groups Feature ===&lt;br /&gt;
To complete this feature do these things.&lt;br /&gt;
* Run through the steps in [http://elixirblocks.com/index.php?title=Create_Foreign_Key_Relationship_Between_Ecto_Tables  | this document] to create Group table.&lt;br /&gt;
* Groups have these fields  '''name: string''', '''description: string''' and '''color: string'''  &lt;br /&gt;
* Add unique constraint in migration file: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def change do&lt;br /&gt;
     create unique_index(:groups, [:name])&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Port over Group LiveView code (temporarily placed at discussion page).&lt;br /&gt;
* On completion '''possibly''', create a Group named '''No Group''' and set all Testbeds to it.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
________&lt;br /&gt;
https://blog.appsignal.com/2022/10/11/phoenix-liveview-018-new-special-html-attributes.html&lt;br /&gt;
https://blixtdev.com/whats-new-phoenix-1-7/&lt;br /&gt;
https://github.com/devato/inertia_phoenix&lt;br /&gt;
https://phoenixonrails.com/blog/you-can-stop-using-form-for-in-phoenix&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://samuelmullen.com/articles/phoenix_templates_rendering_and_layouts&lt;br /&gt;
&lt;br /&gt;
WorkFlow of Todo App in Both LiveView and DeadView.&lt;br /&gt;
&lt;br /&gt;
Note:&lt;br /&gt;
&lt;br /&gt;
Create foreign key data.&lt;br /&gt;
Create live view. List all testbeds and form to assign each a group by group-name.&lt;br /&gt;
&lt;br /&gt;
Repeat in dead view&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Mental model and data flows&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
home.html.heex&lt;br /&gt;
&amp;lt;a href=&amp;quot;/data&amp;quot; name=&amp;quot;we are the world&amp;quot; &amp;gt;  click me&amp;lt;/a&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;%= @message %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
page controller&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  def home(conn, _params) do&lt;br /&gt;
    IO.inspect _params&lt;br /&gt;
    render(conn, :home, message: &amp;quot;Hello&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
get &amp;quot;/:yay&amp;quot;, PageController, :index&lt;br /&gt;
&lt;br /&gt;
get &amp;quot;/&amp;quot;, PageController, :index&lt;br /&gt;
&lt;br /&gt;
* Explain control flow of &amp;quot;Dead Views&amp;quot; and the Generator HTML Control flow.&lt;br /&gt;
* Proper Way to use Modal&lt;br /&gt;
* How to give Focus to Fields in Modal (or other forms fields)&lt;br /&gt;
* &lt;br /&gt;
* &lt;br /&gt;
* How to Create Database Seed Data.&lt;br /&gt;
* How to structure code so controller code is in one file and HTML Heex is in another&lt;br /&gt;
* How to Use Generators in a Real World Project&lt;br /&gt;
* How to Work with Database Data via Basic Commands and Custom Change sets.&lt;br /&gt;
* How to Render Database Data to LiveView (via Context Commands).&lt;br /&gt;
* How to Create a Chat using PubSub.&lt;br /&gt;
* How to Create Event Handlers in LiveView&lt;br /&gt;
* How to Create a Dynamic Route from Scratch.&lt;br /&gt;
* How to Use Elixirs Template language&lt;br /&gt;
* How to Work with Modal&lt;br /&gt;
* How to Use CSS From Scratch (Without bundler)&lt;br /&gt;
* How to use JS hooks&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
______________________&lt;br /&gt;
https://studioindie.co/blog/heex-guide/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
get &amp;quot;/&amp;quot;, PageController, :some-atom    #This is the route. some-atom is the controller name&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  def some-atom(conn, _params) do                 # controller name&lt;br /&gt;
    # The home page is often custom made,&lt;br /&gt;
    # so skip the default app layout.&lt;br /&gt;
    render(conn, :some-atom, layout: false)      # :some-atom is template name&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Controllers page_html.ex contains &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageHTML do&lt;br /&gt;
  use AppWeb, :html&lt;br /&gt;
&lt;br /&gt;
  embed_templates &amp;quot;page_html/*&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''page_html''' is the name of the folder in '''Controllers/page_html'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Controllers/page_html/some-atom.html.heex  (this is the template) &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__________________________________________&lt;br /&gt;
Set all association with preload:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  def list_groups do&lt;br /&gt;
    Repo.all(Group)&lt;br /&gt;
     |&amp;gt; Repo.preload([:testbeds])&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Insert Child into Parent ===&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
App.get_group!(2) # arg is id&lt;br /&gt;
|&amp;gt; Ecto.build_assoc(:testbeds)&lt;br /&gt;
|&amp;gt; Repo.insert()&lt;br /&gt;
&lt;br /&gt;
Or&lt;br /&gt;
&lt;br /&gt;
group = App.get_group!(2) # arg is id&lt;br /&gt;
&lt;br /&gt;
testbeds = Ecto.build_assoc(group, :testbeds)&lt;br /&gt;
&lt;br /&gt;
App.Group.create_group(testbeds)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
group = App.Groups.get_group!(1)&lt;br /&gt;
thing = Ecto.build_assoc(group, :testbeds, name: &amp;quot;DUMB&amp;quot;)&lt;br /&gt;
alias App.{Repo}&lt;br /&gt;
Repo.insert(thing)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
avatar = %Avatar{nick_name: &amp;quot;Elixir&amp;quot;, pic_url: &amp;quot;http://elixir-lang.org/images/logo.png&amp;quot;}&lt;br /&gt;
user = %User{name: &amp;quot;John Doe&amp;quot;, email: &amp;quot;john.doe@example.com&amp;quot;, avatar: avatar}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://www.reddit.com/r/elixir/comments/oh318k/is_there_a_way_to_avoid_ectoassociationnotloaded/h4mmcfi/?utm_source=share&amp;amp;utm_medium=web3x&amp;amp;utm_name=web3xcss&amp;amp;utm_term=1&amp;amp;utm_content=share_button&lt;br /&gt;
&lt;br /&gt;
# Create Group Table&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
mix phx.gen.html Groups Group groups name:string  &lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Set the resources / &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
mix ecto.migrate&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For testbeds create a migration file and add this field:   group_id:references:groups&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
def change do&lt;br /&gt;
    alter table(:testbeds) do    # customize to your code&lt;br /&gt;
      add :group_id, references(:groups)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Update Groups Schema (Don't forget alias / has_many)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule App.Groups.Group do&lt;br /&gt;
	use Ecto.Schema&lt;br /&gt;
	import Ecto.Changeset&lt;br /&gt;
	alias App.Testbeds.Testbed   # Alias!&lt;br /&gt;
&lt;br /&gt;
	schema &amp;quot;posts&amp;quot; do&lt;br /&gt;
		field :body, :string&lt;br /&gt;
		field :title, :string&lt;br /&gt;
		has_many :testbeds, Testbed    # Has many&lt;br /&gt;
&lt;br /&gt;
		timestamps()&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	@doc false&lt;br /&gt;
	def changeset(post, attrs) do&lt;br /&gt;
		post&lt;br /&gt;
		|&amp;gt; cast(attrs, [:title, :body])&lt;br /&gt;
		|&amp;gt; validate_required([:title, :body])&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
TESTBEDS Schema&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule App.Testbeds.Testbed do&lt;br /&gt;
  use Ecto.Schema&lt;br /&gt;
  import Ecto.Changeset&lt;br /&gt;
  alias App.Groups.Group      # Alias&lt;br /&gt;
  schema &amp;quot;testbeds&amp;quot; do&lt;br /&gt;
    field :name, :string&lt;br /&gt;
    belongs_to :group, Group    # Belongs to&lt;br /&gt;
    timestamps()&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  @doc false&lt;br /&gt;
  def changeset(testbed, attrs) do&lt;br /&gt;
    testbed&lt;br /&gt;
    |&amp;gt; cast(attrs, [:name])&lt;br /&gt;
    |&amp;gt; validate_required([:name])&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
_____________________________________&lt;br /&gt;
Side notes.&lt;br /&gt;
&lt;br /&gt;
defmodule App.Repo.Migrations.CreateTestbeds do&lt;br /&gt;
  use Ecto.Migration&lt;br /&gt;
&lt;br /&gt;
  def change do&lt;br /&gt;
    create table(:testbeds) do&lt;br /&gt;
      add :name, :string&lt;br /&gt;
      add :group_id, references(:groups, on_delete: :nothing)&lt;br /&gt;
&lt;br /&gt;
      timestamps()&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    create index(:testbeds, [:group_id])&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
________________________________&lt;br /&gt;
&lt;br /&gt;
mix phx.gen.context Comments Comment comments name:string content:text post_id:references:posts&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
mix phx.gen.html Testbeds Testbed testbeds name:string  group_id:references:groups&lt;br /&gt;
&lt;br /&gt;
https://graffino.com/web-development/first-steps-in-elixir-and-phoenix-create-a-blog-prototype&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://blog.logrocket.com/getting-started-ecto-phoenix/&lt;br /&gt;
&lt;br /&gt;
https://serokell.io/blog/ecto-guide-for-beginners&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
mix phx.gen.html Testbeds Testbed testbeds name:string&lt;br /&gt;
&lt;br /&gt;
mix phx.gen.html Groups Group groups name:string&lt;br /&gt;
&lt;br /&gt;
Create migration for &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
mix ecto.gen.migration add_testbed_group_reference&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Migration:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  def change do&lt;br /&gt;
    alter table(:testbeds) do    # customize to your code&lt;br /&gt;
      add :group_id, references(:groups)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Manually Change:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule App.Group do&lt;br /&gt;
  use Ecto.Schema&lt;br /&gt;
&lt;br /&gt;
  schema &amp;quot;groups&amp;quot; do&lt;br /&gt;
    field :title, :string&lt;br /&gt;
    field :tagline, :string&lt;br /&gt;
    has_many :testbeds, App.Testbed&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
testbeds&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule App.Repo.Migrations.AddTextbedGroups do&lt;br /&gt;
  use Ecto.Migration&lt;br /&gt;
&lt;br /&gt;
  def change do&lt;br /&gt;
    create table(:testbeds) do&lt;br /&gt;
      add :name, :string&lt;br /&gt;
      add :group_id, references(:groups)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
# lib/app/testbeds.ex&lt;br /&gt;
&lt;br /&gt;
defmodule App.Testbed do&lt;br /&gt;
  use Ecto.Schema&lt;br /&gt;
&lt;br /&gt;
  schema &amp;quot;testbedss&amp;quot; do&lt;br /&gt;
    field :name, :string&lt;br /&gt;
    belongs_to :group, App.Group&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_____________________&lt;br /&gt;
&lt;br /&gt;
%App.TestBeds.TestBed{&lt;br /&gt;
  __meta__: #Ecto.Schema.Metadata&amp;lt;:loaded, &amp;quot;testbeds&amp;quot;&amp;gt;,&lt;br /&gt;
  id: 1,&lt;br /&gt;
  developer: &amp;quot;None&amp;quot;,&lt;br /&gt;
  name: &amp;quot;sdfsd&amp;quot;,&lt;br /&gt;
  owner: &amp;quot;sdfsddf&amp;quot;,&lt;br /&gt;
  note: &amp;quot;sdsfsddf&amp;quot;,&lt;br /&gt;
  status: &amp;quot;Available&amp;quot;,&lt;br /&gt;
  url: &amp;quot;sdf&amp;quot;,&lt;br /&gt;
  version: &amp;quot;ddf&amp;quot;,&lt;br /&gt;
  manager: &amp;quot;sf&amp;quot;,&lt;br /&gt;
  inserted_at: ~N[2023-08-21 13:45:39],&lt;br /&gt;
  updated_at: ~N[2023-08-21 13:45:44]&lt;br /&gt;
}&lt;br /&gt;
________________________________________________________________---&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.SendLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  &lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    {:ok, socket}&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  def handle_event(&amp;quot;send&amp;quot;, %{&amp;quot;text&amp;quot; =&amp;gt; text}, socket) do&lt;br /&gt;
&lt;br /&gt;
    AppWeb.Endpoint.broadcast(topic, &amp;quot;message&amp;quot;, text)&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  defp topic do&lt;br /&gt;
    &amp;quot;chat&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def render(assigns)do   &lt;br /&gt;
   ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
  &amp;lt;h1&amp;gt;Send Message&amp;lt;/h1&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;form phx-submit=&amp;quot;send&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;text&amp;quot; /&amp;gt;&lt;br /&gt;
    &amp;lt;button type=&amp;quot;submit&amp;quot;&amp;gt;Send&amp;lt;/button&amp;gt;&lt;br /&gt;
  &amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
______________________________________________________________&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.ReceiveLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  &lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    if connected?(socket) do&lt;br /&gt;
      AppWeb.Endpoint.subscribe(topic)&lt;br /&gt;
    end&lt;br /&gt;
    {:ok, assign(socket, messages: &amp;quot;&amp;quot;)}&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def handle_info(%{event: &amp;quot;message&amp;quot;, payload: message}, socket) do&lt;br /&gt;
    IO.inspect message&lt;br /&gt;
    {:noreply, assign(socket, messages: message)}&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  defp topic do&lt;br /&gt;
    &amp;quot;chat&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns)do   &lt;br /&gt;
   ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
  &amp;lt;h1&amp;gt;ChatLive&amp;lt;/h1&amp;gt;&lt;br /&gt;
  &amp;lt;%= @messages %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
______________________________________________________________&lt;br /&gt;
When you hover over a list of items this hook finds items with the same name and sets the opacity of all others to 0. You see all the items similar to the one you are hovering over.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
TestbedVersionHover: {&lt;br /&gt;
			// https://jsfiddle.net/IrvinDominin/7K2Z3/&lt;br /&gt;
            mounted() {&lt;br /&gt;
&lt;br /&gt;
                let rows = document.getElementsByClassName(&amp;quot;testbed-version&amp;quot;)&lt;br /&gt;
                // this.ele = element&lt;br /&gt;
				// rows = this.ele;&lt;br /&gt;
                &lt;br /&gt;
				for (var i = 0; i &amp;lt; rows.length; i++) {&lt;br /&gt;
					rows[i].onmouseenter = function (event) {&lt;br /&gt;
						for (var j = 0; j &amp;lt; rows.length; j++) {&lt;br /&gt;
							let preversion = this.textContent;&lt;br /&gt;
							let version = preversion.slice(0,5)&lt;br /&gt;
							let compareVersion = rows[j].textContent.slice(0,5)&lt;br /&gt;
							if (compareVersion === version) continue&lt;br /&gt;
							rows[j].className += &amp;quot; other&amp;quot;;&lt;br /&gt;
						}&lt;br /&gt;
					};&lt;br /&gt;
				&lt;br /&gt;
					rows[i].onmouseleave = function (event) {&lt;br /&gt;
						var hovers = document.getElementsByClassName('other');&lt;br /&gt;
						var len = hovers.length;&lt;br /&gt;
						for (var j = 0; j &amp;lt; len; j++) {&lt;br /&gt;
							hovers[0].className = hovers[0].className.replace(/\sother(\s|$)/, '');&lt;br /&gt;
						}&lt;br /&gt;
					};&lt;br /&gt;
				}&lt;br /&gt;
&lt;br /&gt;
                // this.ele.addEventListener(&amp;quot;click&amp;quot;, (e) =&amp;gt; {&lt;br /&gt;
                //     console.log(e.target)&lt;br /&gt;
                    &lt;br /&gt;
                // });&lt;br /&gt;
&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* How to Create Database Seed Data.&lt;br /&gt;
* How to structure code so controller code is in one file and HTML Heex is in another&lt;br /&gt;
* How to Use Generators in a Real World Project&lt;br /&gt;
* How to Work with Database Data via Basic Commands and Custom Change sets.&lt;br /&gt;
* How to Render Database Data to LiveView (via Context Commands).&lt;br /&gt;
* How to Create a Chat using PubSub.&lt;br /&gt;
* How to Create Event Handlers in LiveView&lt;br /&gt;
* How to Create a Dynamic Route from Scratch.&lt;br /&gt;
* How to Use Elixirs Template language&lt;br /&gt;
* How to Work with Modal&lt;br /&gt;
* How to Use CSS From Scratch (Without bundler)&lt;br /&gt;
* How to use JS hooks&lt;br /&gt;
* Dissect Table Component and Update it to Order List in Reverse.&lt;br /&gt;
&lt;br /&gt;
Selenium&lt;br /&gt;
https://www.builder.io/blog/debug-nodejs&lt;br /&gt;
&lt;br /&gt;
https://marketplace.visualstudio.com/items?itemName=ms-vscode.live-server#running-the-extension&lt;br /&gt;
&lt;br /&gt;
This was added recently (see microsoft/vscode#109276).&lt;br /&gt;
    1. Open the palette (Ctrl + Shift + P)&lt;br /&gt;
    2. Select &amp;quot;Simple Browser: Preview&amp;quot;&lt;br /&gt;
    3. Enter web address&lt;br /&gt;
&lt;br /&gt;
_______________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
const {By, Key, Builder} = require(&amp;quot;selenium-webdriver&amp;quot;);&lt;br /&gt;
const assert = require(&amp;quot;assert&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
require(&amp;quot;chromedriver&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
async function test_case(){&lt;br /&gt;
  let driver = await new Builder().forBrowser(&amp;quot;chrome&amp;quot;).build();&lt;br /&gt;
  await driver.get(&amp;quot;sie&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  await driver.findElement(By.name('password')).clear();&lt;br /&gt;
  await driver.findElement(By.name('identification')).clear();&lt;br /&gt;
  await driver.findElement(By.name('identification')).sendKeys(&amp;quot;bill&amp;quot;);&lt;br /&gt;
  await driver.findElement(By.name('password')).sendKeys(&amp;quot;password&amp;quot;, Key.RETURN);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 setTimeout(()=&amp;gt;{&lt;br /&gt;
   driver.findElement(By.className(&amp;quot;req_lan_license&amp;quot;)).click();&lt;br /&gt;
 },5000)&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageLive do &lt;br /&gt;
&lt;br /&gt;
  use AppWeb, :live_view  &lt;br /&gt;
  alias App.Testbeds &lt;br /&gt;
  def mount(_params, _session, socket)do   &lt;br /&gt;
     {:ok, assign(socket, testbeds: Testbeds.list_testbeds())}   &lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
    def button_event(&amp;quot;invoke_editing&amp;quot;) do&lt;br /&gt;
    %JS{}&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;active&amp;quot;, to: &amp;quot;#editing_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#editing_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#preview_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;active&amp;quot;, to: &amp;quot;#preview_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;active&amp;quot;, to: &amp;quot;#preview&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#preview&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#editing&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;active&amp;quot;, to: &amp;quot;#editing&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def button_event(&amp;quot;invoke_preview&amp;quot;) do&lt;br /&gt;
    %JS{}&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;active&amp;quot;, to: &amp;quot;#preview_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#preview_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#editing_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;active&amp;quot;, to: &amp;quot;#editing_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;active&amp;quot;, to: &amp;quot;#editing&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#editing&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#preview&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;active&amp;quot;, to: &amp;quot;#preview&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;send&amp;quot;, params, socket) do&lt;br /&gt;
    hide_modal(&amp;quot;notes-modal-0&amp;quot;)&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do  &lt;br /&gt;
     ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
		&amp;lt;.modal id={&amp;quot;notes-modal-#{testbed.id}&amp;quot;}&amp;gt;&lt;br /&gt;
		    &amp;lt;.button phx-click={button_event(&amp;quot;invoke_editing&amp;quot;)} id=&amp;quot;editing_button&amp;quot; class=&amp;quot;hidden&amp;quot;&amp;gt;&lt;br /&gt;
		      Preview&lt;br /&gt;
		    &amp;lt;/.button&amp;gt;&lt;br /&gt;
		    &amp;lt;.button phx-click={button_event(&amp;quot;invoke_preview&amp;quot;)} id=&amp;quot;preview_button&amp;quot;&amp;gt;&lt;br /&gt;
		      Edit Me&lt;br /&gt;
		    &amp;lt;/.button&amp;gt;&lt;br /&gt;
		    &amp;lt;div id=&amp;quot;editing&amp;quot;&amp;gt; PREVIEWING THE WORK&amp;lt;/div&amp;gt;&lt;br /&gt;
		    &amp;lt;form phx-submit = &amp;quot;send&amp;quot;   id=&amp;quot;preview&amp;quot; class=&amp;quot;hidden&amp;quot;&amp;gt;&lt;br /&gt;
		      &amp;lt;textarea value = {testbed.note}&amp;gt;&amp;lt;/textarea&amp;gt;&lt;br /&gt;
		      &amp;lt;.button type=&amp;quot;submit&amp;quot; phx-click={hide_modal(&amp;quot;notes-modal-#{testbed.id}&amp;quot;)}&amp;gt;SAVE WORK&amp;lt;/.button&amp;gt;&lt;br /&gt;
		    &amp;lt;/form&amp;gt;&lt;br /&gt;
		&amp;lt;/.modal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;%= if testbed.note do %&amp;gt;&lt;br /&gt;
      &amp;lt;div phx-click={show_modal(&amp;quot;notes-modal-#{testbed.id}&amp;quot;)}&amp;gt;READ ME  ...&amp;lt;%= testbed.note %&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
	   &lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
       &lt;br /&gt;
      &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
import {HfInference} from &amp;quot;@huggingface/inference&amp;quot;;&lt;br /&gt;
import dotenv from &amp;quot;dotenv&amp;quot;;&lt;br /&gt;
dotenv.config()&lt;br /&gt;
&lt;br /&gt;
const HF_ACCESS_TOKEN = process.env.HF_ACCESS_TOKEN&lt;br /&gt;
&lt;br /&gt;
const hf = new HfInference(HF_ACCESS_TOKEN);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*______Uncomment for this example______________________&lt;br /&gt;
&lt;br /&gt;
const model = &amp;quot;nlpconnect/vit-gpt2-image-captioning&amp;quot;;&lt;br /&gt;
const imageURL = &amp;quot;https://i.imgur.com/lTvb7Et.png&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
const response = await fetch(imageURL);&lt;br /&gt;
const imageBlob = await response.blob();&lt;br /&gt;
&lt;br /&gt;
const result  = await hf.imageToText({&lt;br /&gt;
	data: imageBlob,&lt;br /&gt;
	model: model,&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
_______________________________________________________*/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*________Another example ___________________*/&lt;br /&gt;
&lt;br /&gt;
const result = await hf.summarization({&lt;br /&gt;
	model: 'facebook/bart-large-cnn',&lt;br /&gt;
	inputs: &amp;quot;The role of a dumb man is to get smarter oogy bookie boo&amp;quot;,&lt;br /&gt;
	parameters:{&lt;br /&gt;
		max_length: 100&lt;br /&gt;
	}&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
console.log(result);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
________________________________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://fly.io/phoenix-files/sdeb-toggling-element/&lt;br /&gt;
https://www.youtube.com/watch?v=vBgZvQapqhs&lt;br /&gt;
&lt;br /&gt;
https://blog.testdouble.com/posts/2022-11-28-how-to-use-javascript-with-phoenix-liveview/&lt;br /&gt;
&lt;br /&gt;
https://hexdocs.pm/phoenix_live_view/0.19.3/Phoenix.Component.html&lt;br /&gt;
_______________________________________&lt;br /&gt;
https://www.smashingmagazine.com/2011/10/quick-look-math-animations-javascript/&lt;br /&gt;
* Depth first traversal&lt;br /&gt;
* Breadth first traversal&lt;br /&gt;
&lt;br /&gt;
https://dev.to/codesphere/10-algorithms-every-developer-should-learn-3lnm&lt;br /&gt;
&lt;br /&gt;
https://www.youtube.com/watch?v=fPz40W9mfCg&lt;br /&gt;
&lt;br /&gt;
__________________________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.GroupLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  alias App.TestBeds&lt;br /&gt;
  alias App.Groups&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    {:ok, assign(socket, testbeds: TestBeds.list_testbeds(), groups: Groups.list_groups())}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;select-group&amp;quot;, params, socket)  do  &lt;br /&gt;
         &lt;br /&gt;
       IO.inspect params&lt;br /&gt;
       {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div class=&amp;quot;grid grid-columns-2 grid-flow-col gap-4&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;column-1&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;%= testbed.name %&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;column-2&amp;quot;&amp;gt;    &lt;br /&gt;
            &amp;lt;form phx-change=&amp;quot;select-group&amp;quot;  &amp;gt;&lt;br /&gt;
               &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;testbed_id&amp;quot; value={testbed.id}/&amp;gt;&lt;br /&gt;
               &amp;lt;select id=&amp;quot;group-selection&amp;quot;  name=&amp;quot;group-id&amp;quot; &amp;gt;&lt;br /&gt;
                &amp;lt;%= for group &amp;lt;- @groups do %&amp;gt;&lt;br /&gt;
                  &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}  &amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
               &amp;lt;/select&amp;gt;&lt;br /&gt;
            &amp;lt;/form&amp;gt;&lt;br /&gt;
         &amp;lt;/div&amp;gt;&lt;br /&gt;
       &amp;lt;% end %&amp;gt;&lt;br /&gt;
   &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
____________________________&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.GroupLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  alias App.TestBeds&lt;br /&gt;
  alias App.Groups&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
&lt;br /&gt;
    {:ok, assign(socket, testbeds: TestBeds.list_testbeds(), groups: Groups.list_groups(), messages: [])}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;select-group&amp;quot;, params, socket)  do  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
      group = App.Groups.get_group!(params[&amp;quot;group-id&amp;quot;])&lt;br /&gt;
       # IO.inspect group&lt;br /&gt;
       testbed = App.TestBeds.get_test_bed!(params[&amp;quot;testbed_id&amp;quot;])&lt;br /&gt;
     &lt;br /&gt;
       App.TestBeds.update_test_bed(testbed, %{group_id: group.id})&lt;br /&gt;
         &lt;br /&gt;
    &lt;br /&gt;
       {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def updated_groups(testbed_id)  do  &lt;br /&gt;
       groups = App.Groups.list_groups&lt;br /&gt;
       tail = Enum.filter(groups, fn(item)-&amp;gt; item.id !== testbed_id end)&lt;br /&gt;
       head = Enum.filter(groups, fn(item)-&amp;gt; item.id == testbed_id end)&lt;br /&gt;
              |&amp;gt;Enum.at(0)&lt;br /&gt;
     [head | tail]&lt;br /&gt;
         &lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
 # def handle_event(&amp;quot;groups&amp;quot;, params, socket)do  &lt;br /&gt;
 #       selected_testbed = %{name: &amp;quot;my testbed name&amp;quot;, id: 3}&lt;br /&gt;
 #       groups = App.Groups.list_groups&lt;br /&gt;
 #       tail = Enum.filter(groups, fn(item)-&amp;gt; item.id !== selected_testbed.id end)&lt;br /&gt;
 #       head = Enum.filter(groups, fn(item)-&amp;gt; item.id == selected_testbed.id end)&lt;br /&gt;
 #              |&amp;gt;Enum.at(0)&lt;br /&gt;
         &lt;br /&gt;
 &lt;br /&gt;
 #       # result = Enum.filter([1, 2, 3], fn x -&amp;gt; x.id !== 1 end)&lt;br /&gt;
 #      IO.inspect [head | tail]&lt;br /&gt;
         &lt;br /&gt;
 #      #&lt;br /&gt;
 #      {:noreply, socket, assigns.message:}&lt;br /&gt;
 #  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    &lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
       &amp;lt;%!-- &amp;lt;div phx-click = &amp;quot;groups&amp;quot;&amp;gt;CLICK ME&amp;lt;/div&amp;gt; --%&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;grid grid-cols-4 gap-4 p-8 rounded shadow bg-white&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;h2&amp;gt; Name&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;%= testbed.name %&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;h2&amp;gt; Group&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;form phx-change=&amp;quot;select-group&amp;quot; name=&amp;quot;testbed_id&amp;quot;  &amp;gt;&lt;br /&gt;
               &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;testbed_id&amp;quot; value={testbed.id}/&amp;gt;&lt;br /&gt;
               &amp;lt;select id=&amp;quot;group-selection&amp;quot;  name=&amp;quot;group-id&amp;quot; class=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
                &amp;lt;%= for group &amp;lt;- updated_groups(testbed.id) do %&amp;gt;&lt;br /&gt;
                  &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}  &amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
                  &amp;lt;!-- Write code to reorder with testbed.group_id matching group_id --&amp;gt;&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
               &amp;lt;/select&amp;gt;&lt;br /&gt;
            &amp;lt;/form&amp;gt;&lt;br /&gt;
          &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
       &amp;lt;% end %&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_____________________________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
   use AppWeb, :live_view  &lt;br /&gt;
     alias App.Testbeds&lt;br /&gt;
  alias App.Groups&lt;br /&gt;
   def mount(_params, _session, socket)  do&lt;br /&gt;
	     {:ok, assign(socket, testbeds: Testbeds.list_testbeds(), groups: Groups.list_groups())}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
   def handle_event(&amp;quot;select-group&amp;quot;, params, socket)  do  &lt;br /&gt;
       group = App.Groups.get_group!(params[&amp;quot;group-id&amp;quot;])&lt;br /&gt;
       testbed = App.Testbeds.get_testbed!(params[&amp;quot;testbed_id&amp;quot;])&lt;br /&gt;
       result = App.Testbeds.update_testbed(testbed, %{group_id: group.id})&lt;br /&gt;
       IO.inspect result&lt;br /&gt;
      &lt;br /&gt;
       {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
    def updated_groups(testbed_id)  do  &lt;br /&gt;
       testbed = App.Testbeds.get_testbed!(testbed_id)&lt;br /&gt;
       groups = App.Groups.list_groups&lt;br /&gt;
       tail = Enum.filter(groups, fn(item)-&amp;gt; item.id !== testbed.group_id end)&lt;br /&gt;
       head = Enum.filter(groups, fn(item)-&amp;gt; item.id == testbed.group_id end)&lt;br /&gt;
              |&amp;gt;Enum.at(0)&lt;br /&gt;
 &lt;br /&gt;
       [head | tail]&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    &lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;grid grid-cols-4 gap-4 p-8 rounded shadow bg-white&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;h2&amp;gt; Name&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;%= testbed.name %&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;h2&amp;gt; Group&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;form phx-change=&amp;quot;select-group&amp;quot; name=&amp;quot;testbed_id&amp;quot;  &amp;gt;&lt;br /&gt;
               &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;testbed_id&amp;quot; value={testbed.id}/&amp;gt;&lt;br /&gt;
               &amp;lt;select id=&amp;quot;group-selection&amp;quot;  name=&amp;quot;group-id&amp;quot; class=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
                &amp;lt;%= for group &amp;lt;- updated_groups(testbed.id) do %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
                  &amp;lt;%!-- &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}&amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt; --%&amp;gt;&lt;br /&gt;
                  &amp;lt;!-- Write code to reorder with testbed.group_id matching group_id --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
                  &amp;lt;%= if group !== nil do %&amp;gt;&lt;br /&gt;
                      &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}&amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
       &lt;br /&gt;
                  &amp;lt;% end %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
               &amp;lt;/select&amp;gt;&lt;br /&gt;
            &amp;lt;/form&amp;gt;&lt;br /&gt;
          &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
       &amp;lt;% end %&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  has_many :testbeds, TestBed, on_delete: :restrict   # Has many&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://elixirforum.com/t/ecto-has-many-on-delete-protect/49550&lt;br /&gt;
&lt;br /&gt;
https://hexdocs.pm/ecto/Ecto.Changeset.html#unique_constraint/3&lt;br /&gt;
&lt;br /&gt;
____________________________________________________________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== How to Create a Mix Project and Use It in Another Mix Project ==&lt;br /&gt;
&lt;br /&gt;
To create and use a **Mix project** inside another **Mix project** in Elixir, follow the steps below:&lt;br /&gt;
&lt;br /&gt;
=== 1. Create a New Mix Project ===&lt;br /&gt;
&lt;br /&gt;
First, you need to create a new Mix project. Let's call this project `library_project`. Run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mix new library_project --module LibraryProject&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will create a new Elixir Mix project named `library_project`. The `--module` flag specifies the name of the module that will be created (in this case `LibraryProject`).&lt;br /&gt;
&lt;br /&gt;
The directory structure of `library_project` will look like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
library_project/&lt;br /&gt;
  |_ lib/&lt;br /&gt;
      |_ library_project.ex&lt;br /&gt;
  |_ mix.exs&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can then add some basic functionality inside the `library_project/lib/library_project.ex` file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule LibraryProject do&lt;br /&gt;
  def hello do&lt;br /&gt;
    IO.puts &amp;quot;Hello from LibraryProject!&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now, `library_project` is ready to be used by another Mix project.&lt;br /&gt;
&lt;br /&gt;
=== 2. Create a Second Mix Project ===&lt;br /&gt;
&lt;br /&gt;
Next, create the second Mix project where you want to use `library_project`. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mix new app_project --module AppProject&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will create another Elixir project called `app_project`.&lt;br /&gt;
&lt;br /&gt;
The directory structure for this project will look like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
app_project/&lt;br /&gt;
  |_ lib/&lt;br /&gt;
      |_ app_project.ex&lt;br /&gt;
  |_ mix.exs&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 3. Add `library_project` as a Dependency in `app_project` ===&lt;br /&gt;
&lt;br /&gt;
Now, you want to make `library_project` available in `app_project`. There are two main ways to do this:&lt;br /&gt;
&lt;br /&gt;
==== Option 1: Local Dependency (via `path`) ====&lt;br /&gt;
&lt;br /&gt;
If `library_project` is a local project (i.e., it's stored in a different directory), you can add it to the `mix.exs` of `app_project` as a local dependency by specifying the path to `library_project`.&lt;br /&gt;
&lt;br /&gt;
Edit the `mix.exs` of `app_project`:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule AppProject.MixProject do&lt;br /&gt;
  use Mix.Project&lt;br /&gt;
&lt;br /&gt;
  def project do&lt;br /&gt;
    [&lt;br /&gt;
      app: :app_project,&lt;br /&gt;
      version: &amp;quot;0.1.0&amp;quot;,&lt;br /&gt;
      elixir: &amp;quot;~&amp;gt; 1.14&amp;quot;,&lt;br /&gt;
      start_permanent: Mix.env() == :prod,&lt;br /&gt;
      deps: deps()&lt;br /&gt;
    ]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  defp deps do&lt;br /&gt;
    [&lt;br /&gt;
      {:library_project, path: &amp;quot;../library_project&amp;quot;}  # Add the local dependency&lt;br /&gt;
    ]&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here, `{:library_project, path: &amp;quot;../library_project&amp;quot;}` tells Mix to use the local `library_project` located in the `../library_project` directory (relative to `app_project`).&lt;br /&gt;
&lt;br /&gt;
After updating the `mix.exs`, run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd app_project&lt;br /&gt;
mix deps.get&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will fetch the dependency and compile `library_project`.&lt;br /&gt;
&lt;br /&gt;
==== Option 2: Publish and Fetch as a Hex Package ====&lt;br /&gt;
&lt;br /&gt;
If you want to use `library_project` as a package in another project (for example, by publishing it to **Hex.pm**, Elixir’s package manager), you need to publish it to Hex and then add it as a dependency.&lt;br /&gt;
&lt;br /&gt;
1. Publish `library_project` to Hex (if it's public or for your private use).&lt;br /&gt;
2. Add `library_project` to your `app_project`’s `mix.exs` dependencies:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defp deps do&lt;br /&gt;
  [&lt;br /&gt;
    {:library_project, &amp;quot;~&amp;gt; 0.1.0&amp;quot;}  # Specify the published version from Hex&lt;br /&gt;
  ]&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Run `mix deps.get` to fetch the package from Hex.&lt;br /&gt;
&lt;br /&gt;
=== 4. Use `library_project` in `app_project` ===&lt;br /&gt;
&lt;br /&gt;
Now, you can use the functionality from `library_project` inside your `app_project`. For example, in `app_project/lib/app_project.ex`, you can call the function from `library_project`:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule AppProject do&lt;br /&gt;
  def start do&lt;br /&gt;
    IO.puts &amp;quot;Starting app_project!&amp;quot;&lt;br /&gt;
    LibraryProject.hello()  # Call the function from the library_project&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 5. Run the App ===&lt;br /&gt;
&lt;br /&gt;
Finally, you can run your `app_project`:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd app_project&lt;br /&gt;
mix run -e &amp;quot;AppProject.start()&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will print:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Starting app_project!&lt;br /&gt;
Hello from LibraryProject!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Recap of the Process ==&lt;br /&gt;
1. **Create the `library_project`**: Use `mix new` to generate a library project.&lt;br /&gt;
2. **Create the `app_project`**: Create the second project where you will use the library.&lt;br /&gt;
3. **Add the `library_project` as a dependency**:&lt;br /&gt;
   - Use the `path` option to point to the local project or publish it to Hex for public access.&lt;br /&gt;
4. **Use the `library_project` in the `app_project`**: Call functions or use modules from the library inside the second project.&lt;br /&gt;
5. **Run the app**: Use `mix run` to execute the project.&lt;br /&gt;
&lt;br /&gt;
This way, you can reuse code from one Mix project in another by adding it as a dependency.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==z==&lt;br /&gt;
Overloaded functions are extremely common in Elixir applications. They are&lt;br /&gt;
regularly used for recursive functions and for changing behavior based on&lt;br /&gt;
configuration.&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>http://elixirblocks.com/index.php?title=User:Admin&amp;diff=1898</id>
		<title>User:Admin</title>
		<link rel="alternate" type="text/html" href="http://elixirblocks.com/index.php?title=User:Admin&amp;diff=1898"/>
		<updated>2025-04-02T20:32:11Z</updated>

		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.Sandbox do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    {:ok, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;start_task&amp;quot;, _params, socket) do&lt;br /&gt;
    Task.async(fn -&amp;gt; :hello_from_task end)&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_info({ref, result}, socket) do&lt;br /&gt;
    IO.inspect&amp;quot;________________________________________________________________________________&amp;quot;&lt;br /&gt;
    IO.inspect({:task_result_received, ref, result})&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_info({:DOWN, ref, :process, pid, reason}, socket) do&lt;br /&gt;
    IO.inspect({:task_completed, ref, pid, reason})&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    &amp;lt;div&amp;gt;&lt;br /&gt;
      &amp;lt;button phx-click=&amp;quot;start_task&amp;quot;&amp;gt;Start Task&amp;lt;/button&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Barebones&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Async claude ai example&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Explain to me the relationship between handle_info and making an async call&lt;br /&gt;
&lt;br /&gt;
The relationship between handle_info and making async calls in Phoenix LiveView is fundamental to understanding how to handle non-blocking operations in your application.&lt;br /&gt;
&lt;br /&gt;
When you make an asynchronous call in Elixir (like using Task.async), you're creating a separate process that runs independently from your LiveView process. This allows your LiveView to remain responsive while potentially time-consuming operations (like API calls) are happening.&lt;br /&gt;
&lt;br /&gt;
Here's how they work together:&lt;br /&gt;
&lt;br /&gt;
Async Operation Initiation: When you start an async operation using Task.async, it returns a reference to the task.&lt;br /&gt;
Message Passing: When the async task completes, it automatically sends a message back to the process that created it. This message contains the task reference and the result: {ref, result}.&lt;br /&gt;
handle_info Reception: The handle_info/2 callback in LiveView is what receives these messages. It's like a mailbox for your LiveView process that handles any messages not related to LiveView events.&lt;br /&gt;
Process Cleanup: After receiving the result, you typically call Process.demonitor(ref, [:flush]) to clean up process monitoring and prevent receiving a :DOWN message when the task process exits.&lt;br /&gt;
This pattern creates a complete async lifecycle:&lt;br /&gt;
&lt;br /&gt;
Start async task →&lt;br /&gt;
Task runs independently →&lt;br /&gt;
Task completes and sends message →&lt;br /&gt;
handle_info receives message →&lt;br /&gt;
Update LiveView state&lt;br /&gt;
In the example I provided, there's a clear separation of concerns:&lt;br /&gt;
&lt;br /&gt;
Task.async(fn -&amp;gt; api() end) starts the async operation&lt;br /&gt;
handle_info({ref, result}, socket) receives and processes the result&lt;br /&gt;
The LiveView remains responsive throughout the entire operation&lt;br /&gt;
This pattern is what makes LiveView capable of handling concurrent operations while maintaining a responsive UI for users.&lt;br /&gt;
________________________&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.Sandbox do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    # Schedule the API call to happen after mount&lt;br /&gt;
    if connected?(socket), do: Process.send_after(self(), :fetch_data, 0)&lt;br /&gt;
    {:ok, assign(socket, data: nil)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_info(:fetch_data, socket) do&lt;br /&gt;
    # Launch API call in separate process&lt;br /&gt;
    Task.async(fn -&amp;gt; api() end)&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_info({ref, result}, socket) when is_reference(ref) do&lt;br /&gt;
    # Clean up the DOWN message&lt;br /&gt;
    Process.demonitor(ref, [:flush])&lt;br /&gt;
    {:noreply, assign(socket, data: result)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def api do&lt;br /&gt;
    Req.request(url: &amp;quot;https://api.github.com/repos/wojtekmach/req&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    SANDBOX&lt;br /&gt;
    &amp;lt;%= if @data, do: inspect(@data) %&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
___________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 defmodule Heading do&lt;br /&gt;
   use Phoenix.Component&lt;br /&gt;
   def head(assigns) do&lt;br /&gt;
	   ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	     &amp;lt;p&amp;gt;Hello, &amp;lt;%= @headings %&amp;gt;!&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	   &amp;quot;&amp;quot;&amp;quot; &lt;br /&gt;
   end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
   use AppWeb, :live_view  &lt;br /&gt;
   import Heading&lt;br /&gt;
   def mount(_params, _session, socket)  do&lt;br /&gt;
	 {:ok, socket}  &lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
   def headings do &lt;br /&gt;
    [&amp;quot;one&amp;quot;,&amp;quot;two&amp;quot;,&amp;quot;three&amp;quot;]&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
   def render(assigns) do&lt;br /&gt;
	   ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	     &amp;lt;Heading.head  headings={headings()} /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	   &amp;quot;&amp;quot;&amp;quot; &lt;br /&gt;
   end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://app.studyraid.com/en/read/11967/381872/component-communication&lt;br /&gt;
&lt;br /&gt;
https://thepugautomatic.com/2020/08/communicating-between-liveviews-on-the-same-page/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
from(a in Article,&lt;br /&gt;
  order_by: [desc: a.inserted_at],  # Assuming 'inserted_at' is the timestamp for when the article was created or updated&lt;br /&gt;
  limit: 8&lt;br /&gt;
)&lt;br /&gt;
|&amp;gt; Repo.all()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.Landing do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  alias App.Testbeds&lt;br /&gt;
  alias App.Testbeds.Testbed&lt;br /&gt;
  alias App.Repo  # Ensure to alias Repo&lt;br /&gt;
  import Ecto.Query  # Import Ecto.Query to work with queries&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    # Default to ordering by name&lt;br /&gt;
    testbeds = Repo.all(from(t in Testbed, order_by: t.name))&lt;br /&gt;
&lt;br /&gt;
    # Assign the testbeds to the socket for rendering&lt;br /&gt;
    {:ok, assign(socket, testbeds: testbeds, sort: :name)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    &amp;lt;h1&amp;gt;Hello World! YAY&amp;lt;/h1&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;div&amp;gt;&lt;br /&gt;
      &amp;lt;!-- Buttons to toggle sorting --&amp;gt;&lt;br /&gt;
      &amp;lt;button phx-click=&amp;quot;sort_by_name&amp;quot;&amp;gt;Sort by Name&amp;lt;/button&amp;gt;&lt;br /&gt;
      &amp;lt;button phx-click=&amp;quot;sort_by_updated_at&amp;quot;&amp;gt;Sort by Updated By&amp;lt;/button&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;ul&amp;gt;&lt;br /&gt;
      &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
        &amp;lt;li&amp;gt;&amp;lt;%= testbed.name %&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;% end %&amp;gt;&lt;br /&gt;
    &amp;lt;/ul&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;sort_by_name&amp;quot;, _params, socket) do&lt;br /&gt;
    testbeds = Repo.all(from(t in Testbed, order_by: t.name))&lt;br /&gt;
    {:noreply, assign(socket, testbeds: testbeds, sort: :name)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;sort_by_updated_at&amp;quot;, _params, socket) do&lt;br /&gt;
    testbeds = Repo.all(from(t in Testbed, order_by: t.inserted_at))&lt;br /&gt;
    {:noreply, assign(socket, testbeds: testbeds, sort: :inserted_at)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
_______________________________________________________&lt;br /&gt;
&lt;br /&gt;
* Create a form with a post request. &lt;br /&gt;
* Create the route needed for that request&lt;br /&gt;
* Create the controller needed for that route&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Form==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;.form action={~p&amp;quot;/todos&amp;quot;} method=&amp;quot;post&amp;quot; class=&amp;quot;mt-10 space-y-8&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    &amp;lt;label for=&amp;quot;contact_name&amp;quot; class=&amp;quot;block text-sm font-semibold leading-6 text-zinc-800&amp;quot;&amp;gt;&lt;br /&gt;
      Name&lt;br /&gt;
    &amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;input&lt;br /&gt;
      id=&amp;quot;todo&amp;quot;&lt;br /&gt;
      type=&amp;quot;text&amp;quot;&lt;br /&gt;
      name=&amp;quot;todo&amp;quot;&lt;br /&gt;
      class=&amp;quot;mt-2 block w-full rounded-lg text-zinc-900 focus:ring-0 sm:text-sm sm:leading-6 border-zinc-300 focus:border-zinc-400&amp;quot;&lt;br /&gt;
    /&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;button&lt;br /&gt;
    type=&amp;quot;submit&amp;quot;&lt;br /&gt;
    class=&amp;quot;rounded-lg bg-zinc-900 hover:bg-zinc-700 py-2 px-3 text-sm font-semibold leading-6 text-white active:text-white/80&amp;quot;&lt;br /&gt;
  &amp;gt;&lt;br /&gt;
    Save Contact&lt;br /&gt;
  &amp;lt;/button&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/.form&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Controller==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# In your TodoController&lt;br /&gt;
defmodule AppWeb.TodoController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  # Action to handle the form submission (POST request)&lt;br /&gt;
  def create(conn, %{&amp;quot;todo&amp;quot; =&amp;gt; todo_name}) do&lt;br /&gt;
    # Here you can handle the form data (e.g., save it to the database)&lt;br /&gt;
    IO.puts(&amp;quot;Received Todo: #{todo_name}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    # For now, let's just redirect to the home page&lt;br /&gt;
    conn&lt;br /&gt;
    |&amp;gt; put_flash(:info, &amp;quot;Todo saved!&amp;quot;)&lt;br /&gt;
    |&amp;gt; redirect(to: &amp;quot;/&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
________________________________________________________&lt;br /&gt;
&lt;br /&gt;
# CRUD Forms&lt;br /&gt;
&lt;br /&gt;
To understand CRUD forms you will need to understand the following concepts. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Ecto Schema&lt;br /&gt;
* Ecto Context&lt;br /&gt;
* Form Basics&lt;br /&gt;
* form/1&lt;br /&gt;
* simple_form/1&lt;br /&gt;
* changesets&lt;br /&gt;
&lt;br /&gt;
We are not going to go in order. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The Context provides CRUD functions for the chosen data schema. Phoenix contexts define the interface through which other parts of the codebase can interact with the app layer.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_______________________&lt;br /&gt;
* Create routes&lt;br /&gt;
* create page with form (submit get request)&lt;br /&gt;
&lt;br /&gt;
(ecto schema, context, changesets)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_______________________________________________________&lt;br /&gt;
In that case, you really should switch it to prod mode. Instead of doing all that above with the &amp;quot;config/secret.exs&amp;quot; file, create the &amp;quot;.env&amp;quot; in the project root, then add DotenvParser.load_file(&amp;quot;.env&amp;quot;) to &amp;quot;config/runtime.exs&amp;quot; as the first line inside the if config_env() == :prod do. In the .env file, set the DATABASE_URL and SECRET_KEY_BASE. Then run it as MIX_ENV=prod mix phx.server.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def get_titles do&lt;br /&gt;
    urls = [&lt;br /&gt;
      &amp;quot;https://cointelegraph.com/rss&amp;quot;,&lt;br /&gt;
      &amp;quot;https://chaski.huffpost.com/us/auto/vertical/us-news&amp;quot;&lt;br /&gt;
      # Add more RSS feed URLs here&lt;br /&gt;
    ]&lt;br /&gt;
&lt;br /&gt;
    urls&lt;br /&gt;
    |&amp;gt; Enum.map(fn url -&amp;gt;&lt;br /&gt;
      with {:ok, feed} &amp;lt;- ElixirRss.fetch_and_parse(url) do&lt;br /&gt;
        Enum.map(feed.entries, &amp;amp; &amp;amp;1.title)&lt;br /&gt;
      else&lt;br /&gt;
        {:error, reason} -&amp;gt; {:error, reason}&lt;br /&gt;
      end&lt;br /&gt;
    end)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule App do&lt;br /&gt;
&lt;br /&gt;
  def get_titles() do&lt;br /&gt;
    data = [&lt;br /&gt;
      &amp;quot;https://cointelegraph.com/rss&amp;quot;,&lt;br /&gt;
      &amp;quot;https://chaski.huffpost.com/us/auto/vertical/us-news&amp;quot;&lt;br /&gt;
      # Add more RSS feed URLs here&lt;br /&gt;
    ]&lt;br /&gt;
&lt;br /&gt;
    data&lt;br /&gt;
    |&amp;gt; Enum.map(fn url -&amp;gt;&lt;br /&gt;
      case ElixirRss.fetch_and_parse(url) do&lt;br /&gt;
        {:ok, feed} -&amp;gt; feed.entries |&amp;gt; Enum.map(fn entry -&amp;gt; entry end)&lt;br /&gt;
        {:error, reason} -&amp;gt; {:error, reason}&lt;br /&gt;
      end&lt;br /&gt;
    end)&lt;br /&gt;
    |&amp;gt; Enum.map(fn entry_list -&amp;gt;&lt;br /&gt;
      entry_list&lt;br /&gt;
      |&amp;gt; Enum.map(fn entry -&amp;gt; entry.title end)&lt;br /&gt;
    end)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def hello do&lt;br /&gt;
    rss_feeds = [&lt;br /&gt;
      &amp;quot;https://cointelegraph.com/rss&amp;quot;,&lt;br /&gt;
      &amp;quot;https://chaski.huffpost.com/us/auto/vertical/us-news&amp;quot;&lt;br /&gt;
      # Add more RSS feed URLs here&lt;br /&gt;
    ]&lt;br /&gt;
&lt;br /&gt;
    rss_feeds&lt;br /&gt;
    |&amp;gt; Enum.map(fn url -&amp;gt;&lt;br /&gt;
      case ElixirRss.fetch_and_parse(url) do&lt;br /&gt;
        {:ok, feed} -&amp;gt; feed.entries |&amp;gt; Enum.map(fn entry -&amp;gt; entry end)&lt;br /&gt;
        {:error, reason} -&amp;gt; {:error, reason}&lt;br /&gt;
      end&lt;br /&gt;
    end)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    if connected?(socket) do&lt;br /&gt;
      Phoenix.PubSub.subscribe(App.PubSub, &amp;quot;message&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
    {:ok, assign(socket, message_item: &amp;quot;different&amp;quot;)}&lt;br /&gt;
  end&lt;br /&gt;
  def handle_info({:pubsub_transmission, text}, socket) do&lt;br /&gt;
    IO.inspect &amp;quot;pub sub working&amp;quot;&lt;br /&gt;
    {:noreply, assign(socket, message_item: text)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def loop(data) do&lt;br /&gt;
     IO.inspect data&lt;br /&gt;
     if data &amp;gt; 0 do&lt;br /&gt;
      IO.inspect &amp;quot;notify&amp;quot;&lt;br /&gt;
      # run code to compare files, loop. If different run pubsub code below&lt;br /&gt;
      :timer.sleep(2000)&lt;br /&gt;
      loop(data-1)&lt;br /&gt;
&lt;br /&gt;
     end&lt;br /&gt;
     if data &amp;lt;= 0 do&lt;br /&gt;
&lt;br /&gt;
      Phoenix.PubSub.broadcast(App.PubSub, &amp;quot;message&amp;quot;, {:pubsub_transmission, &amp;quot;data&amp;quot;})&lt;br /&gt;
      &amp;quot;done&amp;quot;&lt;br /&gt;
     end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;change-text&amp;quot;, _params, socket) do&lt;br /&gt;
    spawn(fn -&amp;gt; loop(3) end)&lt;br /&gt;
    {:noreply, assign(socket, message_item: &amp;quot;START&amp;quot; )}&lt;br /&gt;
  end&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
&lt;br /&gt;
    # AppWeb.PageLive.loop(&amp;quot;xxx&amp;quot;)&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    SANDBOX&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;.button phx-click=&amp;quot;change-text&amp;quot; value={@message_item}&amp;gt;CLICK ME&amp;lt;/.button&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;%= @message_item %&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
elixir :   1.16.2&lt;br /&gt;
&lt;br /&gt;
Erl:   20&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# PostGres&lt;br /&gt;
Created Saturday 18 February 2023&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Launch [PostGres](#PostGres) from Terminal&lt;br /&gt;
------------------------------------------&lt;br /&gt;
sudo -u postgres psql&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Set User Permission&lt;br /&gt;
-------------------&lt;br /&gt;
&amp;lt;https://commandprompt.com/education/how-to-create-a-superuser-in-postgresql/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ALTER USER user_name WITH PASSWORD 'new_password';&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Run Post Gres Commands&lt;br /&gt;
----------------------&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
sudo -i -u postgres&lt;br /&gt;
psql&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Create and Delete Database&lt;br /&gt;
&lt;br /&gt;
CREATE DATABASE name;&lt;br /&gt;
DROP DATABASE name;&lt;br /&gt;
## View user list&lt;br /&gt;
&lt;br /&gt;
\du&lt;br /&gt;
&lt;br /&gt;
 View all databases&lt;br /&gt;
&lt;br /&gt;
postgres=# \l&lt;br /&gt;
&lt;br /&gt;
 Change databases&lt;br /&gt;
&lt;br /&gt;
postgres=# \c    name-of-database&lt;br /&gt;
&lt;br /&gt;
View Tables&lt;br /&gt;
&lt;br /&gt;
After you change databases and are selected on one of them do this:&lt;br /&gt;
&lt;br /&gt;
\dt&lt;br /&gt;
&lt;br /&gt;
SELECT * FROM mytablename;&lt;br /&gt;
&lt;br /&gt;
EMPTY TABLE&lt;br /&gt;
DELETE FROM name-of-table&lt;br /&gt;
&lt;br /&gt;
CREATE TABLE&lt;br /&gt;
&lt;br /&gt;
CREATE TABLE table_name(&lt;br /&gt;
   column1 datatype,&lt;br /&gt;
   column2 datatype,&lt;br /&gt;
   column3 datatype,&lt;br /&gt;
   .....&lt;br /&gt;
   columnN datatype,&lt;br /&gt;
   PRIMARY KEY( one or more columns )&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
INSERT&lt;br /&gt;
&lt;br /&gt;
INSERT INTO ITEMS(id, name) VALUES(1,'htvjbjbgni');     Strings are single quote&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Roadmap==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.ItemsLive do&lt;br /&gt;
    use AppWeb, :live_view  &lt;br /&gt;
    def mount(_params, _session, socket)  do&lt;br /&gt;
      {:ok, assign(socket, switches: [&amp;quot;grindy&amp;quot;,&amp;quot;sonic&amp;quot;,&amp;quot;ogre&amp;quot;])}  &lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    def handle_event(&amp;quot;run&amp;quot;,_params,socket) do  &lt;br /&gt;
        &lt;br /&gt;
        IO.inspect &amp;quot;DOWNLOAD VIA SSH&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        {:noreply, redirect(socket, to: &amp;quot;/download&amp;quot;)}&lt;br /&gt;
&lt;br /&gt;
    end&lt;br /&gt;
   &lt;br /&gt;
&lt;br /&gt;
    def render(assigns) do&lt;br /&gt;
        &lt;br /&gt;
        ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        &amp;lt;ul&amp;gt;&lt;br /&gt;
        &amp;lt;%= for switch &amp;lt;- @switches do %&amp;gt;&lt;br /&gt;
         &amp;lt;a phx-submit=&amp;quot;click&amp;quot; href=&amp;quot;/download&amp;quot;&amp;gt;  &amp;lt;li&amp;gt; &amp;lt;%= switch %&amp;gt;  &amp;lt;/li&amp;gt; &amp;lt;/a&amp;gt;&lt;br /&gt;
&lt;br /&gt;
        &amp;lt;%end%&amp;gt;&lt;br /&gt;
        &amp;lt;/ul&amp;gt;&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot; &lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Notes==&lt;br /&gt;
List of Switches and the option to select the one needed.&lt;br /&gt;
Button to download JSON file.&lt;br /&gt;
Drag and Drop Palette to upload JSON file.&lt;br /&gt;
&lt;br /&gt;
After JSON file is uploaded a button titled &amp;quot;Make Active&amp;quot; is available.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://medium.com/@fraiha26/pushing-events-to-livecomponents-from-js-hooks-w-phoenix-elixir-d5544d4c3dfa&lt;br /&gt;
&lt;br /&gt;
Changeset notes and forms&lt;br /&gt;
&lt;br /&gt;
NOTE: Use case statements for pattern matching&lt;br /&gt;
____________________________________________&lt;br /&gt;
&lt;br /&gt;
Create a basic &amp;lt;.form&amp;gt;&amp;lt;/form&amp;gt; without error handling&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&amp;lt;.form :let={f} for={@changeset}  action={~p&amp;quot;/items&amp;quot;} &amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;.input field={f[:title]} type=&amp;quot;text&amp;quot; label=&amp;quot;Title&amp;quot; /&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
  &amp;lt;.button&amp;gt;Save Item&amp;lt;/.button&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;/.form&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With error handling looks like this:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;.form :let={f} for={@changeset}  action={~p&amp;quot;/items&amp;quot;} &amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;.error :if={@changeset.action}&amp;gt;&lt;br /&gt;
    Oops, something went wrong! Please check the errors below.&lt;br /&gt;
  &amp;lt;/.error&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;.input field={f[:title]} type=&amp;quot;text&amp;quot; label=&amp;quot;Title&amp;quot; /&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
  &amp;lt;.button&amp;gt;Save Item&amp;lt;/.button&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;/.form&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Create the routes for render and post to endpoint.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The controller for the page render needs to pass in the changeset via ```Items.change_item(%Item{})```&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  def new(conn, _params) do&lt;br /&gt;
    changeset = Items.change_item(%Item{})&lt;br /&gt;
    render(conn, :new, changeset: changeset)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Post route without error handling&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  def create(conn, %{&amp;quot;item&amp;quot; =&amp;gt; item_params}) do&lt;br /&gt;
    case Items.create_item(item_params) do&lt;br /&gt;
      {:ok, item} -&amp;gt;&lt;br /&gt;
        conn&lt;br /&gt;
        |&amp;gt; put_flash(:info, &amp;quot;Item created successfully.&amp;quot;)&lt;br /&gt;
        |&amp;gt; redirect(to: ~p&amp;quot;/items/#{item}&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With error handling&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  def create(conn, %{&amp;quot;item&amp;quot; =&amp;gt; item_params}) do&lt;br /&gt;
    case Items.create_item(item_params) do&lt;br /&gt;
      {:ok, item} -&amp;gt;&lt;br /&gt;
        conn&lt;br /&gt;
        |&amp;gt; put_flash(:info, &amp;quot;Item created successfully.&amp;quot;)&lt;br /&gt;
        |&amp;gt; redirect(to: ~p&amp;quot;/items/#{item}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
      {:error, %Ecto.Changeset{} = changeset} -&amp;gt;&lt;br /&gt;
        render(conn, :new, changeset: changeset)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_____________________________________________&lt;br /&gt;
https://medium.com/@vincentlin/phoenix-very-simple-form-c4b121697fcb&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''home.html.heex'''&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&amp;lt;form action=&amp;quot;/submit&amp;quot; method=&amp;quot;post&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;label for=&amp;quot;name&amp;quot;&amp;gt;Name:&amp;lt;/label&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;input type=&amp;quot;text&amp;quot; id=&amp;quot;name&amp;quot; name=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;_csrf_token&amp;quot; value={@csrf_token} /&amp;gt;&lt;br /&gt;
  &amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Submit&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
page_controller.ex&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.PageController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  def home(conn, _params) do&lt;br /&gt;
    # The home page is often custom made,&lt;br /&gt;
&lt;br /&gt;
    csrf_token = Plug.CSRFProtection.get_csrf_token()&lt;br /&gt;
    render(conn, :home, csrf_token: csrf_token)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def submit(conn, _params) do&lt;br /&gt;
    # The home page is often custom made,&lt;br /&gt;
     IO.inspect(_params)&lt;br /&gt;
     IO.inspect &amp;quot;___________________________&amp;quot;&lt;br /&gt;
    csrf_token = Plug.CSRFProtection.get_csrf_token()&lt;br /&gt;
    render(conn, :home, csrf_token: csrf_token)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
router.ex&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  scope &amp;quot;/&amp;quot;, AppWeb do&lt;br /&gt;
    pipe_through :browser&lt;br /&gt;
    post &amp;quot;/submit&amp;quot;, PageController, :submit&lt;br /&gt;
    get &amp;quot;/&amp;quot;, PageController, :home&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ecto.Adapters.SQL.query(Repo, &amp;quot;select * from artists where id=1&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ecto cheatsheet:  https://hexdocs.pm/ecto/crud.html&lt;br /&gt;
__________________________________________________________________&lt;br /&gt;
Most programming languages give you the ability to set global state by creating globally scoped variables. Elixir does not do this. Instead, Elixir provides a tool called a &amp;quot;processes&amp;quot; to persist  state. Elixir applications are composed of these &amp;quot;processes&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
Processes by themselves are complicated to use, thus Elixir provides abstractions to make working with processes easier. One of these abstractions is called a GenServer.&lt;br /&gt;
&lt;br /&gt;
GenServers are not only used to store state, they are also used to invoke work independent of the main application process. &lt;br /&gt;
&lt;br /&gt;
==Creating a GenServer to Store State==&lt;br /&gt;
&lt;br /&gt;
To Create a GenServer, start by creating a basic Module that ''uses'' the GenServer module (image below)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule App do  &lt;br /&gt;
  use GenServer&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We now need to describe the actions we want to perform. Being that this is used to store state, we will use basic CRUD actions: Create, Read, Update, Delete. To begins, empty functions describing each action is created.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule App do&lt;br /&gt;
   def create do &lt;br /&gt;
&lt;br /&gt;
   end&lt;br /&gt;
   def read do &lt;br /&gt;
&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
   def update do  &lt;br /&gt;
&lt;br /&gt;
   end &lt;br /&gt;
&lt;br /&gt;
   def delete do &lt;br /&gt;
&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==What now?==&lt;br /&gt;
&lt;br /&gt;
To fill in the functions with the appropriate code we must first have a basic understanding of how GenServers are structured.&lt;br /&gt;
&lt;br /&gt;
GenServers are composed of the GenServer module invoking callbacks. The callbacks have built in names that you, as a developer have to use.&lt;br /&gt;
&lt;br /&gt;
These callbacks are named:&lt;br /&gt;
&lt;br /&gt;
* init&lt;br /&gt;
* handle_cast&lt;br /&gt;
* handle_call&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To demonstrate, here is an example :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{:ok, pid} = GenServer.start(ModuleNameOfGenServer, %{})&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above function named &amp;quot;start&amp;quot; calls the function named init in the Module below.&lt;br /&gt;
In GenServer syntax the name of the GenServer functions always invoke callbacks that are determined by the language. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule ModuleNameOfGenServer do&lt;br /&gt;
  # 1&lt;br /&gt;
  def init(state \\ %{}) do&lt;br /&gt;
    {:ok, state}&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is a list of the GenServer functions and their corresponding callbacks.&lt;br /&gt;
&lt;br /&gt;
* GenServer.start/1  --&amp;gt;       init/1&lt;br /&gt;
* GenServer.call/3   --&amp;gt;       def handle_call/3&lt;br /&gt;
* GenServer.cast/2   --&amp;gt;       handle_cast/2&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Start and Call ==&lt;br /&gt;
&lt;br /&gt;
Call and Cast can be used to perform the same operations. The &lt;br /&gt;
&lt;br /&gt;
__________________________________________________________&lt;br /&gt;
Genserver timed events&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule Go do&lt;br /&gt;
  use GenServer&lt;br /&gt;
&lt;br /&gt;
  def go() do&lt;br /&gt;
    GenServer.start_link(__MODULE__, [])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def init(list) do&lt;br /&gt;
    :timer.apply_interval(1000, __MODULE__, :add, [self(), &amp;quot;weeeee&amp;quot;])&lt;br /&gt;
    {:ok, list}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def view(pid) do&lt;br /&gt;
    GenServer.call(pid, :view)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_call(:view, _from, list) do&lt;br /&gt;
    {:reply, list, list}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def add(pid, new_item) do&lt;br /&gt;
    GenServer.call(pid, {:item, new_item})&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_call({:item, new_item}, _from, state) do&lt;br /&gt;
    result = [new_item] ++ state&lt;br /&gt;
    {:reply, result, result}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule ShoppingList do&lt;br /&gt;
  use GenServer&lt;br /&gt;
&lt;br /&gt;
  def start_link() do&lt;br /&gt;
    GenServer.start_link(ShoppingList, [])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def init(list) do&lt;br /&gt;
    {:ok, list}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def view(pid) do&lt;br /&gt;
    GenServer.call(pid, :view)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_call(:view, _from, list) do&lt;br /&gt;
    {:reply, list, list}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def add(pid, new_item) do&lt;br /&gt;
    GenServer.call(pid, {:item, new_item})&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_call({:item, new_item}, _from, state) do&lt;br /&gt;
    result = [new_item] ++ state&lt;br /&gt;
    {:reply, result, result}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://blog.appsignal.com/2018/06/12/elixir-alchemy-deconstructing-genservers.html&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule KeyValue do&lt;br /&gt;
  # 1&lt;br /&gt;
  def init(state \\ %{}) do&lt;br /&gt;
    {:ok, state}&lt;br /&gt;
  end&lt;br /&gt;
 &lt;br /&gt;
  # 2&lt;br /&gt;
  def handle_cast({:put, key, value}, state) do&lt;br /&gt;
    {:noreply, Map.put(state, key, value)}&lt;br /&gt;
  end&lt;br /&gt;
 &lt;br /&gt;
  # 3&lt;br /&gt;
  def handle_call({:get, key}, _from, state) do&lt;br /&gt;
    {:reply, Map.fetch!(state, key), state}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
# {:ok, pid} = GenServer.start(KeyValue, %{})&lt;br /&gt;
# GenServer.cast(pid, {:put, :foo, &amp;quot;bar&amp;quot;})&lt;br /&gt;
# GenServer.call(pid, {:get, :foo})&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Send messages via these functions wrapped in module functions .You can look at these are functions used to fire &amp;quot;GenServer Events&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
* start_link&lt;br /&gt;
* GenServer.call&lt;br /&gt;
* GenServer.cast&lt;br /&gt;
&lt;br /&gt;
The corresponding server functions that reply are:&lt;br /&gt;
&lt;br /&gt;
* init&lt;br /&gt;
* handle__call&lt;br /&gt;
* handle_cast&lt;br /&gt;
* &lt;br /&gt;
&lt;br /&gt;
These can be looked at as &amp;quot;listeners&amp;quot; - in JavaScript parlance. &lt;br /&gt;
__________________________________________&lt;br /&gt;
&lt;br /&gt;
If you have experience with programming languages other than Elixir the idea of GenServers may be very foreign and require a strong context shift to learn. This document is intended to simplify the concept.&lt;br /&gt;
&lt;br /&gt;
* What: GenServers are simply a way to hold state and/or invoke actions based on incoming events. &lt;br /&gt;
* when &lt;br /&gt;
* where&lt;br /&gt;
* why&lt;br /&gt;
* how&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
___________________________________________&lt;br /&gt;
GenServer timer example&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule Timer do&lt;br /&gt;
  use GenServer&lt;br /&gt;
&lt;br /&gt;
  def init(_) do&lt;br /&gt;
    :timer.send_interval(1000, :xyz)&lt;br /&gt;
    {:ok, 0}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_info(:xyz, state) do&lt;br /&gt;
    IO.inspect(state)&lt;br /&gt;
    {:noreply, state + 1}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
[&lt;br /&gt;
   {&lt;br /&gt;
     data:{&lt;br /&gt;
        creationTime,&lt;br /&gt;
        publishDate,&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
     featured:{&lt;br /&gt;
        setAmount,&lt;br /&gt;
        items:[]&lt;br /&gt;
     },&lt;br /&gt;
&lt;br /&gt;
     children:{&lt;br /&gt;
        setAmount,&lt;br /&gt;
        items:[]&lt;br /&gt;
     },&lt;br /&gt;
     links:{&lt;br /&gt;
        setAmount,&lt;br /&gt;
        items:[]&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
jason.encode / jason.decode&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  def run(num) do&lt;br /&gt;
&lt;br /&gt;
    Enum.each(0..99999, fn(_x) -&amp;gt;&lt;br /&gt;
      task = Task.async(fn -&amp;gt; num + _x end)&lt;br /&gt;
    IO.inspect Task.await(task)&lt;br /&gt;
  end)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enum.map(feed.entries, fn x -&amp;gt; %{url: x.url, title: x.title} end)&lt;br /&gt;
&lt;br /&gt;
App is split:&lt;br /&gt;
&lt;br /&gt;
App that captures RSS in UI and lets admin select stories. THere are settings to determine the number of FEATURED,CHILD and LINK stories.&lt;br /&gt;
News categories are horizontal and scrollable.&lt;br /&gt;
This exports a json doc with all RSS data for each story.&lt;br /&gt;
The &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
App that reads the json data. This app creates tables and is the front end.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://stephenbussey.com/tags/elixir.html&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule AppWeb.GroupLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  alias App.TestBeds&lt;br /&gt;
  alias App.Groups&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    {:ok, assign(socket, testbeds: TestBeds.list_testbeds(), groups: Groups.list_groups())}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;select-group&amp;quot;, params, socket)  do  &lt;br /&gt;
     group = App.Groups.get_group!(params[&amp;quot;group-id&amp;quot;])&lt;br /&gt;
     testbed = App.TestBeds.get_test_bed!(params[&amp;quot;testbed_id&amp;quot;])&lt;br /&gt;
     App.TestBeds.update_test_bed(testbed, %{group_id: group.id})&lt;br /&gt;
     {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def updated_groups(testbed_id)  do  &lt;br /&gt;
     testbed = App.TestBeds.get_test_bed!(testbed_id)&lt;br /&gt;
     groups = App.Groups.list_groups&lt;br /&gt;
     tail = Enum.filter(groups, fn(item)-&amp;gt; item.id !== testbed.group_id end)&lt;br /&gt;
     head = Enum.filter(groups, fn(item)-&amp;gt; item.id == testbed.group_id end)&lt;br /&gt;
            |&amp;gt;Enum.at(0)&lt;br /&gt;
    [head | tail]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        &amp;lt;%= for testbed &amp;lt;- Enum.sort_by(@testbeds , &amp;amp;(&amp;quot;#{&amp;amp;1.name}&amp;quot;), :asc)do %&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;grid grid-cols-4 gap-4 p-8 rounded shadow bg-white&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;h2&amp;gt; Name&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;%= testbed.name %&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;h2&amp;gt; Group&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div&amp;gt;&lt;br /&gt;
            &amp;lt;form phx-change=&amp;quot;select-group&amp;quot; name=&amp;quot;testbed_id&amp;quot;  &amp;gt;&lt;br /&gt;
               &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;testbed_id&amp;quot; value={testbed.id}/&amp;gt;&lt;br /&gt;
               &amp;lt;select id=&amp;quot;group-selection&amp;quot;  name=&amp;quot;group-id&amp;quot; class=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;%= for group &amp;lt;- updated_groups(testbed.id) do %&amp;gt;&lt;br /&gt;
                  &amp;lt;%= if group !== nil do %&amp;gt;&lt;br /&gt;
                      &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}&amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
                      &amp;lt;%else%&amp;gt;&lt;br /&gt;
                      &amp;lt;option value= {&amp;quot;Unassigned&amp;quot;}&amp;gt;NONE&amp;lt;/option&amp;gt;&lt;br /&gt;
                  &amp;lt;% end %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
               &amp;lt;/select&amp;gt;&lt;br /&gt;
            &amp;lt;/form&amp;gt;&lt;br /&gt;
          &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
       &amp;lt;% end %&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Developer Notes ==&lt;br /&gt;
===Groups Feature ===&lt;br /&gt;
To complete this feature do these things.&lt;br /&gt;
* Run through the steps in [http://elixirblocks.com/index.php?title=Create_Foreign_Key_Relationship_Between_Ecto_Tables  | this document] to create Group table.&lt;br /&gt;
* Groups have these fields  '''name: string''', '''description: string''' and '''color: string'''  &lt;br /&gt;
* Add unique constraint in migration file: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def change do&lt;br /&gt;
     create unique_index(:groups, [:name])&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Port over Group LiveView code (temporarily placed at discussion page).&lt;br /&gt;
* On completion '''possibly''', create a Group named '''No Group''' and set all Testbeds to it.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
________&lt;br /&gt;
https://blog.appsignal.com/2022/10/11/phoenix-liveview-018-new-special-html-attributes.html&lt;br /&gt;
https://blixtdev.com/whats-new-phoenix-1-7/&lt;br /&gt;
https://github.com/devato/inertia_phoenix&lt;br /&gt;
https://phoenixonrails.com/blog/you-can-stop-using-form-for-in-phoenix&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://samuelmullen.com/articles/phoenix_templates_rendering_and_layouts&lt;br /&gt;
&lt;br /&gt;
WorkFlow of Todo App in Both LiveView and DeadView.&lt;br /&gt;
&lt;br /&gt;
Note:&lt;br /&gt;
&lt;br /&gt;
Create foreign key data.&lt;br /&gt;
Create live view. List all testbeds and form to assign each a group by group-name.&lt;br /&gt;
&lt;br /&gt;
Repeat in dead view&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Mental model and data flows&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
home.html.heex&lt;br /&gt;
&amp;lt;a href=&amp;quot;/data&amp;quot; name=&amp;quot;we are the world&amp;quot; &amp;gt;  click me&amp;lt;/a&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;%= @message %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
page controller&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  def home(conn, _params) do&lt;br /&gt;
    IO.inspect _params&lt;br /&gt;
    render(conn, :home, message: &amp;quot;Hello&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
get &amp;quot;/:yay&amp;quot;, PageController, :index&lt;br /&gt;
&lt;br /&gt;
get &amp;quot;/&amp;quot;, PageController, :index&lt;br /&gt;
&lt;br /&gt;
* Explain control flow of &amp;quot;Dead Views&amp;quot; and the Generator HTML Control flow.&lt;br /&gt;
* Proper Way to use Modal&lt;br /&gt;
* How to give Focus to Fields in Modal (or other forms fields)&lt;br /&gt;
* &lt;br /&gt;
* &lt;br /&gt;
* How to Create Database Seed Data.&lt;br /&gt;
* How to structure code so controller code is in one file and HTML Heex is in another&lt;br /&gt;
* How to Use Generators in a Real World Project&lt;br /&gt;
* How to Work with Database Data via Basic Commands and Custom Change sets.&lt;br /&gt;
* How to Render Database Data to LiveView (via Context Commands).&lt;br /&gt;
* How to Create a Chat using PubSub.&lt;br /&gt;
* How to Create Event Handlers in LiveView&lt;br /&gt;
* How to Create a Dynamic Route from Scratch.&lt;br /&gt;
* How to Use Elixirs Template language&lt;br /&gt;
* How to Work with Modal&lt;br /&gt;
* How to Use CSS From Scratch (Without bundler)&lt;br /&gt;
* How to use JS hooks&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
______________________&lt;br /&gt;
https://studioindie.co/blog/heex-guide/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
get &amp;quot;/&amp;quot;, PageController, :some-atom    #This is the route. some-atom is the controller name&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  def some-atom(conn, _params) do                 # controller name&lt;br /&gt;
    # The home page is often custom made,&lt;br /&gt;
    # so skip the default app layout.&lt;br /&gt;
    render(conn, :some-atom, layout: false)      # :some-atom is template name&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Controllers page_html.ex contains &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageHTML do&lt;br /&gt;
  use AppWeb, :html&lt;br /&gt;
&lt;br /&gt;
  embed_templates &amp;quot;page_html/*&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''page_html''' is the name of the folder in '''Controllers/page_html'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Controllers/page_html/some-atom.html.heex  (this is the template) &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__________________________________________&lt;br /&gt;
Set all association with preload:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  def list_groups do&lt;br /&gt;
    Repo.all(Group)&lt;br /&gt;
     |&amp;gt; Repo.preload([:testbeds])&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Insert Child into Parent ===&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
App.get_group!(2) # arg is id&lt;br /&gt;
|&amp;gt; Ecto.build_assoc(:testbeds)&lt;br /&gt;
|&amp;gt; Repo.insert()&lt;br /&gt;
&lt;br /&gt;
Or&lt;br /&gt;
&lt;br /&gt;
group = App.get_group!(2) # arg is id&lt;br /&gt;
&lt;br /&gt;
testbeds = Ecto.build_assoc(group, :testbeds)&lt;br /&gt;
&lt;br /&gt;
App.Group.create_group(testbeds)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
group = App.Groups.get_group!(1)&lt;br /&gt;
thing = Ecto.build_assoc(group, :testbeds, name: &amp;quot;DUMB&amp;quot;)&lt;br /&gt;
alias App.{Repo}&lt;br /&gt;
Repo.insert(thing)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
avatar = %Avatar{nick_name: &amp;quot;Elixir&amp;quot;, pic_url: &amp;quot;http://elixir-lang.org/images/logo.png&amp;quot;}&lt;br /&gt;
user = %User{name: &amp;quot;John Doe&amp;quot;, email: &amp;quot;john.doe@example.com&amp;quot;, avatar: avatar}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://www.reddit.com/r/elixir/comments/oh318k/is_there_a_way_to_avoid_ectoassociationnotloaded/h4mmcfi/?utm_source=share&amp;amp;utm_medium=web3x&amp;amp;utm_name=web3xcss&amp;amp;utm_term=1&amp;amp;utm_content=share_button&lt;br /&gt;
&lt;br /&gt;
# Create Group Table&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
mix phx.gen.html Groups Group groups name:string  &lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Set the resources / &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
mix ecto.migrate&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For testbeds create a migration file and add this field:   group_id:references:groups&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
def change do&lt;br /&gt;
    alter table(:testbeds) do    # customize to your code&lt;br /&gt;
      add :group_id, references(:groups)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Update Groups Schema (Don't forget alias / has_many)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule App.Groups.Group do&lt;br /&gt;
	use Ecto.Schema&lt;br /&gt;
	import Ecto.Changeset&lt;br /&gt;
	alias App.Testbeds.Testbed   # Alias!&lt;br /&gt;
&lt;br /&gt;
	schema &amp;quot;posts&amp;quot; do&lt;br /&gt;
		field :body, :string&lt;br /&gt;
		field :title, :string&lt;br /&gt;
		has_many :testbeds, Testbed    # Has many&lt;br /&gt;
&lt;br /&gt;
		timestamps()&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	@doc false&lt;br /&gt;
	def changeset(post, attrs) do&lt;br /&gt;
		post&lt;br /&gt;
		|&amp;gt; cast(attrs, [:title, :body])&lt;br /&gt;
		|&amp;gt; validate_required([:title, :body])&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
TESTBEDS Schema&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule App.Testbeds.Testbed do&lt;br /&gt;
  use Ecto.Schema&lt;br /&gt;
  import Ecto.Changeset&lt;br /&gt;
  alias App.Groups.Group      # Alias&lt;br /&gt;
  schema &amp;quot;testbeds&amp;quot; do&lt;br /&gt;
    field :name, :string&lt;br /&gt;
    belongs_to :group, Group    # Belongs to&lt;br /&gt;
    timestamps()&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  @doc false&lt;br /&gt;
  def changeset(testbed, attrs) do&lt;br /&gt;
    testbed&lt;br /&gt;
    |&amp;gt; cast(attrs, [:name])&lt;br /&gt;
    |&amp;gt; validate_required([:name])&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
_____________________________________&lt;br /&gt;
Side notes.&lt;br /&gt;
&lt;br /&gt;
defmodule App.Repo.Migrations.CreateTestbeds do&lt;br /&gt;
  use Ecto.Migration&lt;br /&gt;
&lt;br /&gt;
  def change do&lt;br /&gt;
    create table(:testbeds) do&lt;br /&gt;
      add :name, :string&lt;br /&gt;
      add :group_id, references(:groups, on_delete: :nothing)&lt;br /&gt;
&lt;br /&gt;
      timestamps()&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    create index(:testbeds, [:group_id])&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
________________________________&lt;br /&gt;
&lt;br /&gt;
mix phx.gen.context Comments Comment comments name:string content:text post_id:references:posts&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
mix phx.gen.html Testbeds Testbed testbeds name:string  group_id:references:groups&lt;br /&gt;
&lt;br /&gt;
https://graffino.com/web-development/first-steps-in-elixir-and-phoenix-create-a-blog-prototype&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://blog.logrocket.com/getting-started-ecto-phoenix/&lt;br /&gt;
&lt;br /&gt;
https://serokell.io/blog/ecto-guide-for-beginners&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
mix phx.gen.html Testbeds Testbed testbeds name:string&lt;br /&gt;
&lt;br /&gt;
mix phx.gen.html Groups Group groups name:string&lt;br /&gt;
&lt;br /&gt;
Create migration for &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
mix ecto.gen.migration add_testbed_group_reference&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Migration:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  def change do&lt;br /&gt;
    alter table(:testbeds) do    # customize to your code&lt;br /&gt;
      add :group_id, references(:groups)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Manually Change:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule App.Group do&lt;br /&gt;
  use Ecto.Schema&lt;br /&gt;
&lt;br /&gt;
  schema &amp;quot;groups&amp;quot; do&lt;br /&gt;
    field :title, :string&lt;br /&gt;
    field :tagline, :string&lt;br /&gt;
    has_many :testbeds, App.Testbed&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
testbeds&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule App.Repo.Migrations.AddTextbedGroups do&lt;br /&gt;
  use Ecto.Migration&lt;br /&gt;
&lt;br /&gt;
  def change do&lt;br /&gt;
    create table(:testbeds) do&lt;br /&gt;
      add :name, :string&lt;br /&gt;
      add :group_id, references(:groups)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
# lib/app/testbeds.ex&lt;br /&gt;
&lt;br /&gt;
defmodule App.Testbed do&lt;br /&gt;
  use Ecto.Schema&lt;br /&gt;
&lt;br /&gt;
  schema &amp;quot;testbedss&amp;quot; do&lt;br /&gt;
    field :name, :string&lt;br /&gt;
    belongs_to :group, App.Group&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_____________________&lt;br /&gt;
&lt;br /&gt;
%App.TestBeds.TestBed{&lt;br /&gt;
  __meta__: #Ecto.Schema.Metadata&amp;lt;:loaded, &amp;quot;testbeds&amp;quot;&amp;gt;,&lt;br /&gt;
  id: 1,&lt;br /&gt;
  developer: &amp;quot;None&amp;quot;,&lt;br /&gt;
  name: &amp;quot;sdfsd&amp;quot;,&lt;br /&gt;
  owner: &amp;quot;sdfsddf&amp;quot;,&lt;br /&gt;
  note: &amp;quot;sdsfsddf&amp;quot;,&lt;br /&gt;
  status: &amp;quot;Available&amp;quot;,&lt;br /&gt;
  url: &amp;quot;sdf&amp;quot;,&lt;br /&gt;
  version: &amp;quot;ddf&amp;quot;,&lt;br /&gt;
  manager: &amp;quot;sf&amp;quot;,&lt;br /&gt;
  inserted_at: ~N[2023-08-21 13:45:39],&lt;br /&gt;
  updated_at: ~N[2023-08-21 13:45:44]&lt;br /&gt;
}&lt;br /&gt;
________________________________________________________________---&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.SendLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  &lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    {:ok, socket}&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  def handle_event(&amp;quot;send&amp;quot;, %{&amp;quot;text&amp;quot; =&amp;gt; text}, socket) do&lt;br /&gt;
&lt;br /&gt;
    AppWeb.Endpoint.broadcast(topic, &amp;quot;message&amp;quot;, text)&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  defp topic do&lt;br /&gt;
    &amp;quot;chat&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def render(assigns)do   &lt;br /&gt;
   ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
  &amp;lt;h1&amp;gt;Send Message&amp;lt;/h1&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;form phx-submit=&amp;quot;send&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;text&amp;quot; /&amp;gt;&lt;br /&gt;
    &amp;lt;button type=&amp;quot;submit&amp;quot;&amp;gt;Send&amp;lt;/button&amp;gt;&lt;br /&gt;
  &amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
______________________________________________________________&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.ReceiveLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  &lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    if connected?(socket) do&lt;br /&gt;
      AppWeb.Endpoint.subscribe(topic)&lt;br /&gt;
    end&lt;br /&gt;
    {:ok, assign(socket, messages: &amp;quot;&amp;quot;)}&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def handle_info(%{event: &amp;quot;message&amp;quot;, payload: message}, socket) do&lt;br /&gt;
    IO.inspect message&lt;br /&gt;
    {:noreply, assign(socket, messages: message)}&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  defp topic do&lt;br /&gt;
    &amp;quot;chat&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns)do   &lt;br /&gt;
   ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
  &amp;lt;h1&amp;gt;ChatLive&amp;lt;/h1&amp;gt;&lt;br /&gt;
  &amp;lt;%= @messages %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
______________________________________________________________&lt;br /&gt;
When you hover over a list of items this hook finds items with the same name and sets the opacity of all others to 0. You see all the items similar to the one you are hovering over.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
TestbedVersionHover: {&lt;br /&gt;
			// https://jsfiddle.net/IrvinDominin/7K2Z3/&lt;br /&gt;
            mounted() {&lt;br /&gt;
&lt;br /&gt;
                let rows = document.getElementsByClassName(&amp;quot;testbed-version&amp;quot;)&lt;br /&gt;
                // this.ele = element&lt;br /&gt;
				// rows = this.ele;&lt;br /&gt;
                &lt;br /&gt;
				for (var i = 0; i &amp;lt; rows.length; i++) {&lt;br /&gt;
					rows[i].onmouseenter = function (event) {&lt;br /&gt;
						for (var j = 0; j &amp;lt; rows.length; j++) {&lt;br /&gt;
							let preversion = this.textContent;&lt;br /&gt;
							let version = preversion.slice(0,5)&lt;br /&gt;
							let compareVersion = rows[j].textContent.slice(0,5)&lt;br /&gt;
							if (compareVersion === version) continue&lt;br /&gt;
							rows[j].className += &amp;quot; other&amp;quot;;&lt;br /&gt;
						}&lt;br /&gt;
					};&lt;br /&gt;
				&lt;br /&gt;
					rows[i].onmouseleave = function (event) {&lt;br /&gt;
						var hovers = document.getElementsByClassName('other');&lt;br /&gt;
						var len = hovers.length;&lt;br /&gt;
						for (var j = 0; j &amp;lt; len; j++) {&lt;br /&gt;
							hovers[0].className = hovers[0].className.replace(/\sother(\s|$)/, '');&lt;br /&gt;
						}&lt;br /&gt;
					};&lt;br /&gt;
				}&lt;br /&gt;
&lt;br /&gt;
                // this.ele.addEventListener(&amp;quot;click&amp;quot;, (e) =&amp;gt; {&lt;br /&gt;
                //     console.log(e.target)&lt;br /&gt;
                    &lt;br /&gt;
                // });&lt;br /&gt;
&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* How to Create Database Seed Data.&lt;br /&gt;
* How to structure code so controller code is in one file and HTML Heex is in another&lt;br /&gt;
* How to Use Generators in a Real World Project&lt;br /&gt;
* How to Work with Database Data via Basic Commands and Custom Change sets.&lt;br /&gt;
* How to Render Database Data to LiveView (via Context Commands).&lt;br /&gt;
* How to Create a Chat using PubSub.&lt;br /&gt;
* How to Create Event Handlers in LiveView&lt;br /&gt;
* How to Create a Dynamic Route from Scratch.&lt;br /&gt;
* How to Use Elixirs Template language&lt;br /&gt;
* How to Work with Modal&lt;br /&gt;
* How to Use CSS From Scratch (Without bundler)&lt;br /&gt;
* How to use JS hooks&lt;br /&gt;
* Dissect Table Component and Update it to Order List in Reverse.&lt;br /&gt;
&lt;br /&gt;
Selenium&lt;br /&gt;
https://www.builder.io/blog/debug-nodejs&lt;br /&gt;
&lt;br /&gt;
https://marketplace.visualstudio.com/items?itemName=ms-vscode.live-server#running-the-extension&lt;br /&gt;
&lt;br /&gt;
This was added recently (see microsoft/vscode#109276).&lt;br /&gt;
    1. Open the palette (Ctrl + Shift + P)&lt;br /&gt;
    2. Select &amp;quot;Simple Browser: Preview&amp;quot;&lt;br /&gt;
    3. Enter web address&lt;br /&gt;
&lt;br /&gt;
_______________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
const {By, Key, Builder} = require(&amp;quot;selenium-webdriver&amp;quot;);&lt;br /&gt;
const assert = require(&amp;quot;assert&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
require(&amp;quot;chromedriver&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
async function test_case(){&lt;br /&gt;
  let driver = await new Builder().forBrowser(&amp;quot;chrome&amp;quot;).build();&lt;br /&gt;
  await driver.get(&amp;quot;sie&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  await driver.findElement(By.name('password')).clear();&lt;br /&gt;
  await driver.findElement(By.name('identification')).clear();&lt;br /&gt;
  await driver.findElement(By.name('identification')).sendKeys(&amp;quot;bill&amp;quot;);&lt;br /&gt;
  await driver.findElement(By.name('password')).sendKeys(&amp;quot;password&amp;quot;, Key.RETURN);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 setTimeout(()=&amp;gt;{&lt;br /&gt;
   driver.findElement(By.className(&amp;quot;req_lan_license&amp;quot;)).click();&lt;br /&gt;
 },5000)&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageLive do &lt;br /&gt;
&lt;br /&gt;
  use AppWeb, :live_view  &lt;br /&gt;
  alias App.Testbeds &lt;br /&gt;
  def mount(_params, _session, socket)do   &lt;br /&gt;
     {:ok, assign(socket, testbeds: Testbeds.list_testbeds())}   &lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
    def button_event(&amp;quot;invoke_editing&amp;quot;) do&lt;br /&gt;
    %JS{}&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;active&amp;quot;, to: &amp;quot;#editing_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#editing_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#preview_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;active&amp;quot;, to: &amp;quot;#preview_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;active&amp;quot;, to: &amp;quot;#preview&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#preview&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#editing&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;active&amp;quot;, to: &amp;quot;#editing&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def button_event(&amp;quot;invoke_preview&amp;quot;) do&lt;br /&gt;
    %JS{}&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;active&amp;quot;, to: &amp;quot;#preview_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#preview_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#editing_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;active&amp;quot;, to: &amp;quot;#editing_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;active&amp;quot;, to: &amp;quot;#editing&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#editing&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#preview&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;active&amp;quot;, to: &amp;quot;#preview&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;send&amp;quot;, params, socket) do&lt;br /&gt;
    hide_modal(&amp;quot;notes-modal-0&amp;quot;)&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do  &lt;br /&gt;
     ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
		&amp;lt;.modal id={&amp;quot;notes-modal-#{testbed.id}&amp;quot;}&amp;gt;&lt;br /&gt;
		    &amp;lt;.button phx-click={button_event(&amp;quot;invoke_editing&amp;quot;)} id=&amp;quot;editing_button&amp;quot; class=&amp;quot;hidden&amp;quot;&amp;gt;&lt;br /&gt;
		      Preview&lt;br /&gt;
		    &amp;lt;/.button&amp;gt;&lt;br /&gt;
		    &amp;lt;.button phx-click={button_event(&amp;quot;invoke_preview&amp;quot;)} id=&amp;quot;preview_button&amp;quot;&amp;gt;&lt;br /&gt;
		      Edit Me&lt;br /&gt;
		    &amp;lt;/.button&amp;gt;&lt;br /&gt;
		    &amp;lt;div id=&amp;quot;editing&amp;quot;&amp;gt; PREVIEWING THE WORK&amp;lt;/div&amp;gt;&lt;br /&gt;
		    &amp;lt;form phx-submit = &amp;quot;send&amp;quot;   id=&amp;quot;preview&amp;quot; class=&amp;quot;hidden&amp;quot;&amp;gt;&lt;br /&gt;
		      &amp;lt;textarea value = {testbed.note}&amp;gt;&amp;lt;/textarea&amp;gt;&lt;br /&gt;
		      &amp;lt;.button type=&amp;quot;submit&amp;quot; phx-click={hide_modal(&amp;quot;notes-modal-#{testbed.id}&amp;quot;)}&amp;gt;SAVE WORK&amp;lt;/.button&amp;gt;&lt;br /&gt;
		    &amp;lt;/form&amp;gt;&lt;br /&gt;
		&amp;lt;/.modal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;%= if testbed.note do %&amp;gt;&lt;br /&gt;
      &amp;lt;div phx-click={show_modal(&amp;quot;notes-modal-#{testbed.id}&amp;quot;)}&amp;gt;READ ME  ...&amp;lt;%= testbed.note %&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
	   &lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
       &lt;br /&gt;
      &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
import {HfInference} from &amp;quot;@huggingface/inference&amp;quot;;&lt;br /&gt;
import dotenv from &amp;quot;dotenv&amp;quot;;&lt;br /&gt;
dotenv.config()&lt;br /&gt;
&lt;br /&gt;
const HF_ACCESS_TOKEN = process.env.HF_ACCESS_TOKEN&lt;br /&gt;
&lt;br /&gt;
const hf = new HfInference(HF_ACCESS_TOKEN);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*______Uncomment for this example______________________&lt;br /&gt;
&lt;br /&gt;
const model = &amp;quot;nlpconnect/vit-gpt2-image-captioning&amp;quot;;&lt;br /&gt;
const imageURL = &amp;quot;https://i.imgur.com/lTvb7Et.png&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
const response = await fetch(imageURL);&lt;br /&gt;
const imageBlob = await response.blob();&lt;br /&gt;
&lt;br /&gt;
const result  = await hf.imageToText({&lt;br /&gt;
	data: imageBlob,&lt;br /&gt;
	model: model,&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
_______________________________________________________*/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*________Another example ___________________*/&lt;br /&gt;
&lt;br /&gt;
const result = await hf.summarization({&lt;br /&gt;
	model: 'facebook/bart-large-cnn',&lt;br /&gt;
	inputs: &amp;quot;The role of a dumb man is to get smarter oogy bookie boo&amp;quot;,&lt;br /&gt;
	parameters:{&lt;br /&gt;
		max_length: 100&lt;br /&gt;
	}&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
console.log(result);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
________________________________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://fly.io/phoenix-files/sdeb-toggling-element/&lt;br /&gt;
https://www.youtube.com/watch?v=vBgZvQapqhs&lt;br /&gt;
&lt;br /&gt;
https://blog.testdouble.com/posts/2022-11-28-how-to-use-javascript-with-phoenix-liveview/&lt;br /&gt;
&lt;br /&gt;
https://hexdocs.pm/phoenix_live_view/0.19.3/Phoenix.Component.html&lt;br /&gt;
_______________________________________&lt;br /&gt;
https://www.smashingmagazine.com/2011/10/quick-look-math-animations-javascript/&lt;br /&gt;
* Depth first traversal&lt;br /&gt;
* Breadth first traversal&lt;br /&gt;
&lt;br /&gt;
https://dev.to/codesphere/10-algorithms-every-developer-should-learn-3lnm&lt;br /&gt;
&lt;br /&gt;
https://www.youtube.com/watch?v=fPz40W9mfCg&lt;br /&gt;
&lt;br /&gt;
__________________________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.GroupLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  alias App.TestBeds&lt;br /&gt;
  alias App.Groups&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    {:ok, assign(socket, testbeds: TestBeds.list_testbeds(), groups: Groups.list_groups())}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;select-group&amp;quot;, params, socket)  do  &lt;br /&gt;
         &lt;br /&gt;
       IO.inspect params&lt;br /&gt;
       {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div class=&amp;quot;grid grid-columns-2 grid-flow-col gap-4&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;column-1&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;%= testbed.name %&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;column-2&amp;quot;&amp;gt;    &lt;br /&gt;
            &amp;lt;form phx-change=&amp;quot;select-group&amp;quot;  &amp;gt;&lt;br /&gt;
               &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;testbed_id&amp;quot; value={testbed.id}/&amp;gt;&lt;br /&gt;
               &amp;lt;select id=&amp;quot;group-selection&amp;quot;  name=&amp;quot;group-id&amp;quot; &amp;gt;&lt;br /&gt;
                &amp;lt;%= for group &amp;lt;- @groups do %&amp;gt;&lt;br /&gt;
                  &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}  &amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
               &amp;lt;/select&amp;gt;&lt;br /&gt;
            &amp;lt;/form&amp;gt;&lt;br /&gt;
         &amp;lt;/div&amp;gt;&lt;br /&gt;
       &amp;lt;% end %&amp;gt;&lt;br /&gt;
   &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
____________________________&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.GroupLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  alias App.TestBeds&lt;br /&gt;
  alias App.Groups&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
&lt;br /&gt;
    {:ok, assign(socket, testbeds: TestBeds.list_testbeds(), groups: Groups.list_groups(), messages: [])}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;select-group&amp;quot;, params, socket)  do  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
      group = App.Groups.get_group!(params[&amp;quot;group-id&amp;quot;])&lt;br /&gt;
       # IO.inspect group&lt;br /&gt;
       testbed = App.TestBeds.get_test_bed!(params[&amp;quot;testbed_id&amp;quot;])&lt;br /&gt;
     &lt;br /&gt;
       App.TestBeds.update_test_bed(testbed, %{group_id: group.id})&lt;br /&gt;
         &lt;br /&gt;
    &lt;br /&gt;
       {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def updated_groups(testbed_id)  do  &lt;br /&gt;
       groups = App.Groups.list_groups&lt;br /&gt;
       tail = Enum.filter(groups, fn(item)-&amp;gt; item.id !== testbed_id end)&lt;br /&gt;
       head = Enum.filter(groups, fn(item)-&amp;gt; item.id == testbed_id end)&lt;br /&gt;
              |&amp;gt;Enum.at(0)&lt;br /&gt;
     [head | tail]&lt;br /&gt;
         &lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
 # def handle_event(&amp;quot;groups&amp;quot;, params, socket)do  &lt;br /&gt;
 #       selected_testbed = %{name: &amp;quot;my testbed name&amp;quot;, id: 3}&lt;br /&gt;
 #       groups = App.Groups.list_groups&lt;br /&gt;
 #       tail = Enum.filter(groups, fn(item)-&amp;gt; item.id !== selected_testbed.id end)&lt;br /&gt;
 #       head = Enum.filter(groups, fn(item)-&amp;gt; item.id == selected_testbed.id end)&lt;br /&gt;
 #              |&amp;gt;Enum.at(0)&lt;br /&gt;
         &lt;br /&gt;
 &lt;br /&gt;
 #       # result = Enum.filter([1, 2, 3], fn x -&amp;gt; x.id !== 1 end)&lt;br /&gt;
 #      IO.inspect [head | tail]&lt;br /&gt;
         &lt;br /&gt;
 #      #&lt;br /&gt;
 #      {:noreply, socket, assigns.message:}&lt;br /&gt;
 #  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    &lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
       &amp;lt;%!-- &amp;lt;div phx-click = &amp;quot;groups&amp;quot;&amp;gt;CLICK ME&amp;lt;/div&amp;gt; --%&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;grid grid-cols-4 gap-4 p-8 rounded shadow bg-white&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;h2&amp;gt; Name&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;%= testbed.name %&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;h2&amp;gt; Group&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;form phx-change=&amp;quot;select-group&amp;quot; name=&amp;quot;testbed_id&amp;quot;  &amp;gt;&lt;br /&gt;
               &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;testbed_id&amp;quot; value={testbed.id}/&amp;gt;&lt;br /&gt;
               &amp;lt;select id=&amp;quot;group-selection&amp;quot;  name=&amp;quot;group-id&amp;quot; class=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
                &amp;lt;%= for group &amp;lt;- updated_groups(testbed.id) do %&amp;gt;&lt;br /&gt;
                  &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}  &amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
                  &amp;lt;!-- Write code to reorder with testbed.group_id matching group_id --&amp;gt;&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
               &amp;lt;/select&amp;gt;&lt;br /&gt;
            &amp;lt;/form&amp;gt;&lt;br /&gt;
          &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
       &amp;lt;% end %&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_____________________________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
   use AppWeb, :live_view  &lt;br /&gt;
     alias App.Testbeds&lt;br /&gt;
  alias App.Groups&lt;br /&gt;
   def mount(_params, _session, socket)  do&lt;br /&gt;
	     {:ok, assign(socket, testbeds: Testbeds.list_testbeds(), groups: Groups.list_groups())}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
   def handle_event(&amp;quot;select-group&amp;quot;, params, socket)  do  &lt;br /&gt;
       group = App.Groups.get_group!(params[&amp;quot;group-id&amp;quot;])&lt;br /&gt;
       testbed = App.Testbeds.get_testbed!(params[&amp;quot;testbed_id&amp;quot;])&lt;br /&gt;
       result = App.Testbeds.update_testbed(testbed, %{group_id: group.id})&lt;br /&gt;
       IO.inspect result&lt;br /&gt;
      &lt;br /&gt;
       {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
    def updated_groups(testbed_id)  do  &lt;br /&gt;
       testbed = App.Testbeds.get_testbed!(testbed_id)&lt;br /&gt;
       groups = App.Groups.list_groups&lt;br /&gt;
       tail = Enum.filter(groups, fn(item)-&amp;gt; item.id !== testbed.group_id end)&lt;br /&gt;
       head = Enum.filter(groups, fn(item)-&amp;gt; item.id == testbed.group_id end)&lt;br /&gt;
              |&amp;gt;Enum.at(0)&lt;br /&gt;
 &lt;br /&gt;
       [head | tail]&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    &lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;grid grid-cols-4 gap-4 p-8 rounded shadow bg-white&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;h2&amp;gt; Name&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;%= testbed.name %&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;h2&amp;gt; Group&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;form phx-change=&amp;quot;select-group&amp;quot; name=&amp;quot;testbed_id&amp;quot;  &amp;gt;&lt;br /&gt;
               &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;testbed_id&amp;quot; value={testbed.id}/&amp;gt;&lt;br /&gt;
               &amp;lt;select id=&amp;quot;group-selection&amp;quot;  name=&amp;quot;group-id&amp;quot; class=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
                &amp;lt;%= for group &amp;lt;- updated_groups(testbed.id) do %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
                  &amp;lt;%!-- &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}&amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt; --%&amp;gt;&lt;br /&gt;
                  &amp;lt;!-- Write code to reorder with testbed.group_id matching group_id --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
                  &amp;lt;%= if group !== nil do %&amp;gt;&lt;br /&gt;
                      &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}&amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
       &lt;br /&gt;
                  &amp;lt;% end %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
               &amp;lt;/select&amp;gt;&lt;br /&gt;
            &amp;lt;/form&amp;gt;&lt;br /&gt;
          &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
       &amp;lt;% end %&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  has_many :testbeds, TestBed, on_delete: :restrict   # Has many&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://elixirforum.com/t/ecto-has-many-on-delete-protect/49550&lt;br /&gt;
&lt;br /&gt;
https://hexdocs.pm/ecto/Ecto.Changeset.html#unique_constraint/3&lt;br /&gt;
&lt;br /&gt;
____________________________________________________________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== How to Create a Mix Project and Use It in Another Mix Project ==&lt;br /&gt;
&lt;br /&gt;
To create and use a **Mix project** inside another **Mix project** in Elixir, follow the steps below:&lt;br /&gt;
&lt;br /&gt;
=== 1. Create a New Mix Project ===&lt;br /&gt;
&lt;br /&gt;
First, you need to create a new Mix project. Let's call this project `library_project`. Run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mix new library_project --module LibraryProject&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will create a new Elixir Mix project named `library_project`. The `--module` flag specifies the name of the module that will be created (in this case `LibraryProject`).&lt;br /&gt;
&lt;br /&gt;
The directory structure of `library_project` will look like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
library_project/&lt;br /&gt;
  |_ lib/&lt;br /&gt;
      |_ library_project.ex&lt;br /&gt;
  |_ mix.exs&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can then add some basic functionality inside the `library_project/lib/library_project.ex` file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule LibraryProject do&lt;br /&gt;
  def hello do&lt;br /&gt;
    IO.puts &amp;quot;Hello from LibraryProject!&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now, `library_project` is ready to be used by another Mix project.&lt;br /&gt;
&lt;br /&gt;
=== 2. Create a Second Mix Project ===&lt;br /&gt;
&lt;br /&gt;
Next, create the second Mix project where you want to use `library_project`. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mix new app_project --module AppProject&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will create another Elixir project called `app_project`.&lt;br /&gt;
&lt;br /&gt;
The directory structure for this project will look like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
app_project/&lt;br /&gt;
  |_ lib/&lt;br /&gt;
      |_ app_project.ex&lt;br /&gt;
  |_ mix.exs&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 3. Add `library_project` as a Dependency in `app_project` ===&lt;br /&gt;
&lt;br /&gt;
Now, you want to make `library_project` available in `app_project`. There are two main ways to do this:&lt;br /&gt;
&lt;br /&gt;
==== Option 1: Local Dependency (via `path`) ====&lt;br /&gt;
&lt;br /&gt;
If `library_project` is a local project (i.e., it's stored in a different directory), you can add it to the `mix.exs` of `app_project` as a local dependency by specifying the path to `library_project`.&lt;br /&gt;
&lt;br /&gt;
Edit the `mix.exs` of `app_project`:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule AppProject.MixProject do&lt;br /&gt;
  use Mix.Project&lt;br /&gt;
&lt;br /&gt;
  def project do&lt;br /&gt;
    [&lt;br /&gt;
      app: :app_project,&lt;br /&gt;
      version: &amp;quot;0.1.0&amp;quot;,&lt;br /&gt;
      elixir: &amp;quot;~&amp;gt; 1.14&amp;quot;,&lt;br /&gt;
      start_permanent: Mix.env() == :prod,&lt;br /&gt;
      deps: deps()&lt;br /&gt;
    ]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  defp deps do&lt;br /&gt;
    [&lt;br /&gt;
      {:library_project, path: &amp;quot;../library_project&amp;quot;}  # Add the local dependency&lt;br /&gt;
    ]&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here, `{:library_project, path: &amp;quot;../library_project&amp;quot;}` tells Mix to use the local `library_project` located in the `../library_project` directory (relative to `app_project`).&lt;br /&gt;
&lt;br /&gt;
After updating the `mix.exs`, run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd app_project&lt;br /&gt;
mix deps.get&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will fetch the dependency and compile `library_project`.&lt;br /&gt;
&lt;br /&gt;
==== Option 2: Publish and Fetch as a Hex Package ====&lt;br /&gt;
&lt;br /&gt;
If you want to use `library_project` as a package in another project (for example, by publishing it to **Hex.pm**, Elixir’s package manager), you need to publish it to Hex and then add it as a dependency.&lt;br /&gt;
&lt;br /&gt;
1. Publish `library_project` to Hex (if it's public or for your private use).&lt;br /&gt;
2. Add `library_project` to your `app_project`’s `mix.exs` dependencies:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defp deps do&lt;br /&gt;
  [&lt;br /&gt;
    {:library_project, &amp;quot;~&amp;gt; 0.1.0&amp;quot;}  # Specify the published version from Hex&lt;br /&gt;
  ]&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Run `mix deps.get` to fetch the package from Hex.&lt;br /&gt;
&lt;br /&gt;
=== 4. Use `library_project` in `app_project` ===&lt;br /&gt;
&lt;br /&gt;
Now, you can use the functionality from `library_project` inside your `app_project`. For example, in `app_project/lib/app_project.ex`, you can call the function from `library_project`:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule AppProject do&lt;br /&gt;
  def start do&lt;br /&gt;
    IO.puts &amp;quot;Starting app_project!&amp;quot;&lt;br /&gt;
    LibraryProject.hello()  # Call the function from the library_project&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 5. Run the App ===&lt;br /&gt;
&lt;br /&gt;
Finally, you can run your `app_project`:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd app_project&lt;br /&gt;
mix run -e &amp;quot;AppProject.start()&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will print:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Starting app_project!&lt;br /&gt;
Hello from LibraryProject!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Recap of the Process ==&lt;br /&gt;
1. **Create the `library_project`**: Use `mix new` to generate a library project.&lt;br /&gt;
2. **Create the `app_project`**: Create the second project where you will use the library.&lt;br /&gt;
3. **Add the `library_project` as a dependency**:&lt;br /&gt;
   - Use the `path` option to point to the local project or publish it to Hex for public access.&lt;br /&gt;
4. **Use the `library_project` in the `app_project`**: Call functions or use modules from the library inside the second project.&lt;br /&gt;
5. **Run the app**: Use `mix run` to execute the project.&lt;br /&gt;
&lt;br /&gt;
This way, you can reuse code from one Mix project in another by adding it as a dependency.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==z==&lt;br /&gt;
Overloaded functions are extremely common in Elixir applications. They are&lt;br /&gt;
regularly used for recursive functions and for changing behavior based on&lt;br /&gt;
configuration.&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>http://elixirblocks.com/index.php?title=User:Admin&amp;diff=1897</id>
		<title>User:Admin</title>
		<link rel="alternate" type="text/html" href="http://elixirblocks.com/index.php?title=User:Admin&amp;diff=1897"/>
		<updated>2025-04-02T18:42:56Z</updated>

		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Async claude ai example&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Explain to me the relationship between handle_info and making an async call&lt;br /&gt;
&lt;br /&gt;
The relationship between handle_info and making async calls in Phoenix LiveView is fundamental to understanding how to handle non-blocking operations in your application.&lt;br /&gt;
&lt;br /&gt;
When you make an asynchronous call in Elixir (like using Task.async), you're creating a separate process that runs independently from your LiveView process. This allows your LiveView to remain responsive while potentially time-consuming operations (like API calls) are happening.&lt;br /&gt;
&lt;br /&gt;
Here's how they work together:&lt;br /&gt;
&lt;br /&gt;
Async Operation Initiation: When you start an async operation using Task.async, it returns a reference to the task.&lt;br /&gt;
Message Passing: When the async task completes, it automatically sends a message back to the process that created it. This message contains the task reference and the result: {ref, result}.&lt;br /&gt;
handle_info Reception: The handle_info/2 callback in LiveView is what receives these messages. It's like a mailbox for your LiveView process that handles any messages not related to LiveView events.&lt;br /&gt;
Process Cleanup: After receiving the result, you typically call Process.demonitor(ref, [:flush]) to clean up process monitoring and prevent receiving a :DOWN message when the task process exits.&lt;br /&gt;
This pattern creates a complete async lifecycle:&lt;br /&gt;
&lt;br /&gt;
Start async task →&lt;br /&gt;
Task runs independently →&lt;br /&gt;
Task completes and sends message →&lt;br /&gt;
handle_info receives message →&lt;br /&gt;
Update LiveView state&lt;br /&gt;
In the example I provided, there's a clear separation of concerns:&lt;br /&gt;
&lt;br /&gt;
Task.async(fn -&amp;gt; api() end) starts the async operation&lt;br /&gt;
handle_info({ref, result}, socket) receives and processes the result&lt;br /&gt;
The LiveView remains responsive throughout the entire operation&lt;br /&gt;
This pattern is what makes LiveView capable of handling concurrent operations while maintaining a responsive UI for users.&lt;br /&gt;
________________________&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.Sandbox do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    # Schedule the API call to happen after mount&lt;br /&gt;
    if connected?(socket), do: Process.send_after(self(), :fetch_data, 0)&lt;br /&gt;
    {:ok, assign(socket, data: nil)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_info(:fetch_data, socket) do&lt;br /&gt;
    # Launch API call in separate process&lt;br /&gt;
    Task.async(fn -&amp;gt; api() end)&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_info({ref, result}, socket) when is_reference(ref) do&lt;br /&gt;
    # Clean up the DOWN message&lt;br /&gt;
    Process.demonitor(ref, [:flush])&lt;br /&gt;
    {:noreply, assign(socket, data: result)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def api do&lt;br /&gt;
    Req.request(url: &amp;quot;https://api.github.com/repos/wojtekmach/req&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    SANDBOX&lt;br /&gt;
    &amp;lt;%= if @data, do: inspect(@data) %&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
___________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 defmodule Heading do&lt;br /&gt;
   use Phoenix.Component&lt;br /&gt;
   def head(assigns) do&lt;br /&gt;
	   ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	     &amp;lt;p&amp;gt;Hello, &amp;lt;%= @headings %&amp;gt;!&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	   &amp;quot;&amp;quot;&amp;quot; &lt;br /&gt;
   end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
   use AppWeb, :live_view  &lt;br /&gt;
   import Heading&lt;br /&gt;
   def mount(_params, _session, socket)  do&lt;br /&gt;
	 {:ok, socket}  &lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
   def headings do &lt;br /&gt;
    [&amp;quot;one&amp;quot;,&amp;quot;two&amp;quot;,&amp;quot;three&amp;quot;]&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
   def render(assigns) do&lt;br /&gt;
	   ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	     &amp;lt;Heading.head  headings={headings()} /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	   &amp;quot;&amp;quot;&amp;quot; &lt;br /&gt;
   end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://app.studyraid.com/en/read/11967/381872/component-communication&lt;br /&gt;
&lt;br /&gt;
https://thepugautomatic.com/2020/08/communicating-between-liveviews-on-the-same-page/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
from(a in Article,&lt;br /&gt;
  order_by: [desc: a.inserted_at],  # Assuming 'inserted_at' is the timestamp for when the article was created or updated&lt;br /&gt;
  limit: 8&lt;br /&gt;
)&lt;br /&gt;
|&amp;gt; Repo.all()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.Landing do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  alias App.Testbeds&lt;br /&gt;
  alias App.Testbeds.Testbed&lt;br /&gt;
  alias App.Repo  # Ensure to alias Repo&lt;br /&gt;
  import Ecto.Query  # Import Ecto.Query to work with queries&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    # Default to ordering by name&lt;br /&gt;
    testbeds = Repo.all(from(t in Testbed, order_by: t.name))&lt;br /&gt;
&lt;br /&gt;
    # Assign the testbeds to the socket for rendering&lt;br /&gt;
    {:ok, assign(socket, testbeds: testbeds, sort: :name)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    &amp;lt;h1&amp;gt;Hello World! YAY&amp;lt;/h1&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;div&amp;gt;&lt;br /&gt;
      &amp;lt;!-- Buttons to toggle sorting --&amp;gt;&lt;br /&gt;
      &amp;lt;button phx-click=&amp;quot;sort_by_name&amp;quot;&amp;gt;Sort by Name&amp;lt;/button&amp;gt;&lt;br /&gt;
      &amp;lt;button phx-click=&amp;quot;sort_by_updated_at&amp;quot;&amp;gt;Sort by Updated By&amp;lt;/button&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;ul&amp;gt;&lt;br /&gt;
      &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
        &amp;lt;li&amp;gt;&amp;lt;%= testbed.name %&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;% end %&amp;gt;&lt;br /&gt;
    &amp;lt;/ul&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;sort_by_name&amp;quot;, _params, socket) do&lt;br /&gt;
    testbeds = Repo.all(from(t in Testbed, order_by: t.name))&lt;br /&gt;
    {:noreply, assign(socket, testbeds: testbeds, sort: :name)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;sort_by_updated_at&amp;quot;, _params, socket) do&lt;br /&gt;
    testbeds = Repo.all(from(t in Testbed, order_by: t.inserted_at))&lt;br /&gt;
    {:noreply, assign(socket, testbeds: testbeds, sort: :inserted_at)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
_______________________________________________________&lt;br /&gt;
&lt;br /&gt;
* Create a form with a post request. &lt;br /&gt;
* Create the route needed for that request&lt;br /&gt;
* Create the controller needed for that route&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Form==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;.form action={~p&amp;quot;/todos&amp;quot;} method=&amp;quot;post&amp;quot; class=&amp;quot;mt-10 space-y-8&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    &amp;lt;label for=&amp;quot;contact_name&amp;quot; class=&amp;quot;block text-sm font-semibold leading-6 text-zinc-800&amp;quot;&amp;gt;&lt;br /&gt;
      Name&lt;br /&gt;
    &amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;input&lt;br /&gt;
      id=&amp;quot;todo&amp;quot;&lt;br /&gt;
      type=&amp;quot;text&amp;quot;&lt;br /&gt;
      name=&amp;quot;todo&amp;quot;&lt;br /&gt;
      class=&amp;quot;mt-2 block w-full rounded-lg text-zinc-900 focus:ring-0 sm:text-sm sm:leading-6 border-zinc-300 focus:border-zinc-400&amp;quot;&lt;br /&gt;
    /&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;button&lt;br /&gt;
    type=&amp;quot;submit&amp;quot;&lt;br /&gt;
    class=&amp;quot;rounded-lg bg-zinc-900 hover:bg-zinc-700 py-2 px-3 text-sm font-semibold leading-6 text-white active:text-white/80&amp;quot;&lt;br /&gt;
  &amp;gt;&lt;br /&gt;
    Save Contact&lt;br /&gt;
  &amp;lt;/button&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/.form&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Controller==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# In your TodoController&lt;br /&gt;
defmodule AppWeb.TodoController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  # Action to handle the form submission (POST request)&lt;br /&gt;
  def create(conn, %{&amp;quot;todo&amp;quot; =&amp;gt; todo_name}) do&lt;br /&gt;
    # Here you can handle the form data (e.g., save it to the database)&lt;br /&gt;
    IO.puts(&amp;quot;Received Todo: #{todo_name}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    # For now, let's just redirect to the home page&lt;br /&gt;
    conn&lt;br /&gt;
    |&amp;gt; put_flash(:info, &amp;quot;Todo saved!&amp;quot;)&lt;br /&gt;
    |&amp;gt; redirect(to: &amp;quot;/&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
________________________________________________________&lt;br /&gt;
&lt;br /&gt;
# CRUD Forms&lt;br /&gt;
&lt;br /&gt;
To understand CRUD forms you will need to understand the following concepts. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Ecto Schema&lt;br /&gt;
* Ecto Context&lt;br /&gt;
* Form Basics&lt;br /&gt;
* form/1&lt;br /&gt;
* simple_form/1&lt;br /&gt;
* changesets&lt;br /&gt;
&lt;br /&gt;
We are not going to go in order. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The Context provides CRUD functions for the chosen data schema. Phoenix contexts define the interface through which other parts of the codebase can interact with the app layer.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_______________________&lt;br /&gt;
* Create routes&lt;br /&gt;
* create page with form (submit get request)&lt;br /&gt;
&lt;br /&gt;
(ecto schema, context, changesets)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_______________________________________________________&lt;br /&gt;
In that case, you really should switch it to prod mode. Instead of doing all that above with the &amp;quot;config/secret.exs&amp;quot; file, create the &amp;quot;.env&amp;quot; in the project root, then add DotenvParser.load_file(&amp;quot;.env&amp;quot;) to &amp;quot;config/runtime.exs&amp;quot; as the first line inside the if config_env() == :prod do. In the .env file, set the DATABASE_URL and SECRET_KEY_BASE. Then run it as MIX_ENV=prod mix phx.server.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def get_titles do&lt;br /&gt;
    urls = [&lt;br /&gt;
      &amp;quot;https://cointelegraph.com/rss&amp;quot;,&lt;br /&gt;
      &amp;quot;https://chaski.huffpost.com/us/auto/vertical/us-news&amp;quot;&lt;br /&gt;
      # Add more RSS feed URLs here&lt;br /&gt;
    ]&lt;br /&gt;
&lt;br /&gt;
    urls&lt;br /&gt;
    |&amp;gt; Enum.map(fn url -&amp;gt;&lt;br /&gt;
      with {:ok, feed} &amp;lt;- ElixirRss.fetch_and_parse(url) do&lt;br /&gt;
        Enum.map(feed.entries, &amp;amp; &amp;amp;1.title)&lt;br /&gt;
      else&lt;br /&gt;
        {:error, reason} -&amp;gt; {:error, reason}&lt;br /&gt;
      end&lt;br /&gt;
    end)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule App do&lt;br /&gt;
&lt;br /&gt;
  def get_titles() do&lt;br /&gt;
    data = [&lt;br /&gt;
      &amp;quot;https://cointelegraph.com/rss&amp;quot;,&lt;br /&gt;
      &amp;quot;https://chaski.huffpost.com/us/auto/vertical/us-news&amp;quot;&lt;br /&gt;
      # Add more RSS feed URLs here&lt;br /&gt;
    ]&lt;br /&gt;
&lt;br /&gt;
    data&lt;br /&gt;
    |&amp;gt; Enum.map(fn url -&amp;gt;&lt;br /&gt;
      case ElixirRss.fetch_and_parse(url) do&lt;br /&gt;
        {:ok, feed} -&amp;gt; feed.entries |&amp;gt; Enum.map(fn entry -&amp;gt; entry end)&lt;br /&gt;
        {:error, reason} -&amp;gt; {:error, reason}&lt;br /&gt;
      end&lt;br /&gt;
    end)&lt;br /&gt;
    |&amp;gt; Enum.map(fn entry_list -&amp;gt;&lt;br /&gt;
      entry_list&lt;br /&gt;
      |&amp;gt; Enum.map(fn entry -&amp;gt; entry.title end)&lt;br /&gt;
    end)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def hello do&lt;br /&gt;
    rss_feeds = [&lt;br /&gt;
      &amp;quot;https://cointelegraph.com/rss&amp;quot;,&lt;br /&gt;
      &amp;quot;https://chaski.huffpost.com/us/auto/vertical/us-news&amp;quot;&lt;br /&gt;
      # Add more RSS feed URLs here&lt;br /&gt;
    ]&lt;br /&gt;
&lt;br /&gt;
    rss_feeds&lt;br /&gt;
    |&amp;gt; Enum.map(fn url -&amp;gt;&lt;br /&gt;
      case ElixirRss.fetch_and_parse(url) do&lt;br /&gt;
        {:ok, feed} -&amp;gt; feed.entries |&amp;gt; Enum.map(fn entry -&amp;gt; entry end)&lt;br /&gt;
        {:error, reason} -&amp;gt; {:error, reason}&lt;br /&gt;
      end&lt;br /&gt;
    end)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    if connected?(socket) do&lt;br /&gt;
      Phoenix.PubSub.subscribe(App.PubSub, &amp;quot;message&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
    {:ok, assign(socket, message_item: &amp;quot;different&amp;quot;)}&lt;br /&gt;
  end&lt;br /&gt;
  def handle_info({:pubsub_transmission, text}, socket) do&lt;br /&gt;
    IO.inspect &amp;quot;pub sub working&amp;quot;&lt;br /&gt;
    {:noreply, assign(socket, message_item: text)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def loop(data) do&lt;br /&gt;
     IO.inspect data&lt;br /&gt;
     if data &amp;gt; 0 do&lt;br /&gt;
      IO.inspect &amp;quot;notify&amp;quot;&lt;br /&gt;
      # run code to compare files, loop. If different run pubsub code below&lt;br /&gt;
      :timer.sleep(2000)&lt;br /&gt;
      loop(data-1)&lt;br /&gt;
&lt;br /&gt;
     end&lt;br /&gt;
     if data &amp;lt;= 0 do&lt;br /&gt;
&lt;br /&gt;
      Phoenix.PubSub.broadcast(App.PubSub, &amp;quot;message&amp;quot;, {:pubsub_transmission, &amp;quot;data&amp;quot;})&lt;br /&gt;
      &amp;quot;done&amp;quot;&lt;br /&gt;
     end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;change-text&amp;quot;, _params, socket) do&lt;br /&gt;
    spawn(fn -&amp;gt; loop(3) end)&lt;br /&gt;
    {:noreply, assign(socket, message_item: &amp;quot;START&amp;quot; )}&lt;br /&gt;
  end&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
&lt;br /&gt;
    # AppWeb.PageLive.loop(&amp;quot;xxx&amp;quot;)&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    SANDBOX&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;.button phx-click=&amp;quot;change-text&amp;quot; value={@message_item}&amp;gt;CLICK ME&amp;lt;/.button&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;%= @message_item %&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
elixir :   1.16.2&lt;br /&gt;
&lt;br /&gt;
Erl:   20&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# PostGres&lt;br /&gt;
Created Saturday 18 February 2023&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Launch [PostGres](#PostGres) from Terminal&lt;br /&gt;
------------------------------------------&lt;br /&gt;
sudo -u postgres psql&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Set User Permission&lt;br /&gt;
-------------------&lt;br /&gt;
&amp;lt;https://commandprompt.com/education/how-to-create-a-superuser-in-postgresql/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ALTER USER user_name WITH PASSWORD 'new_password';&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Run Post Gres Commands&lt;br /&gt;
----------------------&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
sudo -i -u postgres&lt;br /&gt;
psql&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Create and Delete Database&lt;br /&gt;
&lt;br /&gt;
CREATE DATABASE name;&lt;br /&gt;
DROP DATABASE name;&lt;br /&gt;
## View user list&lt;br /&gt;
&lt;br /&gt;
\du&lt;br /&gt;
&lt;br /&gt;
 View all databases&lt;br /&gt;
&lt;br /&gt;
postgres=# \l&lt;br /&gt;
&lt;br /&gt;
 Change databases&lt;br /&gt;
&lt;br /&gt;
postgres=# \c    name-of-database&lt;br /&gt;
&lt;br /&gt;
View Tables&lt;br /&gt;
&lt;br /&gt;
After you change databases and are selected on one of them do this:&lt;br /&gt;
&lt;br /&gt;
\dt&lt;br /&gt;
&lt;br /&gt;
SELECT * FROM mytablename;&lt;br /&gt;
&lt;br /&gt;
EMPTY TABLE&lt;br /&gt;
DELETE FROM name-of-table&lt;br /&gt;
&lt;br /&gt;
CREATE TABLE&lt;br /&gt;
&lt;br /&gt;
CREATE TABLE table_name(&lt;br /&gt;
   column1 datatype,&lt;br /&gt;
   column2 datatype,&lt;br /&gt;
   column3 datatype,&lt;br /&gt;
   .....&lt;br /&gt;
   columnN datatype,&lt;br /&gt;
   PRIMARY KEY( one or more columns )&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
INSERT&lt;br /&gt;
&lt;br /&gt;
INSERT INTO ITEMS(id, name) VALUES(1,'htvjbjbgni');     Strings are single quote&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Roadmap==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.ItemsLive do&lt;br /&gt;
    use AppWeb, :live_view  &lt;br /&gt;
    def mount(_params, _session, socket)  do&lt;br /&gt;
      {:ok, assign(socket, switches: [&amp;quot;grindy&amp;quot;,&amp;quot;sonic&amp;quot;,&amp;quot;ogre&amp;quot;])}  &lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    def handle_event(&amp;quot;run&amp;quot;,_params,socket) do  &lt;br /&gt;
        &lt;br /&gt;
        IO.inspect &amp;quot;DOWNLOAD VIA SSH&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        {:noreply, redirect(socket, to: &amp;quot;/download&amp;quot;)}&lt;br /&gt;
&lt;br /&gt;
    end&lt;br /&gt;
   &lt;br /&gt;
&lt;br /&gt;
    def render(assigns) do&lt;br /&gt;
        &lt;br /&gt;
        ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        &amp;lt;ul&amp;gt;&lt;br /&gt;
        &amp;lt;%= for switch &amp;lt;- @switches do %&amp;gt;&lt;br /&gt;
         &amp;lt;a phx-submit=&amp;quot;click&amp;quot; href=&amp;quot;/download&amp;quot;&amp;gt;  &amp;lt;li&amp;gt; &amp;lt;%= switch %&amp;gt;  &amp;lt;/li&amp;gt; &amp;lt;/a&amp;gt;&lt;br /&gt;
&lt;br /&gt;
        &amp;lt;%end%&amp;gt;&lt;br /&gt;
        &amp;lt;/ul&amp;gt;&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot; &lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Notes==&lt;br /&gt;
List of Switches and the option to select the one needed.&lt;br /&gt;
Button to download JSON file.&lt;br /&gt;
Drag and Drop Palette to upload JSON file.&lt;br /&gt;
&lt;br /&gt;
After JSON file is uploaded a button titled &amp;quot;Make Active&amp;quot; is available.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://medium.com/@fraiha26/pushing-events-to-livecomponents-from-js-hooks-w-phoenix-elixir-d5544d4c3dfa&lt;br /&gt;
&lt;br /&gt;
Changeset notes and forms&lt;br /&gt;
&lt;br /&gt;
NOTE: Use case statements for pattern matching&lt;br /&gt;
____________________________________________&lt;br /&gt;
&lt;br /&gt;
Create a basic &amp;lt;.form&amp;gt;&amp;lt;/form&amp;gt; without error handling&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&amp;lt;.form :let={f} for={@changeset}  action={~p&amp;quot;/items&amp;quot;} &amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;.input field={f[:title]} type=&amp;quot;text&amp;quot; label=&amp;quot;Title&amp;quot; /&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
  &amp;lt;.button&amp;gt;Save Item&amp;lt;/.button&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;/.form&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With error handling looks like this:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;.form :let={f} for={@changeset}  action={~p&amp;quot;/items&amp;quot;} &amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;.error :if={@changeset.action}&amp;gt;&lt;br /&gt;
    Oops, something went wrong! Please check the errors below.&lt;br /&gt;
  &amp;lt;/.error&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;.input field={f[:title]} type=&amp;quot;text&amp;quot; label=&amp;quot;Title&amp;quot; /&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
  &amp;lt;.button&amp;gt;Save Item&amp;lt;/.button&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;/.form&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Create the routes for render and post to endpoint.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The controller for the page render needs to pass in the changeset via ```Items.change_item(%Item{})```&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  def new(conn, _params) do&lt;br /&gt;
    changeset = Items.change_item(%Item{})&lt;br /&gt;
    render(conn, :new, changeset: changeset)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Post route without error handling&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  def create(conn, %{&amp;quot;item&amp;quot; =&amp;gt; item_params}) do&lt;br /&gt;
    case Items.create_item(item_params) do&lt;br /&gt;
      {:ok, item} -&amp;gt;&lt;br /&gt;
        conn&lt;br /&gt;
        |&amp;gt; put_flash(:info, &amp;quot;Item created successfully.&amp;quot;)&lt;br /&gt;
        |&amp;gt; redirect(to: ~p&amp;quot;/items/#{item}&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With error handling&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  def create(conn, %{&amp;quot;item&amp;quot; =&amp;gt; item_params}) do&lt;br /&gt;
    case Items.create_item(item_params) do&lt;br /&gt;
      {:ok, item} -&amp;gt;&lt;br /&gt;
        conn&lt;br /&gt;
        |&amp;gt; put_flash(:info, &amp;quot;Item created successfully.&amp;quot;)&lt;br /&gt;
        |&amp;gt; redirect(to: ~p&amp;quot;/items/#{item}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
      {:error, %Ecto.Changeset{} = changeset} -&amp;gt;&lt;br /&gt;
        render(conn, :new, changeset: changeset)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_____________________________________________&lt;br /&gt;
https://medium.com/@vincentlin/phoenix-very-simple-form-c4b121697fcb&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''home.html.heex'''&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&amp;lt;form action=&amp;quot;/submit&amp;quot; method=&amp;quot;post&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;label for=&amp;quot;name&amp;quot;&amp;gt;Name:&amp;lt;/label&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;input type=&amp;quot;text&amp;quot; id=&amp;quot;name&amp;quot; name=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;_csrf_token&amp;quot; value={@csrf_token} /&amp;gt;&lt;br /&gt;
  &amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Submit&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
page_controller.ex&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.PageController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  def home(conn, _params) do&lt;br /&gt;
    # The home page is often custom made,&lt;br /&gt;
&lt;br /&gt;
    csrf_token = Plug.CSRFProtection.get_csrf_token()&lt;br /&gt;
    render(conn, :home, csrf_token: csrf_token)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def submit(conn, _params) do&lt;br /&gt;
    # The home page is often custom made,&lt;br /&gt;
     IO.inspect(_params)&lt;br /&gt;
     IO.inspect &amp;quot;___________________________&amp;quot;&lt;br /&gt;
    csrf_token = Plug.CSRFProtection.get_csrf_token()&lt;br /&gt;
    render(conn, :home, csrf_token: csrf_token)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
router.ex&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  scope &amp;quot;/&amp;quot;, AppWeb do&lt;br /&gt;
    pipe_through :browser&lt;br /&gt;
    post &amp;quot;/submit&amp;quot;, PageController, :submit&lt;br /&gt;
    get &amp;quot;/&amp;quot;, PageController, :home&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ecto.Adapters.SQL.query(Repo, &amp;quot;select * from artists where id=1&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ecto cheatsheet:  https://hexdocs.pm/ecto/crud.html&lt;br /&gt;
__________________________________________________________________&lt;br /&gt;
Most programming languages give you the ability to set global state by creating globally scoped variables. Elixir does not do this. Instead, Elixir provides a tool called a &amp;quot;processes&amp;quot; to persist  state. Elixir applications are composed of these &amp;quot;processes&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
Processes by themselves are complicated to use, thus Elixir provides abstractions to make working with processes easier. One of these abstractions is called a GenServer.&lt;br /&gt;
&lt;br /&gt;
GenServers are not only used to store state, they are also used to invoke work independent of the main application process. &lt;br /&gt;
&lt;br /&gt;
==Creating a GenServer to Store State==&lt;br /&gt;
&lt;br /&gt;
To Create a GenServer, start by creating a basic Module that ''uses'' the GenServer module (image below)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule App do  &lt;br /&gt;
  use GenServer&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We now need to describe the actions we want to perform. Being that this is used to store state, we will use basic CRUD actions: Create, Read, Update, Delete. To begins, empty functions describing each action is created.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule App do&lt;br /&gt;
   def create do &lt;br /&gt;
&lt;br /&gt;
   end&lt;br /&gt;
   def read do &lt;br /&gt;
&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
   def update do  &lt;br /&gt;
&lt;br /&gt;
   end &lt;br /&gt;
&lt;br /&gt;
   def delete do &lt;br /&gt;
&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==What now?==&lt;br /&gt;
&lt;br /&gt;
To fill in the functions with the appropriate code we must first have a basic understanding of how GenServers are structured.&lt;br /&gt;
&lt;br /&gt;
GenServers are composed of the GenServer module invoking callbacks. The callbacks have built in names that you, as a developer have to use.&lt;br /&gt;
&lt;br /&gt;
These callbacks are named:&lt;br /&gt;
&lt;br /&gt;
* init&lt;br /&gt;
* handle_cast&lt;br /&gt;
* handle_call&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To demonstrate, here is an example :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{:ok, pid} = GenServer.start(ModuleNameOfGenServer, %{})&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above function named &amp;quot;start&amp;quot; calls the function named init in the Module below.&lt;br /&gt;
In GenServer syntax the name of the GenServer functions always invoke callbacks that are determined by the language. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule ModuleNameOfGenServer do&lt;br /&gt;
  # 1&lt;br /&gt;
  def init(state \\ %{}) do&lt;br /&gt;
    {:ok, state}&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is a list of the GenServer functions and their corresponding callbacks.&lt;br /&gt;
&lt;br /&gt;
* GenServer.start/1  --&amp;gt;       init/1&lt;br /&gt;
* GenServer.call/3   --&amp;gt;       def handle_call/3&lt;br /&gt;
* GenServer.cast/2   --&amp;gt;       handle_cast/2&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Start and Call ==&lt;br /&gt;
&lt;br /&gt;
Call and Cast can be used to perform the same operations. The &lt;br /&gt;
&lt;br /&gt;
__________________________________________________________&lt;br /&gt;
Genserver timed events&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule Go do&lt;br /&gt;
  use GenServer&lt;br /&gt;
&lt;br /&gt;
  def go() do&lt;br /&gt;
    GenServer.start_link(__MODULE__, [])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def init(list) do&lt;br /&gt;
    :timer.apply_interval(1000, __MODULE__, :add, [self(), &amp;quot;weeeee&amp;quot;])&lt;br /&gt;
    {:ok, list}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def view(pid) do&lt;br /&gt;
    GenServer.call(pid, :view)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_call(:view, _from, list) do&lt;br /&gt;
    {:reply, list, list}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def add(pid, new_item) do&lt;br /&gt;
    GenServer.call(pid, {:item, new_item})&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_call({:item, new_item}, _from, state) do&lt;br /&gt;
    result = [new_item] ++ state&lt;br /&gt;
    {:reply, result, result}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule ShoppingList do&lt;br /&gt;
  use GenServer&lt;br /&gt;
&lt;br /&gt;
  def start_link() do&lt;br /&gt;
    GenServer.start_link(ShoppingList, [])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def init(list) do&lt;br /&gt;
    {:ok, list}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def view(pid) do&lt;br /&gt;
    GenServer.call(pid, :view)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_call(:view, _from, list) do&lt;br /&gt;
    {:reply, list, list}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def add(pid, new_item) do&lt;br /&gt;
    GenServer.call(pid, {:item, new_item})&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_call({:item, new_item}, _from, state) do&lt;br /&gt;
    result = [new_item] ++ state&lt;br /&gt;
    {:reply, result, result}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://blog.appsignal.com/2018/06/12/elixir-alchemy-deconstructing-genservers.html&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule KeyValue do&lt;br /&gt;
  # 1&lt;br /&gt;
  def init(state \\ %{}) do&lt;br /&gt;
    {:ok, state}&lt;br /&gt;
  end&lt;br /&gt;
 &lt;br /&gt;
  # 2&lt;br /&gt;
  def handle_cast({:put, key, value}, state) do&lt;br /&gt;
    {:noreply, Map.put(state, key, value)}&lt;br /&gt;
  end&lt;br /&gt;
 &lt;br /&gt;
  # 3&lt;br /&gt;
  def handle_call({:get, key}, _from, state) do&lt;br /&gt;
    {:reply, Map.fetch!(state, key), state}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
# {:ok, pid} = GenServer.start(KeyValue, %{})&lt;br /&gt;
# GenServer.cast(pid, {:put, :foo, &amp;quot;bar&amp;quot;})&lt;br /&gt;
# GenServer.call(pid, {:get, :foo})&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Send messages via these functions wrapped in module functions .You can look at these are functions used to fire &amp;quot;GenServer Events&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
* start_link&lt;br /&gt;
* GenServer.call&lt;br /&gt;
* GenServer.cast&lt;br /&gt;
&lt;br /&gt;
The corresponding server functions that reply are:&lt;br /&gt;
&lt;br /&gt;
* init&lt;br /&gt;
* handle__call&lt;br /&gt;
* handle_cast&lt;br /&gt;
* &lt;br /&gt;
&lt;br /&gt;
These can be looked at as &amp;quot;listeners&amp;quot; - in JavaScript parlance. &lt;br /&gt;
__________________________________________&lt;br /&gt;
&lt;br /&gt;
If you have experience with programming languages other than Elixir the idea of GenServers may be very foreign and require a strong context shift to learn. This document is intended to simplify the concept.&lt;br /&gt;
&lt;br /&gt;
* What: GenServers are simply a way to hold state and/or invoke actions based on incoming events. &lt;br /&gt;
* when &lt;br /&gt;
* where&lt;br /&gt;
* why&lt;br /&gt;
* how&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
___________________________________________&lt;br /&gt;
GenServer timer example&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule Timer do&lt;br /&gt;
  use GenServer&lt;br /&gt;
&lt;br /&gt;
  def init(_) do&lt;br /&gt;
    :timer.send_interval(1000, :xyz)&lt;br /&gt;
    {:ok, 0}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_info(:xyz, state) do&lt;br /&gt;
    IO.inspect(state)&lt;br /&gt;
    {:noreply, state + 1}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
[&lt;br /&gt;
   {&lt;br /&gt;
     data:{&lt;br /&gt;
        creationTime,&lt;br /&gt;
        publishDate,&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
     featured:{&lt;br /&gt;
        setAmount,&lt;br /&gt;
        items:[]&lt;br /&gt;
     },&lt;br /&gt;
&lt;br /&gt;
     children:{&lt;br /&gt;
        setAmount,&lt;br /&gt;
        items:[]&lt;br /&gt;
     },&lt;br /&gt;
     links:{&lt;br /&gt;
        setAmount,&lt;br /&gt;
        items:[]&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
jason.encode / jason.decode&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  def run(num) do&lt;br /&gt;
&lt;br /&gt;
    Enum.each(0..99999, fn(_x) -&amp;gt;&lt;br /&gt;
      task = Task.async(fn -&amp;gt; num + _x end)&lt;br /&gt;
    IO.inspect Task.await(task)&lt;br /&gt;
  end)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enum.map(feed.entries, fn x -&amp;gt; %{url: x.url, title: x.title} end)&lt;br /&gt;
&lt;br /&gt;
App is split:&lt;br /&gt;
&lt;br /&gt;
App that captures RSS in UI and lets admin select stories. THere are settings to determine the number of FEATURED,CHILD and LINK stories.&lt;br /&gt;
News categories are horizontal and scrollable.&lt;br /&gt;
This exports a json doc with all RSS data for each story.&lt;br /&gt;
The &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
App that reads the json data. This app creates tables and is the front end.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://stephenbussey.com/tags/elixir.html&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule AppWeb.GroupLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  alias App.TestBeds&lt;br /&gt;
  alias App.Groups&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    {:ok, assign(socket, testbeds: TestBeds.list_testbeds(), groups: Groups.list_groups())}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;select-group&amp;quot;, params, socket)  do  &lt;br /&gt;
     group = App.Groups.get_group!(params[&amp;quot;group-id&amp;quot;])&lt;br /&gt;
     testbed = App.TestBeds.get_test_bed!(params[&amp;quot;testbed_id&amp;quot;])&lt;br /&gt;
     App.TestBeds.update_test_bed(testbed, %{group_id: group.id})&lt;br /&gt;
     {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def updated_groups(testbed_id)  do  &lt;br /&gt;
     testbed = App.TestBeds.get_test_bed!(testbed_id)&lt;br /&gt;
     groups = App.Groups.list_groups&lt;br /&gt;
     tail = Enum.filter(groups, fn(item)-&amp;gt; item.id !== testbed.group_id end)&lt;br /&gt;
     head = Enum.filter(groups, fn(item)-&amp;gt; item.id == testbed.group_id end)&lt;br /&gt;
            |&amp;gt;Enum.at(0)&lt;br /&gt;
    [head | tail]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        &amp;lt;%= for testbed &amp;lt;- Enum.sort_by(@testbeds , &amp;amp;(&amp;quot;#{&amp;amp;1.name}&amp;quot;), :asc)do %&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;grid grid-cols-4 gap-4 p-8 rounded shadow bg-white&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;h2&amp;gt; Name&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;%= testbed.name %&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;h2&amp;gt; Group&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div&amp;gt;&lt;br /&gt;
            &amp;lt;form phx-change=&amp;quot;select-group&amp;quot; name=&amp;quot;testbed_id&amp;quot;  &amp;gt;&lt;br /&gt;
               &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;testbed_id&amp;quot; value={testbed.id}/&amp;gt;&lt;br /&gt;
               &amp;lt;select id=&amp;quot;group-selection&amp;quot;  name=&amp;quot;group-id&amp;quot; class=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;%= for group &amp;lt;- updated_groups(testbed.id) do %&amp;gt;&lt;br /&gt;
                  &amp;lt;%= if group !== nil do %&amp;gt;&lt;br /&gt;
                      &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}&amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
                      &amp;lt;%else%&amp;gt;&lt;br /&gt;
                      &amp;lt;option value= {&amp;quot;Unassigned&amp;quot;}&amp;gt;NONE&amp;lt;/option&amp;gt;&lt;br /&gt;
                  &amp;lt;% end %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
               &amp;lt;/select&amp;gt;&lt;br /&gt;
            &amp;lt;/form&amp;gt;&lt;br /&gt;
          &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
       &amp;lt;% end %&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Developer Notes ==&lt;br /&gt;
===Groups Feature ===&lt;br /&gt;
To complete this feature do these things.&lt;br /&gt;
* Run through the steps in [http://elixirblocks.com/index.php?title=Create_Foreign_Key_Relationship_Between_Ecto_Tables  | this document] to create Group table.&lt;br /&gt;
* Groups have these fields  '''name: string''', '''description: string''' and '''color: string'''  &lt;br /&gt;
* Add unique constraint in migration file: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def change do&lt;br /&gt;
     create unique_index(:groups, [:name])&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Port over Group LiveView code (temporarily placed at discussion page).&lt;br /&gt;
* On completion '''possibly''', create a Group named '''No Group''' and set all Testbeds to it.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
________&lt;br /&gt;
https://blog.appsignal.com/2022/10/11/phoenix-liveview-018-new-special-html-attributes.html&lt;br /&gt;
https://blixtdev.com/whats-new-phoenix-1-7/&lt;br /&gt;
https://github.com/devato/inertia_phoenix&lt;br /&gt;
https://phoenixonrails.com/blog/you-can-stop-using-form-for-in-phoenix&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://samuelmullen.com/articles/phoenix_templates_rendering_and_layouts&lt;br /&gt;
&lt;br /&gt;
WorkFlow of Todo App in Both LiveView and DeadView.&lt;br /&gt;
&lt;br /&gt;
Note:&lt;br /&gt;
&lt;br /&gt;
Create foreign key data.&lt;br /&gt;
Create live view. List all testbeds and form to assign each a group by group-name.&lt;br /&gt;
&lt;br /&gt;
Repeat in dead view&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Mental model and data flows&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
home.html.heex&lt;br /&gt;
&amp;lt;a href=&amp;quot;/data&amp;quot; name=&amp;quot;we are the world&amp;quot; &amp;gt;  click me&amp;lt;/a&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;%= @message %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
page controller&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  def home(conn, _params) do&lt;br /&gt;
    IO.inspect _params&lt;br /&gt;
    render(conn, :home, message: &amp;quot;Hello&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
get &amp;quot;/:yay&amp;quot;, PageController, :index&lt;br /&gt;
&lt;br /&gt;
get &amp;quot;/&amp;quot;, PageController, :index&lt;br /&gt;
&lt;br /&gt;
* Explain control flow of &amp;quot;Dead Views&amp;quot; and the Generator HTML Control flow.&lt;br /&gt;
* Proper Way to use Modal&lt;br /&gt;
* How to give Focus to Fields in Modal (or other forms fields)&lt;br /&gt;
* &lt;br /&gt;
* &lt;br /&gt;
* How to Create Database Seed Data.&lt;br /&gt;
* How to structure code so controller code is in one file and HTML Heex is in another&lt;br /&gt;
* How to Use Generators in a Real World Project&lt;br /&gt;
* How to Work with Database Data via Basic Commands and Custom Change sets.&lt;br /&gt;
* How to Render Database Data to LiveView (via Context Commands).&lt;br /&gt;
* How to Create a Chat using PubSub.&lt;br /&gt;
* How to Create Event Handlers in LiveView&lt;br /&gt;
* How to Create a Dynamic Route from Scratch.&lt;br /&gt;
* How to Use Elixirs Template language&lt;br /&gt;
* How to Work with Modal&lt;br /&gt;
* How to Use CSS From Scratch (Without bundler)&lt;br /&gt;
* How to use JS hooks&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
______________________&lt;br /&gt;
https://studioindie.co/blog/heex-guide/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
get &amp;quot;/&amp;quot;, PageController, :some-atom    #This is the route. some-atom is the controller name&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  def some-atom(conn, _params) do                 # controller name&lt;br /&gt;
    # The home page is often custom made,&lt;br /&gt;
    # so skip the default app layout.&lt;br /&gt;
    render(conn, :some-atom, layout: false)      # :some-atom is template name&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Controllers page_html.ex contains &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageHTML do&lt;br /&gt;
  use AppWeb, :html&lt;br /&gt;
&lt;br /&gt;
  embed_templates &amp;quot;page_html/*&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''page_html''' is the name of the folder in '''Controllers/page_html'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Controllers/page_html/some-atom.html.heex  (this is the template) &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__________________________________________&lt;br /&gt;
Set all association with preload:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  def list_groups do&lt;br /&gt;
    Repo.all(Group)&lt;br /&gt;
     |&amp;gt; Repo.preload([:testbeds])&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Insert Child into Parent ===&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
App.get_group!(2) # arg is id&lt;br /&gt;
|&amp;gt; Ecto.build_assoc(:testbeds)&lt;br /&gt;
|&amp;gt; Repo.insert()&lt;br /&gt;
&lt;br /&gt;
Or&lt;br /&gt;
&lt;br /&gt;
group = App.get_group!(2) # arg is id&lt;br /&gt;
&lt;br /&gt;
testbeds = Ecto.build_assoc(group, :testbeds)&lt;br /&gt;
&lt;br /&gt;
App.Group.create_group(testbeds)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
group = App.Groups.get_group!(1)&lt;br /&gt;
thing = Ecto.build_assoc(group, :testbeds, name: &amp;quot;DUMB&amp;quot;)&lt;br /&gt;
alias App.{Repo}&lt;br /&gt;
Repo.insert(thing)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
avatar = %Avatar{nick_name: &amp;quot;Elixir&amp;quot;, pic_url: &amp;quot;http://elixir-lang.org/images/logo.png&amp;quot;}&lt;br /&gt;
user = %User{name: &amp;quot;John Doe&amp;quot;, email: &amp;quot;john.doe@example.com&amp;quot;, avatar: avatar}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://www.reddit.com/r/elixir/comments/oh318k/is_there_a_way_to_avoid_ectoassociationnotloaded/h4mmcfi/?utm_source=share&amp;amp;utm_medium=web3x&amp;amp;utm_name=web3xcss&amp;amp;utm_term=1&amp;amp;utm_content=share_button&lt;br /&gt;
&lt;br /&gt;
# Create Group Table&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
mix phx.gen.html Groups Group groups name:string  &lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Set the resources / &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
mix ecto.migrate&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For testbeds create a migration file and add this field:   group_id:references:groups&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
def change do&lt;br /&gt;
    alter table(:testbeds) do    # customize to your code&lt;br /&gt;
      add :group_id, references(:groups)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Update Groups Schema (Don't forget alias / has_many)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule App.Groups.Group do&lt;br /&gt;
	use Ecto.Schema&lt;br /&gt;
	import Ecto.Changeset&lt;br /&gt;
	alias App.Testbeds.Testbed   # Alias!&lt;br /&gt;
&lt;br /&gt;
	schema &amp;quot;posts&amp;quot; do&lt;br /&gt;
		field :body, :string&lt;br /&gt;
		field :title, :string&lt;br /&gt;
		has_many :testbeds, Testbed    # Has many&lt;br /&gt;
&lt;br /&gt;
		timestamps()&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	@doc false&lt;br /&gt;
	def changeset(post, attrs) do&lt;br /&gt;
		post&lt;br /&gt;
		|&amp;gt; cast(attrs, [:title, :body])&lt;br /&gt;
		|&amp;gt; validate_required([:title, :body])&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
TESTBEDS Schema&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule App.Testbeds.Testbed do&lt;br /&gt;
  use Ecto.Schema&lt;br /&gt;
  import Ecto.Changeset&lt;br /&gt;
  alias App.Groups.Group      # Alias&lt;br /&gt;
  schema &amp;quot;testbeds&amp;quot; do&lt;br /&gt;
    field :name, :string&lt;br /&gt;
    belongs_to :group, Group    # Belongs to&lt;br /&gt;
    timestamps()&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  @doc false&lt;br /&gt;
  def changeset(testbed, attrs) do&lt;br /&gt;
    testbed&lt;br /&gt;
    |&amp;gt; cast(attrs, [:name])&lt;br /&gt;
    |&amp;gt; validate_required([:name])&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
_____________________________________&lt;br /&gt;
Side notes.&lt;br /&gt;
&lt;br /&gt;
defmodule App.Repo.Migrations.CreateTestbeds do&lt;br /&gt;
  use Ecto.Migration&lt;br /&gt;
&lt;br /&gt;
  def change do&lt;br /&gt;
    create table(:testbeds) do&lt;br /&gt;
      add :name, :string&lt;br /&gt;
      add :group_id, references(:groups, on_delete: :nothing)&lt;br /&gt;
&lt;br /&gt;
      timestamps()&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    create index(:testbeds, [:group_id])&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
________________________________&lt;br /&gt;
&lt;br /&gt;
mix phx.gen.context Comments Comment comments name:string content:text post_id:references:posts&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
mix phx.gen.html Testbeds Testbed testbeds name:string  group_id:references:groups&lt;br /&gt;
&lt;br /&gt;
https://graffino.com/web-development/first-steps-in-elixir-and-phoenix-create-a-blog-prototype&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://blog.logrocket.com/getting-started-ecto-phoenix/&lt;br /&gt;
&lt;br /&gt;
https://serokell.io/blog/ecto-guide-for-beginners&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
mix phx.gen.html Testbeds Testbed testbeds name:string&lt;br /&gt;
&lt;br /&gt;
mix phx.gen.html Groups Group groups name:string&lt;br /&gt;
&lt;br /&gt;
Create migration for &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
mix ecto.gen.migration add_testbed_group_reference&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Migration:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  def change do&lt;br /&gt;
    alter table(:testbeds) do    # customize to your code&lt;br /&gt;
      add :group_id, references(:groups)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Manually Change:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule App.Group do&lt;br /&gt;
  use Ecto.Schema&lt;br /&gt;
&lt;br /&gt;
  schema &amp;quot;groups&amp;quot; do&lt;br /&gt;
    field :title, :string&lt;br /&gt;
    field :tagline, :string&lt;br /&gt;
    has_many :testbeds, App.Testbed&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
testbeds&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule App.Repo.Migrations.AddTextbedGroups do&lt;br /&gt;
  use Ecto.Migration&lt;br /&gt;
&lt;br /&gt;
  def change do&lt;br /&gt;
    create table(:testbeds) do&lt;br /&gt;
      add :name, :string&lt;br /&gt;
      add :group_id, references(:groups)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
# lib/app/testbeds.ex&lt;br /&gt;
&lt;br /&gt;
defmodule App.Testbed do&lt;br /&gt;
  use Ecto.Schema&lt;br /&gt;
&lt;br /&gt;
  schema &amp;quot;testbedss&amp;quot; do&lt;br /&gt;
    field :name, :string&lt;br /&gt;
    belongs_to :group, App.Group&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_____________________&lt;br /&gt;
&lt;br /&gt;
%App.TestBeds.TestBed{&lt;br /&gt;
  __meta__: #Ecto.Schema.Metadata&amp;lt;:loaded, &amp;quot;testbeds&amp;quot;&amp;gt;,&lt;br /&gt;
  id: 1,&lt;br /&gt;
  developer: &amp;quot;None&amp;quot;,&lt;br /&gt;
  name: &amp;quot;sdfsd&amp;quot;,&lt;br /&gt;
  owner: &amp;quot;sdfsddf&amp;quot;,&lt;br /&gt;
  note: &amp;quot;sdsfsddf&amp;quot;,&lt;br /&gt;
  status: &amp;quot;Available&amp;quot;,&lt;br /&gt;
  url: &amp;quot;sdf&amp;quot;,&lt;br /&gt;
  version: &amp;quot;ddf&amp;quot;,&lt;br /&gt;
  manager: &amp;quot;sf&amp;quot;,&lt;br /&gt;
  inserted_at: ~N[2023-08-21 13:45:39],&lt;br /&gt;
  updated_at: ~N[2023-08-21 13:45:44]&lt;br /&gt;
}&lt;br /&gt;
________________________________________________________________---&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.SendLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  &lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    {:ok, socket}&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  def handle_event(&amp;quot;send&amp;quot;, %{&amp;quot;text&amp;quot; =&amp;gt; text}, socket) do&lt;br /&gt;
&lt;br /&gt;
    AppWeb.Endpoint.broadcast(topic, &amp;quot;message&amp;quot;, text)&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  defp topic do&lt;br /&gt;
    &amp;quot;chat&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def render(assigns)do   &lt;br /&gt;
   ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
  &amp;lt;h1&amp;gt;Send Message&amp;lt;/h1&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;form phx-submit=&amp;quot;send&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;text&amp;quot; /&amp;gt;&lt;br /&gt;
    &amp;lt;button type=&amp;quot;submit&amp;quot;&amp;gt;Send&amp;lt;/button&amp;gt;&lt;br /&gt;
  &amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
______________________________________________________________&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.ReceiveLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  &lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    if connected?(socket) do&lt;br /&gt;
      AppWeb.Endpoint.subscribe(topic)&lt;br /&gt;
    end&lt;br /&gt;
    {:ok, assign(socket, messages: &amp;quot;&amp;quot;)}&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def handle_info(%{event: &amp;quot;message&amp;quot;, payload: message}, socket) do&lt;br /&gt;
    IO.inspect message&lt;br /&gt;
    {:noreply, assign(socket, messages: message)}&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  defp topic do&lt;br /&gt;
    &amp;quot;chat&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns)do   &lt;br /&gt;
   ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
  &amp;lt;h1&amp;gt;ChatLive&amp;lt;/h1&amp;gt;&lt;br /&gt;
  &amp;lt;%= @messages %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
______________________________________________________________&lt;br /&gt;
When you hover over a list of items this hook finds items with the same name and sets the opacity of all others to 0. You see all the items similar to the one you are hovering over.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
TestbedVersionHover: {&lt;br /&gt;
			// https://jsfiddle.net/IrvinDominin/7K2Z3/&lt;br /&gt;
            mounted() {&lt;br /&gt;
&lt;br /&gt;
                let rows = document.getElementsByClassName(&amp;quot;testbed-version&amp;quot;)&lt;br /&gt;
                // this.ele = element&lt;br /&gt;
				// rows = this.ele;&lt;br /&gt;
                &lt;br /&gt;
				for (var i = 0; i &amp;lt; rows.length; i++) {&lt;br /&gt;
					rows[i].onmouseenter = function (event) {&lt;br /&gt;
						for (var j = 0; j &amp;lt; rows.length; j++) {&lt;br /&gt;
							let preversion = this.textContent;&lt;br /&gt;
							let version = preversion.slice(0,5)&lt;br /&gt;
							let compareVersion = rows[j].textContent.slice(0,5)&lt;br /&gt;
							if (compareVersion === version) continue&lt;br /&gt;
							rows[j].className += &amp;quot; other&amp;quot;;&lt;br /&gt;
						}&lt;br /&gt;
					};&lt;br /&gt;
				&lt;br /&gt;
					rows[i].onmouseleave = function (event) {&lt;br /&gt;
						var hovers = document.getElementsByClassName('other');&lt;br /&gt;
						var len = hovers.length;&lt;br /&gt;
						for (var j = 0; j &amp;lt; len; j++) {&lt;br /&gt;
							hovers[0].className = hovers[0].className.replace(/\sother(\s|$)/, '');&lt;br /&gt;
						}&lt;br /&gt;
					};&lt;br /&gt;
				}&lt;br /&gt;
&lt;br /&gt;
                // this.ele.addEventListener(&amp;quot;click&amp;quot;, (e) =&amp;gt; {&lt;br /&gt;
                //     console.log(e.target)&lt;br /&gt;
                    &lt;br /&gt;
                // });&lt;br /&gt;
&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* How to Create Database Seed Data.&lt;br /&gt;
* How to structure code so controller code is in one file and HTML Heex is in another&lt;br /&gt;
* How to Use Generators in a Real World Project&lt;br /&gt;
* How to Work with Database Data via Basic Commands and Custom Change sets.&lt;br /&gt;
* How to Render Database Data to LiveView (via Context Commands).&lt;br /&gt;
* How to Create a Chat using PubSub.&lt;br /&gt;
* How to Create Event Handlers in LiveView&lt;br /&gt;
* How to Create a Dynamic Route from Scratch.&lt;br /&gt;
* How to Use Elixirs Template language&lt;br /&gt;
* How to Work with Modal&lt;br /&gt;
* How to Use CSS From Scratch (Without bundler)&lt;br /&gt;
* How to use JS hooks&lt;br /&gt;
* Dissect Table Component and Update it to Order List in Reverse.&lt;br /&gt;
&lt;br /&gt;
Selenium&lt;br /&gt;
https://www.builder.io/blog/debug-nodejs&lt;br /&gt;
&lt;br /&gt;
https://marketplace.visualstudio.com/items?itemName=ms-vscode.live-server#running-the-extension&lt;br /&gt;
&lt;br /&gt;
This was added recently (see microsoft/vscode#109276).&lt;br /&gt;
    1. Open the palette (Ctrl + Shift + P)&lt;br /&gt;
    2. Select &amp;quot;Simple Browser: Preview&amp;quot;&lt;br /&gt;
    3. Enter web address&lt;br /&gt;
&lt;br /&gt;
_______________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
const {By, Key, Builder} = require(&amp;quot;selenium-webdriver&amp;quot;);&lt;br /&gt;
const assert = require(&amp;quot;assert&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
require(&amp;quot;chromedriver&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
async function test_case(){&lt;br /&gt;
  let driver = await new Builder().forBrowser(&amp;quot;chrome&amp;quot;).build();&lt;br /&gt;
  await driver.get(&amp;quot;sie&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  await driver.findElement(By.name('password')).clear();&lt;br /&gt;
  await driver.findElement(By.name('identification')).clear();&lt;br /&gt;
  await driver.findElement(By.name('identification')).sendKeys(&amp;quot;bill&amp;quot;);&lt;br /&gt;
  await driver.findElement(By.name('password')).sendKeys(&amp;quot;password&amp;quot;, Key.RETURN);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 setTimeout(()=&amp;gt;{&lt;br /&gt;
   driver.findElement(By.className(&amp;quot;req_lan_license&amp;quot;)).click();&lt;br /&gt;
 },5000)&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageLive do &lt;br /&gt;
&lt;br /&gt;
  use AppWeb, :live_view  &lt;br /&gt;
  alias App.Testbeds &lt;br /&gt;
  def mount(_params, _session, socket)do   &lt;br /&gt;
     {:ok, assign(socket, testbeds: Testbeds.list_testbeds())}   &lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
    def button_event(&amp;quot;invoke_editing&amp;quot;) do&lt;br /&gt;
    %JS{}&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;active&amp;quot;, to: &amp;quot;#editing_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#editing_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#preview_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;active&amp;quot;, to: &amp;quot;#preview_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;active&amp;quot;, to: &amp;quot;#preview&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#preview&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#editing&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;active&amp;quot;, to: &amp;quot;#editing&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def button_event(&amp;quot;invoke_preview&amp;quot;) do&lt;br /&gt;
    %JS{}&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;active&amp;quot;, to: &amp;quot;#preview_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#preview_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#editing_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;active&amp;quot;, to: &amp;quot;#editing_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;active&amp;quot;, to: &amp;quot;#editing&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#editing&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#preview&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;active&amp;quot;, to: &amp;quot;#preview&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;send&amp;quot;, params, socket) do&lt;br /&gt;
    hide_modal(&amp;quot;notes-modal-0&amp;quot;)&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do  &lt;br /&gt;
     ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
		&amp;lt;.modal id={&amp;quot;notes-modal-#{testbed.id}&amp;quot;}&amp;gt;&lt;br /&gt;
		    &amp;lt;.button phx-click={button_event(&amp;quot;invoke_editing&amp;quot;)} id=&amp;quot;editing_button&amp;quot; class=&amp;quot;hidden&amp;quot;&amp;gt;&lt;br /&gt;
		      Preview&lt;br /&gt;
		    &amp;lt;/.button&amp;gt;&lt;br /&gt;
		    &amp;lt;.button phx-click={button_event(&amp;quot;invoke_preview&amp;quot;)} id=&amp;quot;preview_button&amp;quot;&amp;gt;&lt;br /&gt;
		      Edit Me&lt;br /&gt;
		    &amp;lt;/.button&amp;gt;&lt;br /&gt;
		    &amp;lt;div id=&amp;quot;editing&amp;quot;&amp;gt; PREVIEWING THE WORK&amp;lt;/div&amp;gt;&lt;br /&gt;
		    &amp;lt;form phx-submit = &amp;quot;send&amp;quot;   id=&amp;quot;preview&amp;quot; class=&amp;quot;hidden&amp;quot;&amp;gt;&lt;br /&gt;
		      &amp;lt;textarea value = {testbed.note}&amp;gt;&amp;lt;/textarea&amp;gt;&lt;br /&gt;
		      &amp;lt;.button type=&amp;quot;submit&amp;quot; phx-click={hide_modal(&amp;quot;notes-modal-#{testbed.id}&amp;quot;)}&amp;gt;SAVE WORK&amp;lt;/.button&amp;gt;&lt;br /&gt;
		    &amp;lt;/form&amp;gt;&lt;br /&gt;
		&amp;lt;/.modal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;%= if testbed.note do %&amp;gt;&lt;br /&gt;
      &amp;lt;div phx-click={show_modal(&amp;quot;notes-modal-#{testbed.id}&amp;quot;)}&amp;gt;READ ME  ...&amp;lt;%= testbed.note %&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
	   &lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
       &lt;br /&gt;
      &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
import {HfInference} from &amp;quot;@huggingface/inference&amp;quot;;&lt;br /&gt;
import dotenv from &amp;quot;dotenv&amp;quot;;&lt;br /&gt;
dotenv.config()&lt;br /&gt;
&lt;br /&gt;
const HF_ACCESS_TOKEN = process.env.HF_ACCESS_TOKEN&lt;br /&gt;
&lt;br /&gt;
const hf = new HfInference(HF_ACCESS_TOKEN);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*______Uncomment for this example______________________&lt;br /&gt;
&lt;br /&gt;
const model = &amp;quot;nlpconnect/vit-gpt2-image-captioning&amp;quot;;&lt;br /&gt;
const imageURL = &amp;quot;https://i.imgur.com/lTvb7Et.png&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
const response = await fetch(imageURL);&lt;br /&gt;
const imageBlob = await response.blob();&lt;br /&gt;
&lt;br /&gt;
const result  = await hf.imageToText({&lt;br /&gt;
	data: imageBlob,&lt;br /&gt;
	model: model,&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
_______________________________________________________*/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*________Another example ___________________*/&lt;br /&gt;
&lt;br /&gt;
const result = await hf.summarization({&lt;br /&gt;
	model: 'facebook/bart-large-cnn',&lt;br /&gt;
	inputs: &amp;quot;The role of a dumb man is to get smarter oogy bookie boo&amp;quot;,&lt;br /&gt;
	parameters:{&lt;br /&gt;
		max_length: 100&lt;br /&gt;
	}&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
console.log(result);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
________________________________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://fly.io/phoenix-files/sdeb-toggling-element/&lt;br /&gt;
https://www.youtube.com/watch?v=vBgZvQapqhs&lt;br /&gt;
&lt;br /&gt;
https://blog.testdouble.com/posts/2022-11-28-how-to-use-javascript-with-phoenix-liveview/&lt;br /&gt;
&lt;br /&gt;
https://hexdocs.pm/phoenix_live_view/0.19.3/Phoenix.Component.html&lt;br /&gt;
_______________________________________&lt;br /&gt;
https://www.smashingmagazine.com/2011/10/quick-look-math-animations-javascript/&lt;br /&gt;
* Depth first traversal&lt;br /&gt;
* Breadth first traversal&lt;br /&gt;
&lt;br /&gt;
https://dev.to/codesphere/10-algorithms-every-developer-should-learn-3lnm&lt;br /&gt;
&lt;br /&gt;
https://www.youtube.com/watch?v=fPz40W9mfCg&lt;br /&gt;
&lt;br /&gt;
__________________________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.GroupLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  alias App.TestBeds&lt;br /&gt;
  alias App.Groups&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    {:ok, assign(socket, testbeds: TestBeds.list_testbeds(), groups: Groups.list_groups())}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;select-group&amp;quot;, params, socket)  do  &lt;br /&gt;
         &lt;br /&gt;
       IO.inspect params&lt;br /&gt;
       {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div class=&amp;quot;grid grid-columns-2 grid-flow-col gap-4&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;column-1&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;%= testbed.name %&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;column-2&amp;quot;&amp;gt;    &lt;br /&gt;
            &amp;lt;form phx-change=&amp;quot;select-group&amp;quot;  &amp;gt;&lt;br /&gt;
               &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;testbed_id&amp;quot; value={testbed.id}/&amp;gt;&lt;br /&gt;
               &amp;lt;select id=&amp;quot;group-selection&amp;quot;  name=&amp;quot;group-id&amp;quot; &amp;gt;&lt;br /&gt;
                &amp;lt;%= for group &amp;lt;- @groups do %&amp;gt;&lt;br /&gt;
                  &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}  &amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
               &amp;lt;/select&amp;gt;&lt;br /&gt;
            &amp;lt;/form&amp;gt;&lt;br /&gt;
         &amp;lt;/div&amp;gt;&lt;br /&gt;
       &amp;lt;% end %&amp;gt;&lt;br /&gt;
   &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
____________________________&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.GroupLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  alias App.TestBeds&lt;br /&gt;
  alias App.Groups&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
&lt;br /&gt;
    {:ok, assign(socket, testbeds: TestBeds.list_testbeds(), groups: Groups.list_groups(), messages: [])}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;select-group&amp;quot;, params, socket)  do  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
      group = App.Groups.get_group!(params[&amp;quot;group-id&amp;quot;])&lt;br /&gt;
       # IO.inspect group&lt;br /&gt;
       testbed = App.TestBeds.get_test_bed!(params[&amp;quot;testbed_id&amp;quot;])&lt;br /&gt;
     &lt;br /&gt;
       App.TestBeds.update_test_bed(testbed, %{group_id: group.id})&lt;br /&gt;
         &lt;br /&gt;
    &lt;br /&gt;
       {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def updated_groups(testbed_id)  do  &lt;br /&gt;
       groups = App.Groups.list_groups&lt;br /&gt;
       tail = Enum.filter(groups, fn(item)-&amp;gt; item.id !== testbed_id end)&lt;br /&gt;
       head = Enum.filter(groups, fn(item)-&amp;gt; item.id == testbed_id end)&lt;br /&gt;
              |&amp;gt;Enum.at(0)&lt;br /&gt;
     [head | tail]&lt;br /&gt;
         &lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
 # def handle_event(&amp;quot;groups&amp;quot;, params, socket)do  &lt;br /&gt;
 #       selected_testbed = %{name: &amp;quot;my testbed name&amp;quot;, id: 3}&lt;br /&gt;
 #       groups = App.Groups.list_groups&lt;br /&gt;
 #       tail = Enum.filter(groups, fn(item)-&amp;gt; item.id !== selected_testbed.id end)&lt;br /&gt;
 #       head = Enum.filter(groups, fn(item)-&amp;gt; item.id == selected_testbed.id end)&lt;br /&gt;
 #              |&amp;gt;Enum.at(0)&lt;br /&gt;
         &lt;br /&gt;
 &lt;br /&gt;
 #       # result = Enum.filter([1, 2, 3], fn x -&amp;gt; x.id !== 1 end)&lt;br /&gt;
 #      IO.inspect [head | tail]&lt;br /&gt;
         &lt;br /&gt;
 #      #&lt;br /&gt;
 #      {:noreply, socket, assigns.message:}&lt;br /&gt;
 #  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    &lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
       &amp;lt;%!-- &amp;lt;div phx-click = &amp;quot;groups&amp;quot;&amp;gt;CLICK ME&amp;lt;/div&amp;gt; --%&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;grid grid-cols-4 gap-4 p-8 rounded shadow bg-white&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;h2&amp;gt; Name&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;%= testbed.name %&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;h2&amp;gt; Group&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;form phx-change=&amp;quot;select-group&amp;quot; name=&amp;quot;testbed_id&amp;quot;  &amp;gt;&lt;br /&gt;
               &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;testbed_id&amp;quot; value={testbed.id}/&amp;gt;&lt;br /&gt;
               &amp;lt;select id=&amp;quot;group-selection&amp;quot;  name=&amp;quot;group-id&amp;quot; class=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
                &amp;lt;%= for group &amp;lt;- updated_groups(testbed.id) do %&amp;gt;&lt;br /&gt;
                  &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}  &amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
                  &amp;lt;!-- Write code to reorder with testbed.group_id matching group_id --&amp;gt;&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
               &amp;lt;/select&amp;gt;&lt;br /&gt;
            &amp;lt;/form&amp;gt;&lt;br /&gt;
          &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
       &amp;lt;% end %&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_____________________________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
   use AppWeb, :live_view  &lt;br /&gt;
     alias App.Testbeds&lt;br /&gt;
  alias App.Groups&lt;br /&gt;
   def mount(_params, _session, socket)  do&lt;br /&gt;
	     {:ok, assign(socket, testbeds: Testbeds.list_testbeds(), groups: Groups.list_groups())}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
   def handle_event(&amp;quot;select-group&amp;quot;, params, socket)  do  &lt;br /&gt;
       group = App.Groups.get_group!(params[&amp;quot;group-id&amp;quot;])&lt;br /&gt;
       testbed = App.Testbeds.get_testbed!(params[&amp;quot;testbed_id&amp;quot;])&lt;br /&gt;
       result = App.Testbeds.update_testbed(testbed, %{group_id: group.id})&lt;br /&gt;
       IO.inspect result&lt;br /&gt;
      &lt;br /&gt;
       {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
    def updated_groups(testbed_id)  do  &lt;br /&gt;
       testbed = App.Testbeds.get_testbed!(testbed_id)&lt;br /&gt;
       groups = App.Groups.list_groups&lt;br /&gt;
       tail = Enum.filter(groups, fn(item)-&amp;gt; item.id !== testbed.group_id end)&lt;br /&gt;
       head = Enum.filter(groups, fn(item)-&amp;gt; item.id == testbed.group_id end)&lt;br /&gt;
              |&amp;gt;Enum.at(0)&lt;br /&gt;
 &lt;br /&gt;
       [head | tail]&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    &lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;grid grid-cols-4 gap-4 p-8 rounded shadow bg-white&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;h2&amp;gt; Name&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;%= testbed.name %&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;h2&amp;gt; Group&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;form phx-change=&amp;quot;select-group&amp;quot; name=&amp;quot;testbed_id&amp;quot;  &amp;gt;&lt;br /&gt;
               &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;testbed_id&amp;quot; value={testbed.id}/&amp;gt;&lt;br /&gt;
               &amp;lt;select id=&amp;quot;group-selection&amp;quot;  name=&amp;quot;group-id&amp;quot; class=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
                &amp;lt;%= for group &amp;lt;- updated_groups(testbed.id) do %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
                  &amp;lt;%!-- &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}&amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt; --%&amp;gt;&lt;br /&gt;
                  &amp;lt;!-- Write code to reorder with testbed.group_id matching group_id --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
                  &amp;lt;%= if group !== nil do %&amp;gt;&lt;br /&gt;
                      &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}&amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
       &lt;br /&gt;
                  &amp;lt;% end %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
               &amp;lt;/select&amp;gt;&lt;br /&gt;
            &amp;lt;/form&amp;gt;&lt;br /&gt;
          &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
       &amp;lt;% end %&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  has_many :testbeds, TestBed, on_delete: :restrict   # Has many&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://elixirforum.com/t/ecto-has-many-on-delete-protect/49550&lt;br /&gt;
&lt;br /&gt;
https://hexdocs.pm/ecto/Ecto.Changeset.html#unique_constraint/3&lt;br /&gt;
&lt;br /&gt;
____________________________________________________________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== How to Create a Mix Project and Use It in Another Mix Project ==&lt;br /&gt;
&lt;br /&gt;
To create and use a **Mix project** inside another **Mix project** in Elixir, follow the steps below:&lt;br /&gt;
&lt;br /&gt;
=== 1. Create a New Mix Project ===&lt;br /&gt;
&lt;br /&gt;
First, you need to create a new Mix project. Let's call this project `library_project`. Run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mix new library_project --module LibraryProject&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will create a new Elixir Mix project named `library_project`. The `--module` flag specifies the name of the module that will be created (in this case `LibraryProject`).&lt;br /&gt;
&lt;br /&gt;
The directory structure of `library_project` will look like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
library_project/&lt;br /&gt;
  |_ lib/&lt;br /&gt;
      |_ library_project.ex&lt;br /&gt;
  |_ mix.exs&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can then add some basic functionality inside the `library_project/lib/library_project.ex` file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule LibraryProject do&lt;br /&gt;
  def hello do&lt;br /&gt;
    IO.puts &amp;quot;Hello from LibraryProject!&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now, `library_project` is ready to be used by another Mix project.&lt;br /&gt;
&lt;br /&gt;
=== 2. Create a Second Mix Project ===&lt;br /&gt;
&lt;br /&gt;
Next, create the second Mix project where you want to use `library_project`. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mix new app_project --module AppProject&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will create another Elixir project called `app_project`.&lt;br /&gt;
&lt;br /&gt;
The directory structure for this project will look like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
app_project/&lt;br /&gt;
  |_ lib/&lt;br /&gt;
      |_ app_project.ex&lt;br /&gt;
  |_ mix.exs&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 3. Add `library_project` as a Dependency in `app_project` ===&lt;br /&gt;
&lt;br /&gt;
Now, you want to make `library_project` available in `app_project`. There are two main ways to do this:&lt;br /&gt;
&lt;br /&gt;
==== Option 1: Local Dependency (via `path`) ====&lt;br /&gt;
&lt;br /&gt;
If `library_project` is a local project (i.e., it's stored in a different directory), you can add it to the `mix.exs` of `app_project` as a local dependency by specifying the path to `library_project`.&lt;br /&gt;
&lt;br /&gt;
Edit the `mix.exs` of `app_project`:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule AppProject.MixProject do&lt;br /&gt;
  use Mix.Project&lt;br /&gt;
&lt;br /&gt;
  def project do&lt;br /&gt;
    [&lt;br /&gt;
      app: :app_project,&lt;br /&gt;
      version: &amp;quot;0.1.0&amp;quot;,&lt;br /&gt;
      elixir: &amp;quot;~&amp;gt; 1.14&amp;quot;,&lt;br /&gt;
      start_permanent: Mix.env() == :prod,&lt;br /&gt;
      deps: deps()&lt;br /&gt;
    ]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  defp deps do&lt;br /&gt;
    [&lt;br /&gt;
      {:library_project, path: &amp;quot;../library_project&amp;quot;}  # Add the local dependency&lt;br /&gt;
    ]&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here, `{:library_project, path: &amp;quot;../library_project&amp;quot;}` tells Mix to use the local `library_project` located in the `../library_project` directory (relative to `app_project`).&lt;br /&gt;
&lt;br /&gt;
After updating the `mix.exs`, run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd app_project&lt;br /&gt;
mix deps.get&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will fetch the dependency and compile `library_project`.&lt;br /&gt;
&lt;br /&gt;
==== Option 2: Publish and Fetch as a Hex Package ====&lt;br /&gt;
&lt;br /&gt;
If you want to use `library_project` as a package in another project (for example, by publishing it to **Hex.pm**, Elixir’s package manager), you need to publish it to Hex and then add it as a dependency.&lt;br /&gt;
&lt;br /&gt;
1. Publish `library_project` to Hex (if it's public or for your private use).&lt;br /&gt;
2. Add `library_project` to your `app_project`’s `mix.exs` dependencies:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defp deps do&lt;br /&gt;
  [&lt;br /&gt;
    {:library_project, &amp;quot;~&amp;gt; 0.1.0&amp;quot;}  # Specify the published version from Hex&lt;br /&gt;
  ]&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Run `mix deps.get` to fetch the package from Hex.&lt;br /&gt;
&lt;br /&gt;
=== 4. Use `library_project` in `app_project` ===&lt;br /&gt;
&lt;br /&gt;
Now, you can use the functionality from `library_project` inside your `app_project`. For example, in `app_project/lib/app_project.ex`, you can call the function from `library_project`:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule AppProject do&lt;br /&gt;
  def start do&lt;br /&gt;
    IO.puts &amp;quot;Starting app_project!&amp;quot;&lt;br /&gt;
    LibraryProject.hello()  # Call the function from the library_project&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 5. Run the App ===&lt;br /&gt;
&lt;br /&gt;
Finally, you can run your `app_project`:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd app_project&lt;br /&gt;
mix run -e &amp;quot;AppProject.start()&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will print:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Starting app_project!&lt;br /&gt;
Hello from LibraryProject!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Recap of the Process ==&lt;br /&gt;
1. **Create the `library_project`**: Use `mix new` to generate a library project.&lt;br /&gt;
2. **Create the `app_project`**: Create the second project where you will use the library.&lt;br /&gt;
3. **Add the `library_project` as a dependency**:&lt;br /&gt;
   - Use the `path` option to point to the local project or publish it to Hex for public access.&lt;br /&gt;
4. **Use the `library_project` in the `app_project`**: Call functions or use modules from the library inside the second project.&lt;br /&gt;
5. **Run the app**: Use `mix run` to execute the project.&lt;br /&gt;
&lt;br /&gt;
This way, you can reuse code from one Mix project in another by adding it as a dependency.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==z==&lt;br /&gt;
Overloaded functions are extremely common in Elixir applications. They are&lt;br /&gt;
regularly used for recursive functions and for changing behavior based on&lt;br /&gt;
configuration.&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>http://elixirblocks.com/index.php?title=User:Admin&amp;diff=1896</id>
		<title>User:Admin</title>
		<link rel="alternate" type="text/html" href="http://elixirblocks.com/index.php?title=User:Admin&amp;diff=1896"/>
		<updated>2025-04-02T18:41:17Z</updated>

		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Async claude ai example&lt;br /&gt;
&lt;br /&gt;
________________________&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.Sandbox do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    # Schedule the API call to happen after mount&lt;br /&gt;
    if connected?(socket), do: Process.send_after(self(), :fetch_data, 0)&lt;br /&gt;
    {:ok, assign(socket, data: nil)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_info(:fetch_data, socket) do&lt;br /&gt;
    # Launch API call in separate process&lt;br /&gt;
    Task.async(fn -&amp;gt; api() end)&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_info({ref, result}, socket) when is_reference(ref) do&lt;br /&gt;
    # Clean up the DOWN message&lt;br /&gt;
    Process.demonitor(ref, [:flush])&lt;br /&gt;
    {:noreply, assign(socket, data: result)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def api do&lt;br /&gt;
    Req.request(url: &amp;quot;https://api.github.com/repos/wojtekmach/req&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    SANDBOX&lt;br /&gt;
    &amp;lt;%= if @data, do: inspect(@data) %&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
___________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 defmodule Heading do&lt;br /&gt;
   use Phoenix.Component&lt;br /&gt;
   def head(assigns) do&lt;br /&gt;
	   ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	     &amp;lt;p&amp;gt;Hello, &amp;lt;%= @headings %&amp;gt;!&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	   &amp;quot;&amp;quot;&amp;quot; &lt;br /&gt;
   end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
   use AppWeb, :live_view  &lt;br /&gt;
   import Heading&lt;br /&gt;
   def mount(_params, _session, socket)  do&lt;br /&gt;
	 {:ok, socket}  &lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
   def headings do &lt;br /&gt;
    [&amp;quot;one&amp;quot;,&amp;quot;two&amp;quot;,&amp;quot;three&amp;quot;]&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
   def render(assigns) do&lt;br /&gt;
	   ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	     &amp;lt;Heading.head  headings={headings()} /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	   &amp;quot;&amp;quot;&amp;quot; &lt;br /&gt;
   end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://app.studyraid.com/en/read/11967/381872/component-communication&lt;br /&gt;
&lt;br /&gt;
https://thepugautomatic.com/2020/08/communicating-between-liveviews-on-the-same-page/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
from(a in Article,&lt;br /&gt;
  order_by: [desc: a.inserted_at],  # Assuming 'inserted_at' is the timestamp for when the article was created or updated&lt;br /&gt;
  limit: 8&lt;br /&gt;
)&lt;br /&gt;
|&amp;gt; Repo.all()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.Landing do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  alias App.Testbeds&lt;br /&gt;
  alias App.Testbeds.Testbed&lt;br /&gt;
  alias App.Repo  # Ensure to alias Repo&lt;br /&gt;
  import Ecto.Query  # Import Ecto.Query to work with queries&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    # Default to ordering by name&lt;br /&gt;
    testbeds = Repo.all(from(t in Testbed, order_by: t.name))&lt;br /&gt;
&lt;br /&gt;
    # Assign the testbeds to the socket for rendering&lt;br /&gt;
    {:ok, assign(socket, testbeds: testbeds, sort: :name)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    &amp;lt;h1&amp;gt;Hello World! YAY&amp;lt;/h1&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;div&amp;gt;&lt;br /&gt;
      &amp;lt;!-- Buttons to toggle sorting --&amp;gt;&lt;br /&gt;
      &amp;lt;button phx-click=&amp;quot;sort_by_name&amp;quot;&amp;gt;Sort by Name&amp;lt;/button&amp;gt;&lt;br /&gt;
      &amp;lt;button phx-click=&amp;quot;sort_by_updated_at&amp;quot;&amp;gt;Sort by Updated By&amp;lt;/button&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;ul&amp;gt;&lt;br /&gt;
      &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
        &amp;lt;li&amp;gt;&amp;lt;%= testbed.name %&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;% end %&amp;gt;&lt;br /&gt;
    &amp;lt;/ul&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;sort_by_name&amp;quot;, _params, socket) do&lt;br /&gt;
    testbeds = Repo.all(from(t in Testbed, order_by: t.name))&lt;br /&gt;
    {:noreply, assign(socket, testbeds: testbeds, sort: :name)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;sort_by_updated_at&amp;quot;, _params, socket) do&lt;br /&gt;
    testbeds = Repo.all(from(t in Testbed, order_by: t.inserted_at))&lt;br /&gt;
    {:noreply, assign(socket, testbeds: testbeds, sort: :inserted_at)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
_______________________________________________________&lt;br /&gt;
&lt;br /&gt;
* Create a form with a post request. &lt;br /&gt;
* Create the route needed for that request&lt;br /&gt;
* Create the controller needed for that route&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Form==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;.form action={~p&amp;quot;/todos&amp;quot;} method=&amp;quot;post&amp;quot; class=&amp;quot;mt-10 space-y-8&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    &amp;lt;label for=&amp;quot;contact_name&amp;quot; class=&amp;quot;block text-sm font-semibold leading-6 text-zinc-800&amp;quot;&amp;gt;&lt;br /&gt;
      Name&lt;br /&gt;
    &amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;input&lt;br /&gt;
      id=&amp;quot;todo&amp;quot;&lt;br /&gt;
      type=&amp;quot;text&amp;quot;&lt;br /&gt;
      name=&amp;quot;todo&amp;quot;&lt;br /&gt;
      class=&amp;quot;mt-2 block w-full rounded-lg text-zinc-900 focus:ring-0 sm:text-sm sm:leading-6 border-zinc-300 focus:border-zinc-400&amp;quot;&lt;br /&gt;
    /&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;button&lt;br /&gt;
    type=&amp;quot;submit&amp;quot;&lt;br /&gt;
    class=&amp;quot;rounded-lg bg-zinc-900 hover:bg-zinc-700 py-2 px-3 text-sm font-semibold leading-6 text-white active:text-white/80&amp;quot;&lt;br /&gt;
  &amp;gt;&lt;br /&gt;
    Save Contact&lt;br /&gt;
  &amp;lt;/button&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/.form&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Controller==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# In your TodoController&lt;br /&gt;
defmodule AppWeb.TodoController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  # Action to handle the form submission (POST request)&lt;br /&gt;
  def create(conn, %{&amp;quot;todo&amp;quot; =&amp;gt; todo_name}) do&lt;br /&gt;
    # Here you can handle the form data (e.g., save it to the database)&lt;br /&gt;
    IO.puts(&amp;quot;Received Todo: #{todo_name}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    # For now, let's just redirect to the home page&lt;br /&gt;
    conn&lt;br /&gt;
    |&amp;gt; put_flash(:info, &amp;quot;Todo saved!&amp;quot;)&lt;br /&gt;
    |&amp;gt; redirect(to: &amp;quot;/&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
________________________________________________________&lt;br /&gt;
&lt;br /&gt;
# CRUD Forms&lt;br /&gt;
&lt;br /&gt;
To understand CRUD forms you will need to understand the following concepts. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Ecto Schema&lt;br /&gt;
* Ecto Context&lt;br /&gt;
* Form Basics&lt;br /&gt;
* form/1&lt;br /&gt;
* simple_form/1&lt;br /&gt;
* changesets&lt;br /&gt;
&lt;br /&gt;
We are not going to go in order. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The Context provides CRUD functions for the chosen data schema. Phoenix contexts define the interface through which other parts of the codebase can interact with the app layer.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_______________________&lt;br /&gt;
* Create routes&lt;br /&gt;
* create page with form (submit get request)&lt;br /&gt;
&lt;br /&gt;
(ecto schema, context, changesets)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_______________________________________________________&lt;br /&gt;
In that case, you really should switch it to prod mode. Instead of doing all that above with the &amp;quot;config/secret.exs&amp;quot; file, create the &amp;quot;.env&amp;quot; in the project root, then add DotenvParser.load_file(&amp;quot;.env&amp;quot;) to &amp;quot;config/runtime.exs&amp;quot; as the first line inside the if config_env() == :prod do. In the .env file, set the DATABASE_URL and SECRET_KEY_BASE. Then run it as MIX_ENV=prod mix phx.server.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def get_titles do&lt;br /&gt;
    urls = [&lt;br /&gt;
      &amp;quot;https://cointelegraph.com/rss&amp;quot;,&lt;br /&gt;
      &amp;quot;https://chaski.huffpost.com/us/auto/vertical/us-news&amp;quot;&lt;br /&gt;
      # Add more RSS feed URLs here&lt;br /&gt;
    ]&lt;br /&gt;
&lt;br /&gt;
    urls&lt;br /&gt;
    |&amp;gt; Enum.map(fn url -&amp;gt;&lt;br /&gt;
      with {:ok, feed} &amp;lt;- ElixirRss.fetch_and_parse(url) do&lt;br /&gt;
        Enum.map(feed.entries, &amp;amp; &amp;amp;1.title)&lt;br /&gt;
      else&lt;br /&gt;
        {:error, reason} -&amp;gt; {:error, reason}&lt;br /&gt;
      end&lt;br /&gt;
    end)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule App do&lt;br /&gt;
&lt;br /&gt;
  def get_titles() do&lt;br /&gt;
    data = [&lt;br /&gt;
      &amp;quot;https://cointelegraph.com/rss&amp;quot;,&lt;br /&gt;
      &amp;quot;https://chaski.huffpost.com/us/auto/vertical/us-news&amp;quot;&lt;br /&gt;
      # Add more RSS feed URLs here&lt;br /&gt;
    ]&lt;br /&gt;
&lt;br /&gt;
    data&lt;br /&gt;
    |&amp;gt; Enum.map(fn url -&amp;gt;&lt;br /&gt;
      case ElixirRss.fetch_and_parse(url) do&lt;br /&gt;
        {:ok, feed} -&amp;gt; feed.entries |&amp;gt; Enum.map(fn entry -&amp;gt; entry end)&lt;br /&gt;
        {:error, reason} -&amp;gt; {:error, reason}&lt;br /&gt;
      end&lt;br /&gt;
    end)&lt;br /&gt;
    |&amp;gt; Enum.map(fn entry_list -&amp;gt;&lt;br /&gt;
      entry_list&lt;br /&gt;
      |&amp;gt; Enum.map(fn entry -&amp;gt; entry.title end)&lt;br /&gt;
    end)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def hello do&lt;br /&gt;
    rss_feeds = [&lt;br /&gt;
      &amp;quot;https://cointelegraph.com/rss&amp;quot;,&lt;br /&gt;
      &amp;quot;https://chaski.huffpost.com/us/auto/vertical/us-news&amp;quot;&lt;br /&gt;
      # Add more RSS feed URLs here&lt;br /&gt;
    ]&lt;br /&gt;
&lt;br /&gt;
    rss_feeds&lt;br /&gt;
    |&amp;gt; Enum.map(fn url -&amp;gt;&lt;br /&gt;
      case ElixirRss.fetch_and_parse(url) do&lt;br /&gt;
        {:ok, feed} -&amp;gt; feed.entries |&amp;gt; Enum.map(fn entry -&amp;gt; entry end)&lt;br /&gt;
        {:error, reason} -&amp;gt; {:error, reason}&lt;br /&gt;
      end&lt;br /&gt;
    end)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    if connected?(socket) do&lt;br /&gt;
      Phoenix.PubSub.subscribe(App.PubSub, &amp;quot;message&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
    {:ok, assign(socket, message_item: &amp;quot;different&amp;quot;)}&lt;br /&gt;
  end&lt;br /&gt;
  def handle_info({:pubsub_transmission, text}, socket) do&lt;br /&gt;
    IO.inspect &amp;quot;pub sub working&amp;quot;&lt;br /&gt;
    {:noreply, assign(socket, message_item: text)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def loop(data) do&lt;br /&gt;
     IO.inspect data&lt;br /&gt;
     if data &amp;gt; 0 do&lt;br /&gt;
      IO.inspect &amp;quot;notify&amp;quot;&lt;br /&gt;
      # run code to compare files, loop. If different run pubsub code below&lt;br /&gt;
      :timer.sleep(2000)&lt;br /&gt;
      loop(data-1)&lt;br /&gt;
&lt;br /&gt;
     end&lt;br /&gt;
     if data &amp;lt;= 0 do&lt;br /&gt;
&lt;br /&gt;
      Phoenix.PubSub.broadcast(App.PubSub, &amp;quot;message&amp;quot;, {:pubsub_transmission, &amp;quot;data&amp;quot;})&lt;br /&gt;
      &amp;quot;done&amp;quot;&lt;br /&gt;
     end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;change-text&amp;quot;, _params, socket) do&lt;br /&gt;
    spawn(fn -&amp;gt; loop(3) end)&lt;br /&gt;
    {:noreply, assign(socket, message_item: &amp;quot;START&amp;quot; )}&lt;br /&gt;
  end&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
&lt;br /&gt;
    # AppWeb.PageLive.loop(&amp;quot;xxx&amp;quot;)&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    SANDBOX&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;.button phx-click=&amp;quot;change-text&amp;quot; value={@message_item}&amp;gt;CLICK ME&amp;lt;/.button&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;%= @message_item %&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
elixir :   1.16.2&lt;br /&gt;
&lt;br /&gt;
Erl:   20&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# PostGres&lt;br /&gt;
Created Saturday 18 February 2023&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Launch [PostGres](#PostGres) from Terminal&lt;br /&gt;
------------------------------------------&lt;br /&gt;
sudo -u postgres psql&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Set User Permission&lt;br /&gt;
-------------------&lt;br /&gt;
&amp;lt;https://commandprompt.com/education/how-to-create-a-superuser-in-postgresql/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ALTER USER user_name WITH PASSWORD 'new_password';&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Run Post Gres Commands&lt;br /&gt;
----------------------&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
sudo -i -u postgres&lt;br /&gt;
psql&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Create and Delete Database&lt;br /&gt;
&lt;br /&gt;
CREATE DATABASE name;&lt;br /&gt;
DROP DATABASE name;&lt;br /&gt;
## View user list&lt;br /&gt;
&lt;br /&gt;
\du&lt;br /&gt;
&lt;br /&gt;
 View all databases&lt;br /&gt;
&lt;br /&gt;
postgres=# \l&lt;br /&gt;
&lt;br /&gt;
 Change databases&lt;br /&gt;
&lt;br /&gt;
postgres=# \c    name-of-database&lt;br /&gt;
&lt;br /&gt;
View Tables&lt;br /&gt;
&lt;br /&gt;
After you change databases and are selected on one of them do this:&lt;br /&gt;
&lt;br /&gt;
\dt&lt;br /&gt;
&lt;br /&gt;
SELECT * FROM mytablename;&lt;br /&gt;
&lt;br /&gt;
EMPTY TABLE&lt;br /&gt;
DELETE FROM name-of-table&lt;br /&gt;
&lt;br /&gt;
CREATE TABLE&lt;br /&gt;
&lt;br /&gt;
CREATE TABLE table_name(&lt;br /&gt;
   column1 datatype,&lt;br /&gt;
   column2 datatype,&lt;br /&gt;
   column3 datatype,&lt;br /&gt;
   .....&lt;br /&gt;
   columnN datatype,&lt;br /&gt;
   PRIMARY KEY( one or more columns )&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
INSERT&lt;br /&gt;
&lt;br /&gt;
INSERT INTO ITEMS(id, name) VALUES(1,'htvjbjbgni');     Strings are single quote&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Roadmap==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.ItemsLive do&lt;br /&gt;
    use AppWeb, :live_view  &lt;br /&gt;
    def mount(_params, _session, socket)  do&lt;br /&gt;
      {:ok, assign(socket, switches: [&amp;quot;grindy&amp;quot;,&amp;quot;sonic&amp;quot;,&amp;quot;ogre&amp;quot;])}  &lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    def handle_event(&amp;quot;run&amp;quot;,_params,socket) do  &lt;br /&gt;
        &lt;br /&gt;
        IO.inspect &amp;quot;DOWNLOAD VIA SSH&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        {:noreply, redirect(socket, to: &amp;quot;/download&amp;quot;)}&lt;br /&gt;
&lt;br /&gt;
    end&lt;br /&gt;
   &lt;br /&gt;
&lt;br /&gt;
    def render(assigns) do&lt;br /&gt;
        &lt;br /&gt;
        ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        &amp;lt;ul&amp;gt;&lt;br /&gt;
        &amp;lt;%= for switch &amp;lt;- @switches do %&amp;gt;&lt;br /&gt;
         &amp;lt;a phx-submit=&amp;quot;click&amp;quot; href=&amp;quot;/download&amp;quot;&amp;gt;  &amp;lt;li&amp;gt; &amp;lt;%= switch %&amp;gt;  &amp;lt;/li&amp;gt; &amp;lt;/a&amp;gt;&lt;br /&gt;
&lt;br /&gt;
        &amp;lt;%end%&amp;gt;&lt;br /&gt;
        &amp;lt;/ul&amp;gt;&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot; &lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Notes==&lt;br /&gt;
List of Switches and the option to select the one needed.&lt;br /&gt;
Button to download JSON file.&lt;br /&gt;
Drag and Drop Palette to upload JSON file.&lt;br /&gt;
&lt;br /&gt;
After JSON file is uploaded a button titled &amp;quot;Make Active&amp;quot; is available.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://medium.com/@fraiha26/pushing-events-to-livecomponents-from-js-hooks-w-phoenix-elixir-d5544d4c3dfa&lt;br /&gt;
&lt;br /&gt;
Changeset notes and forms&lt;br /&gt;
&lt;br /&gt;
NOTE: Use case statements for pattern matching&lt;br /&gt;
____________________________________________&lt;br /&gt;
&lt;br /&gt;
Create a basic &amp;lt;.form&amp;gt;&amp;lt;/form&amp;gt; without error handling&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&amp;lt;.form :let={f} for={@changeset}  action={~p&amp;quot;/items&amp;quot;} &amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;.input field={f[:title]} type=&amp;quot;text&amp;quot; label=&amp;quot;Title&amp;quot; /&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
  &amp;lt;.button&amp;gt;Save Item&amp;lt;/.button&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;/.form&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With error handling looks like this:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;.form :let={f} for={@changeset}  action={~p&amp;quot;/items&amp;quot;} &amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;.error :if={@changeset.action}&amp;gt;&lt;br /&gt;
    Oops, something went wrong! Please check the errors below.&lt;br /&gt;
  &amp;lt;/.error&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;.input field={f[:title]} type=&amp;quot;text&amp;quot; label=&amp;quot;Title&amp;quot; /&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
  &amp;lt;.button&amp;gt;Save Item&amp;lt;/.button&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;/.form&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Create the routes for render and post to endpoint.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The controller for the page render needs to pass in the changeset via ```Items.change_item(%Item{})```&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  def new(conn, _params) do&lt;br /&gt;
    changeset = Items.change_item(%Item{})&lt;br /&gt;
    render(conn, :new, changeset: changeset)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Post route without error handling&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  def create(conn, %{&amp;quot;item&amp;quot; =&amp;gt; item_params}) do&lt;br /&gt;
    case Items.create_item(item_params) do&lt;br /&gt;
      {:ok, item} -&amp;gt;&lt;br /&gt;
        conn&lt;br /&gt;
        |&amp;gt; put_flash(:info, &amp;quot;Item created successfully.&amp;quot;)&lt;br /&gt;
        |&amp;gt; redirect(to: ~p&amp;quot;/items/#{item}&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With error handling&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  def create(conn, %{&amp;quot;item&amp;quot; =&amp;gt; item_params}) do&lt;br /&gt;
    case Items.create_item(item_params) do&lt;br /&gt;
      {:ok, item} -&amp;gt;&lt;br /&gt;
        conn&lt;br /&gt;
        |&amp;gt; put_flash(:info, &amp;quot;Item created successfully.&amp;quot;)&lt;br /&gt;
        |&amp;gt; redirect(to: ~p&amp;quot;/items/#{item}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
      {:error, %Ecto.Changeset{} = changeset} -&amp;gt;&lt;br /&gt;
        render(conn, :new, changeset: changeset)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_____________________________________________&lt;br /&gt;
https://medium.com/@vincentlin/phoenix-very-simple-form-c4b121697fcb&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''home.html.heex'''&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&amp;lt;form action=&amp;quot;/submit&amp;quot; method=&amp;quot;post&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;label for=&amp;quot;name&amp;quot;&amp;gt;Name:&amp;lt;/label&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;input type=&amp;quot;text&amp;quot; id=&amp;quot;name&amp;quot; name=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;_csrf_token&amp;quot; value={@csrf_token} /&amp;gt;&lt;br /&gt;
  &amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Submit&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
page_controller.ex&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.PageController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  def home(conn, _params) do&lt;br /&gt;
    # The home page is often custom made,&lt;br /&gt;
&lt;br /&gt;
    csrf_token = Plug.CSRFProtection.get_csrf_token()&lt;br /&gt;
    render(conn, :home, csrf_token: csrf_token)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def submit(conn, _params) do&lt;br /&gt;
    # The home page is often custom made,&lt;br /&gt;
     IO.inspect(_params)&lt;br /&gt;
     IO.inspect &amp;quot;___________________________&amp;quot;&lt;br /&gt;
    csrf_token = Plug.CSRFProtection.get_csrf_token()&lt;br /&gt;
    render(conn, :home, csrf_token: csrf_token)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
router.ex&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  scope &amp;quot;/&amp;quot;, AppWeb do&lt;br /&gt;
    pipe_through :browser&lt;br /&gt;
    post &amp;quot;/submit&amp;quot;, PageController, :submit&lt;br /&gt;
    get &amp;quot;/&amp;quot;, PageController, :home&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ecto.Adapters.SQL.query(Repo, &amp;quot;select * from artists where id=1&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ecto cheatsheet:  https://hexdocs.pm/ecto/crud.html&lt;br /&gt;
__________________________________________________________________&lt;br /&gt;
Most programming languages give you the ability to set global state by creating globally scoped variables. Elixir does not do this. Instead, Elixir provides a tool called a &amp;quot;processes&amp;quot; to persist  state. Elixir applications are composed of these &amp;quot;processes&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
Processes by themselves are complicated to use, thus Elixir provides abstractions to make working with processes easier. One of these abstractions is called a GenServer.&lt;br /&gt;
&lt;br /&gt;
GenServers are not only used to store state, they are also used to invoke work independent of the main application process. &lt;br /&gt;
&lt;br /&gt;
==Creating a GenServer to Store State==&lt;br /&gt;
&lt;br /&gt;
To Create a GenServer, start by creating a basic Module that ''uses'' the GenServer module (image below)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule App do  &lt;br /&gt;
  use GenServer&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We now need to describe the actions we want to perform. Being that this is used to store state, we will use basic CRUD actions: Create, Read, Update, Delete. To begins, empty functions describing each action is created.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule App do&lt;br /&gt;
   def create do &lt;br /&gt;
&lt;br /&gt;
   end&lt;br /&gt;
   def read do &lt;br /&gt;
&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
   def update do  &lt;br /&gt;
&lt;br /&gt;
   end &lt;br /&gt;
&lt;br /&gt;
   def delete do &lt;br /&gt;
&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==What now?==&lt;br /&gt;
&lt;br /&gt;
To fill in the functions with the appropriate code we must first have a basic understanding of how GenServers are structured.&lt;br /&gt;
&lt;br /&gt;
GenServers are composed of the GenServer module invoking callbacks. The callbacks have built in names that you, as a developer have to use.&lt;br /&gt;
&lt;br /&gt;
These callbacks are named:&lt;br /&gt;
&lt;br /&gt;
* init&lt;br /&gt;
* handle_cast&lt;br /&gt;
* handle_call&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To demonstrate, here is an example :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{:ok, pid} = GenServer.start(ModuleNameOfGenServer, %{})&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above function named &amp;quot;start&amp;quot; calls the function named init in the Module below.&lt;br /&gt;
In GenServer syntax the name of the GenServer functions always invoke callbacks that are determined by the language. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule ModuleNameOfGenServer do&lt;br /&gt;
  # 1&lt;br /&gt;
  def init(state \\ %{}) do&lt;br /&gt;
    {:ok, state}&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is a list of the GenServer functions and their corresponding callbacks.&lt;br /&gt;
&lt;br /&gt;
* GenServer.start/1  --&amp;gt;       init/1&lt;br /&gt;
* GenServer.call/3   --&amp;gt;       def handle_call/3&lt;br /&gt;
* GenServer.cast/2   --&amp;gt;       handle_cast/2&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Start and Call ==&lt;br /&gt;
&lt;br /&gt;
Call and Cast can be used to perform the same operations. The &lt;br /&gt;
&lt;br /&gt;
__________________________________________________________&lt;br /&gt;
Genserver timed events&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule Go do&lt;br /&gt;
  use GenServer&lt;br /&gt;
&lt;br /&gt;
  def go() do&lt;br /&gt;
    GenServer.start_link(__MODULE__, [])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def init(list) do&lt;br /&gt;
    :timer.apply_interval(1000, __MODULE__, :add, [self(), &amp;quot;weeeee&amp;quot;])&lt;br /&gt;
    {:ok, list}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def view(pid) do&lt;br /&gt;
    GenServer.call(pid, :view)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_call(:view, _from, list) do&lt;br /&gt;
    {:reply, list, list}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def add(pid, new_item) do&lt;br /&gt;
    GenServer.call(pid, {:item, new_item})&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_call({:item, new_item}, _from, state) do&lt;br /&gt;
    result = [new_item] ++ state&lt;br /&gt;
    {:reply, result, result}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule ShoppingList do&lt;br /&gt;
  use GenServer&lt;br /&gt;
&lt;br /&gt;
  def start_link() do&lt;br /&gt;
    GenServer.start_link(ShoppingList, [])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def init(list) do&lt;br /&gt;
    {:ok, list}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def view(pid) do&lt;br /&gt;
    GenServer.call(pid, :view)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_call(:view, _from, list) do&lt;br /&gt;
    {:reply, list, list}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def add(pid, new_item) do&lt;br /&gt;
    GenServer.call(pid, {:item, new_item})&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_call({:item, new_item}, _from, state) do&lt;br /&gt;
    result = [new_item] ++ state&lt;br /&gt;
    {:reply, result, result}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://blog.appsignal.com/2018/06/12/elixir-alchemy-deconstructing-genservers.html&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule KeyValue do&lt;br /&gt;
  # 1&lt;br /&gt;
  def init(state \\ %{}) do&lt;br /&gt;
    {:ok, state}&lt;br /&gt;
  end&lt;br /&gt;
 &lt;br /&gt;
  # 2&lt;br /&gt;
  def handle_cast({:put, key, value}, state) do&lt;br /&gt;
    {:noreply, Map.put(state, key, value)}&lt;br /&gt;
  end&lt;br /&gt;
 &lt;br /&gt;
  # 3&lt;br /&gt;
  def handle_call({:get, key}, _from, state) do&lt;br /&gt;
    {:reply, Map.fetch!(state, key), state}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
# {:ok, pid} = GenServer.start(KeyValue, %{})&lt;br /&gt;
# GenServer.cast(pid, {:put, :foo, &amp;quot;bar&amp;quot;})&lt;br /&gt;
# GenServer.call(pid, {:get, :foo})&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Send messages via these functions wrapped in module functions .You can look at these are functions used to fire &amp;quot;GenServer Events&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
* start_link&lt;br /&gt;
* GenServer.call&lt;br /&gt;
* GenServer.cast&lt;br /&gt;
&lt;br /&gt;
The corresponding server functions that reply are:&lt;br /&gt;
&lt;br /&gt;
* init&lt;br /&gt;
* handle__call&lt;br /&gt;
* handle_cast&lt;br /&gt;
* &lt;br /&gt;
&lt;br /&gt;
These can be looked at as &amp;quot;listeners&amp;quot; - in JavaScript parlance. &lt;br /&gt;
__________________________________________&lt;br /&gt;
&lt;br /&gt;
If you have experience with programming languages other than Elixir the idea of GenServers may be very foreign and require a strong context shift to learn. This document is intended to simplify the concept.&lt;br /&gt;
&lt;br /&gt;
* What: GenServers are simply a way to hold state and/or invoke actions based on incoming events. &lt;br /&gt;
* when &lt;br /&gt;
* where&lt;br /&gt;
* why&lt;br /&gt;
* how&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
___________________________________________&lt;br /&gt;
GenServer timer example&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule Timer do&lt;br /&gt;
  use GenServer&lt;br /&gt;
&lt;br /&gt;
  def init(_) do&lt;br /&gt;
    :timer.send_interval(1000, :xyz)&lt;br /&gt;
    {:ok, 0}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_info(:xyz, state) do&lt;br /&gt;
    IO.inspect(state)&lt;br /&gt;
    {:noreply, state + 1}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
[&lt;br /&gt;
   {&lt;br /&gt;
     data:{&lt;br /&gt;
        creationTime,&lt;br /&gt;
        publishDate,&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
     featured:{&lt;br /&gt;
        setAmount,&lt;br /&gt;
        items:[]&lt;br /&gt;
     },&lt;br /&gt;
&lt;br /&gt;
     children:{&lt;br /&gt;
        setAmount,&lt;br /&gt;
        items:[]&lt;br /&gt;
     },&lt;br /&gt;
     links:{&lt;br /&gt;
        setAmount,&lt;br /&gt;
        items:[]&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
jason.encode / jason.decode&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  def run(num) do&lt;br /&gt;
&lt;br /&gt;
    Enum.each(0..99999, fn(_x) -&amp;gt;&lt;br /&gt;
      task = Task.async(fn -&amp;gt; num + _x end)&lt;br /&gt;
    IO.inspect Task.await(task)&lt;br /&gt;
  end)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enum.map(feed.entries, fn x -&amp;gt; %{url: x.url, title: x.title} end)&lt;br /&gt;
&lt;br /&gt;
App is split:&lt;br /&gt;
&lt;br /&gt;
App that captures RSS in UI and lets admin select stories. THere are settings to determine the number of FEATURED,CHILD and LINK stories.&lt;br /&gt;
News categories are horizontal and scrollable.&lt;br /&gt;
This exports a json doc with all RSS data for each story.&lt;br /&gt;
The &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
App that reads the json data. This app creates tables and is the front end.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://stephenbussey.com/tags/elixir.html&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule AppWeb.GroupLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  alias App.TestBeds&lt;br /&gt;
  alias App.Groups&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    {:ok, assign(socket, testbeds: TestBeds.list_testbeds(), groups: Groups.list_groups())}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;select-group&amp;quot;, params, socket)  do  &lt;br /&gt;
     group = App.Groups.get_group!(params[&amp;quot;group-id&amp;quot;])&lt;br /&gt;
     testbed = App.TestBeds.get_test_bed!(params[&amp;quot;testbed_id&amp;quot;])&lt;br /&gt;
     App.TestBeds.update_test_bed(testbed, %{group_id: group.id})&lt;br /&gt;
     {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def updated_groups(testbed_id)  do  &lt;br /&gt;
     testbed = App.TestBeds.get_test_bed!(testbed_id)&lt;br /&gt;
     groups = App.Groups.list_groups&lt;br /&gt;
     tail = Enum.filter(groups, fn(item)-&amp;gt; item.id !== testbed.group_id end)&lt;br /&gt;
     head = Enum.filter(groups, fn(item)-&amp;gt; item.id == testbed.group_id end)&lt;br /&gt;
            |&amp;gt;Enum.at(0)&lt;br /&gt;
    [head | tail]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        &amp;lt;%= for testbed &amp;lt;- Enum.sort_by(@testbeds , &amp;amp;(&amp;quot;#{&amp;amp;1.name}&amp;quot;), :asc)do %&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;grid grid-cols-4 gap-4 p-8 rounded shadow bg-white&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;h2&amp;gt; Name&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;%= testbed.name %&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;h2&amp;gt; Group&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div&amp;gt;&lt;br /&gt;
            &amp;lt;form phx-change=&amp;quot;select-group&amp;quot; name=&amp;quot;testbed_id&amp;quot;  &amp;gt;&lt;br /&gt;
               &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;testbed_id&amp;quot; value={testbed.id}/&amp;gt;&lt;br /&gt;
               &amp;lt;select id=&amp;quot;group-selection&amp;quot;  name=&amp;quot;group-id&amp;quot; class=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;%= for group &amp;lt;- updated_groups(testbed.id) do %&amp;gt;&lt;br /&gt;
                  &amp;lt;%= if group !== nil do %&amp;gt;&lt;br /&gt;
                      &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}&amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
                      &amp;lt;%else%&amp;gt;&lt;br /&gt;
                      &amp;lt;option value= {&amp;quot;Unassigned&amp;quot;}&amp;gt;NONE&amp;lt;/option&amp;gt;&lt;br /&gt;
                  &amp;lt;% end %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
               &amp;lt;/select&amp;gt;&lt;br /&gt;
            &amp;lt;/form&amp;gt;&lt;br /&gt;
          &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
       &amp;lt;% end %&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Developer Notes ==&lt;br /&gt;
===Groups Feature ===&lt;br /&gt;
To complete this feature do these things.&lt;br /&gt;
* Run through the steps in [http://elixirblocks.com/index.php?title=Create_Foreign_Key_Relationship_Between_Ecto_Tables  | this document] to create Group table.&lt;br /&gt;
* Groups have these fields  '''name: string''', '''description: string''' and '''color: string'''  &lt;br /&gt;
* Add unique constraint in migration file: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def change do&lt;br /&gt;
     create unique_index(:groups, [:name])&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Port over Group LiveView code (temporarily placed at discussion page).&lt;br /&gt;
* On completion '''possibly''', create a Group named '''No Group''' and set all Testbeds to it.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
________&lt;br /&gt;
https://blog.appsignal.com/2022/10/11/phoenix-liveview-018-new-special-html-attributes.html&lt;br /&gt;
https://blixtdev.com/whats-new-phoenix-1-7/&lt;br /&gt;
https://github.com/devato/inertia_phoenix&lt;br /&gt;
https://phoenixonrails.com/blog/you-can-stop-using-form-for-in-phoenix&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://samuelmullen.com/articles/phoenix_templates_rendering_and_layouts&lt;br /&gt;
&lt;br /&gt;
WorkFlow of Todo App in Both LiveView and DeadView.&lt;br /&gt;
&lt;br /&gt;
Note:&lt;br /&gt;
&lt;br /&gt;
Create foreign key data.&lt;br /&gt;
Create live view. List all testbeds and form to assign each a group by group-name.&lt;br /&gt;
&lt;br /&gt;
Repeat in dead view&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Mental model and data flows&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
home.html.heex&lt;br /&gt;
&amp;lt;a href=&amp;quot;/data&amp;quot; name=&amp;quot;we are the world&amp;quot; &amp;gt;  click me&amp;lt;/a&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;%= @message %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
page controller&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  def home(conn, _params) do&lt;br /&gt;
    IO.inspect _params&lt;br /&gt;
    render(conn, :home, message: &amp;quot;Hello&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
get &amp;quot;/:yay&amp;quot;, PageController, :index&lt;br /&gt;
&lt;br /&gt;
get &amp;quot;/&amp;quot;, PageController, :index&lt;br /&gt;
&lt;br /&gt;
* Explain control flow of &amp;quot;Dead Views&amp;quot; and the Generator HTML Control flow.&lt;br /&gt;
* Proper Way to use Modal&lt;br /&gt;
* How to give Focus to Fields in Modal (or other forms fields)&lt;br /&gt;
* &lt;br /&gt;
* &lt;br /&gt;
* How to Create Database Seed Data.&lt;br /&gt;
* How to structure code so controller code is in one file and HTML Heex is in another&lt;br /&gt;
* How to Use Generators in a Real World Project&lt;br /&gt;
* How to Work with Database Data via Basic Commands and Custom Change sets.&lt;br /&gt;
* How to Render Database Data to LiveView (via Context Commands).&lt;br /&gt;
* How to Create a Chat using PubSub.&lt;br /&gt;
* How to Create Event Handlers in LiveView&lt;br /&gt;
* How to Create a Dynamic Route from Scratch.&lt;br /&gt;
* How to Use Elixirs Template language&lt;br /&gt;
* How to Work with Modal&lt;br /&gt;
* How to Use CSS From Scratch (Without bundler)&lt;br /&gt;
* How to use JS hooks&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
______________________&lt;br /&gt;
https://studioindie.co/blog/heex-guide/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
get &amp;quot;/&amp;quot;, PageController, :some-atom    #This is the route. some-atom is the controller name&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  def some-atom(conn, _params) do                 # controller name&lt;br /&gt;
    # The home page is often custom made,&lt;br /&gt;
    # so skip the default app layout.&lt;br /&gt;
    render(conn, :some-atom, layout: false)      # :some-atom is template name&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Controllers page_html.ex contains &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageHTML do&lt;br /&gt;
  use AppWeb, :html&lt;br /&gt;
&lt;br /&gt;
  embed_templates &amp;quot;page_html/*&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''page_html''' is the name of the folder in '''Controllers/page_html'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Controllers/page_html/some-atom.html.heex  (this is the template) &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__________________________________________&lt;br /&gt;
Set all association with preload:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  def list_groups do&lt;br /&gt;
    Repo.all(Group)&lt;br /&gt;
     |&amp;gt; Repo.preload([:testbeds])&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Insert Child into Parent ===&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
App.get_group!(2) # arg is id&lt;br /&gt;
|&amp;gt; Ecto.build_assoc(:testbeds)&lt;br /&gt;
|&amp;gt; Repo.insert()&lt;br /&gt;
&lt;br /&gt;
Or&lt;br /&gt;
&lt;br /&gt;
group = App.get_group!(2) # arg is id&lt;br /&gt;
&lt;br /&gt;
testbeds = Ecto.build_assoc(group, :testbeds)&lt;br /&gt;
&lt;br /&gt;
App.Group.create_group(testbeds)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
group = App.Groups.get_group!(1)&lt;br /&gt;
thing = Ecto.build_assoc(group, :testbeds, name: &amp;quot;DUMB&amp;quot;)&lt;br /&gt;
alias App.{Repo}&lt;br /&gt;
Repo.insert(thing)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
avatar = %Avatar{nick_name: &amp;quot;Elixir&amp;quot;, pic_url: &amp;quot;http://elixir-lang.org/images/logo.png&amp;quot;}&lt;br /&gt;
user = %User{name: &amp;quot;John Doe&amp;quot;, email: &amp;quot;john.doe@example.com&amp;quot;, avatar: avatar}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://www.reddit.com/r/elixir/comments/oh318k/is_there_a_way_to_avoid_ectoassociationnotloaded/h4mmcfi/?utm_source=share&amp;amp;utm_medium=web3x&amp;amp;utm_name=web3xcss&amp;amp;utm_term=1&amp;amp;utm_content=share_button&lt;br /&gt;
&lt;br /&gt;
# Create Group Table&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
mix phx.gen.html Groups Group groups name:string  &lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Set the resources / &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
mix ecto.migrate&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For testbeds create a migration file and add this field:   group_id:references:groups&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
def change do&lt;br /&gt;
    alter table(:testbeds) do    # customize to your code&lt;br /&gt;
      add :group_id, references(:groups)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Update Groups Schema (Don't forget alias / has_many)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule App.Groups.Group do&lt;br /&gt;
	use Ecto.Schema&lt;br /&gt;
	import Ecto.Changeset&lt;br /&gt;
	alias App.Testbeds.Testbed   # Alias!&lt;br /&gt;
&lt;br /&gt;
	schema &amp;quot;posts&amp;quot; do&lt;br /&gt;
		field :body, :string&lt;br /&gt;
		field :title, :string&lt;br /&gt;
		has_many :testbeds, Testbed    # Has many&lt;br /&gt;
&lt;br /&gt;
		timestamps()&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	@doc false&lt;br /&gt;
	def changeset(post, attrs) do&lt;br /&gt;
		post&lt;br /&gt;
		|&amp;gt; cast(attrs, [:title, :body])&lt;br /&gt;
		|&amp;gt; validate_required([:title, :body])&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
TESTBEDS Schema&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule App.Testbeds.Testbed do&lt;br /&gt;
  use Ecto.Schema&lt;br /&gt;
  import Ecto.Changeset&lt;br /&gt;
  alias App.Groups.Group      # Alias&lt;br /&gt;
  schema &amp;quot;testbeds&amp;quot; do&lt;br /&gt;
    field :name, :string&lt;br /&gt;
    belongs_to :group, Group    # Belongs to&lt;br /&gt;
    timestamps()&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  @doc false&lt;br /&gt;
  def changeset(testbed, attrs) do&lt;br /&gt;
    testbed&lt;br /&gt;
    |&amp;gt; cast(attrs, [:name])&lt;br /&gt;
    |&amp;gt; validate_required([:name])&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
_____________________________________&lt;br /&gt;
Side notes.&lt;br /&gt;
&lt;br /&gt;
defmodule App.Repo.Migrations.CreateTestbeds do&lt;br /&gt;
  use Ecto.Migration&lt;br /&gt;
&lt;br /&gt;
  def change do&lt;br /&gt;
    create table(:testbeds) do&lt;br /&gt;
      add :name, :string&lt;br /&gt;
      add :group_id, references(:groups, on_delete: :nothing)&lt;br /&gt;
&lt;br /&gt;
      timestamps()&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    create index(:testbeds, [:group_id])&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
________________________________&lt;br /&gt;
&lt;br /&gt;
mix phx.gen.context Comments Comment comments name:string content:text post_id:references:posts&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
mix phx.gen.html Testbeds Testbed testbeds name:string  group_id:references:groups&lt;br /&gt;
&lt;br /&gt;
https://graffino.com/web-development/first-steps-in-elixir-and-phoenix-create-a-blog-prototype&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://blog.logrocket.com/getting-started-ecto-phoenix/&lt;br /&gt;
&lt;br /&gt;
https://serokell.io/blog/ecto-guide-for-beginners&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
mix phx.gen.html Testbeds Testbed testbeds name:string&lt;br /&gt;
&lt;br /&gt;
mix phx.gen.html Groups Group groups name:string&lt;br /&gt;
&lt;br /&gt;
Create migration for &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
mix ecto.gen.migration add_testbed_group_reference&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Migration:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  def change do&lt;br /&gt;
    alter table(:testbeds) do    # customize to your code&lt;br /&gt;
      add :group_id, references(:groups)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Manually Change:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule App.Group do&lt;br /&gt;
  use Ecto.Schema&lt;br /&gt;
&lt;br /&gt;
  schema &amp;quot;groups&amp;quot; do&lt;br /&gt;
    field :title, :string&lt;br /&gt;
    field :tagline, :string&lt;br /&gt;
    has_many :testbeds, App.Testbed&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
testbeds&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule App.Repo.Migrations.AddTextbedGroups do&lt;br /&gt;
  use Ecto.Migration&lt;br /&gt;
&lt;br /&gt;
  def change do&lt;br /&gt;
    create table(:testbeds) do&lt;br /&gt;
      add :name, :string&lt;br /&gt;
      add :group_id, references(:groups)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
# lib/app/testbeds.ex&lt;br /&gt;
&lt;br /&gt;
defmodule App.Testbed do&lt;br /&gt;
  use Ecto.Schema&lt;br /&gt;
&lt;br /&gt;
  schema &amp;quot;testbedss&amp;quot; do&lt;br /&gt;
    field :name, :string&lt;br /&gt;
    belongs_to :group, App.Group&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_____________________&lt;br /&gt;
&lt;br /&gt;
%App.TestBeds.TestBed{&lt;br /&gt;
  __meta__: #Ecto.Schema.Metadata&amp;lt;:loaded, &amp;quot;testbeds&amp;quot;&amp;gt;,&lt;br /&gt;
  id: 1,&lt;br /&gt;
  developer: &amp;quot;None&amp;quot;,&lt;br /&gt;
  name: &amp;quot;sdfsd&amp;quot;,&lt;br /&gt;
  owner: &amp;quot;sdfsddf&amp;quot;,&lt;br /&gt;
  note: &amp;quot;sdsfsddf&amp;quot;,&lt;br /&gt;
  status: &amp;quot;Available&amp;quot;,&lt;br /&gt;
  url: &amp;quot;sdf&amp;quot;,&lt;br /&gt;
  version: &amp;quot;ddf&amp;quot;,&lt;br /&gt;
  manager: &amp;quot;sf&amp;quot;,&lt;br /&gt;
  inserted_at: ~N[2023-08-21 13:45:39],&lt;br /&gt;
  updated_at: ~N[2023-08-21 13:45:44]&lt;br /&gt;
}&lt;br /&gt;
________________________________________________________________---&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.SendLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  &lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    {:ok, socket}&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  def handle_event(&amp;quot;send&amp;quot;, %{&amp;quot;text&amp;quot; =&amp;gt; text}, socket) do&lt;br /&gt;
&lt;br /&gt;
    AppWeb.Endpoint.broadcast(topic, &amp;quot;message&amp;quot;, text)&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  defp topic do&lt;br /&gt;
    &amp;quot;chat&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def render(assigns)do   &lt;br /&gt;
   ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
  &amp;lt;h1&amp;gt;Send Message&amp;lt;/h1&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;form phx-submit=&amp;quot;send&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;text&amp;quot; /&amp;gt;&lt;br /&gt;
    &amp;lt;button type=&amp;quot;submit&amp;quot;&amp;gt;Send&amp;lt;/button&amp;gt;&lt;br /&gt;
  &amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
______________________________________________________________&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.ReceiveLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  &lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    if connected?(socket) do&lt;br /&gt;
      AppWeb.Endpoint.subscribe(topic)&lt;br /&gt;
    end&lt;br /&gt;
    {:ok, assign(socket, messages: &amp;quot;&amp;quot;)}&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def handle_info(%{event: &amp;quot;message&amp;quot;, payload: message}, socket) do&lt;br /&gt;
    IO.inspect message&lt;br /&gt;
    {:noreply, assign(socket, messages: message)}&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  defp topic do&lt;br /&gt;
    &amp;quot;chat&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns)do   &lt;br /&gt;
   ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
  &amp;lt;h1&amp;gt;ChatLive&amp;lt;/h1&amp;gt;&lt;br /&gt;
  &amp;lt;%= @messages %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
______________________________________________________________&lt;br /&gt;
When you hover over a list of items this hook finds items with the same name and sets the opacity of all others to 0. You see all the items similar to the one you are hovering over.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
TestbedVersionHover: {&lt;br /&gt;
			// https://jsfiddle.net/IrvinDominin/7K2Z3/&lt;br /&gt;
            mounted() {&lt;br /&gt;
&lt;br /&gt;
                let rows = document.getElementsByClassName(&amp;quot;testbed-version&amp;quot;)&lt;br /&gt;
                // this.ele = element&lt;br /&gt;
				// rows = this.ele;&lt;br /&gt;
                &lt;br /&gt;
				for (var i = 0; i &amp;lt; rows.length; i++) {&lt;br /&gt;
					rows[i].onmouseenter = function (event) {&lt;br /&gt;
						for (var j = 0; j &amp;lt; rows.length; j++) {&lt;br /&gt;
							let preversion = this.textContent;&lt;br /&gt;
							let version = preversion.slice(0,5)&lt;br /&gt;
							let compareVersion = rows[j].textContent.slice(0,5)&lt;br /&gt;
							if (compareVersion === version) continue&lt;br /&gt;
							rows[j].className += &amp;quot; other&amp;quot;;&lt;br /&gt;
						}&lt;br /&gt;
					};&lt;br /&gt;
				&lt;br /&gt;
					rows[i].onmouseleave = function (event) {&lt;br /&gt;
						var hovers = document.getElementsByClassName('other');&lt;br /&gt;
						var len = hovers.length;&lt;br /&gt;
						for (var j = 0; j &amp;lt; len; j++) {&lt;br /&gt;
							hovers[0].className = hovers[0].className.replace(/\sother(\s|$)/, '');&lt;br /&gt;
						}&lt;br /&gt;
					};&lt;br /&gt;
				}&lt;br /&gt;
&lt;br /&gt;
                // this.ele.addEventListener(&amp;quot;click&amp;quot;, (e) =&amp;gt; {&lt;br /&gt;
                //     console.log(e.target)&lt;br /&gt;
                    &lt;br /&gt;
                // });&lt;br /&gt;
&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* How to Create Database Seed Data.&lt;br /&gt;
* How to structure code so controller code is in one file and HTML Heex is in another&lt;br /&gt;
* How to Use Generators in a Real World Project&lt;br /&gt;
* How to Work with Database Data via Basic Commands and Custom Change sets.&lt;br /&gt;
* How to Render Database Data to LiveView (via Context Commands).&lt;br /&gt;
* How to Create a Chat using PubSub.&lt;br /&gt;
* How to Create Event Handlers in LiveView&lt;br /&gt;
* How to Create a Dynamic Route from Scratch.&lt;br /&gt;
* How to Use Elixirs Template language&lt;br /&gt;
* How to Work with Modal&lt;br /&gt;
* How to Use CSS From Scratch (Without bundler)&lt;br /&gt;
* How to use JS hooks&lt;br /&gt;
* Dissect Table Component and Update it to Order List in Reverse.&lt;br /&gt;
&lt;br /&gt;
Selenium&lt;br /&gt;
https://www.builder.io/blog/debug-nodejs&lt;br /&gt;
&lt;br /&gt;
https://marketplace.visualstudio.com/items?itemName=ms-vscode.live-server#running-the-extension&lt;br /&gt;
&lt;br /&gt;
This was added recently (see microsoft/vscode#109276).&lt;br /&gt;
    1. Open the palette (Ctrl + Shift + P)&lt;br /&gt;
    2. Select &amp;quot;Simple Browser: Preview&amp;quot;&lt;br /&gt;
    3. Enter web address&lt;br /&gt;
&lt;br /&gt;
_______________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
const {By, Key, Builder} = require(&amp;quot;selenium-webdriver&amp;quot;);&lt;br /&gt;
const assert = require(&amp;quot;assert&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
require(&amp;quot;chromedriver&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
async function test_case(){&lt;br /&gt;
  let driver = await new Builder().forBrowser(&amp;quot;chrome&amp;quot;).build();&lt;br /&gt;
  await driver.get(&amp;quot;sie&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  await driver.findElement(By.name('password')).clear();&lt;br /&gt;
  await driver.findElement(By.name('identification')).clear();&lt;br /&gt;
  await driver.findElement(By.name('identification')).sendKeys(&amp;quot;bill&amp;quot;);&lt;br /&gt;
  await driver.findElement(By.name('password')).sendKeys(&amp;quot;password&amp;quot;, Key.RETURN);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 setTimeout(()=&amp;gt;{&lt;br /&gt;
   driver.findElement(By.className(&amp;quot;req_lan_license&amp;quot;)).click();&lt;br /&gt;
 },5000)&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageLive do &lt;br /&gt;
&lt;br /&gt;
  use AppWeb, :live_view  &lt;br /&gt;
  alias App.Testbeds &lt;br /&gt;
  def mount(_params, _session, socket)do   &lt;br /&gt;
     {:ok, assign(socket, testbeds: Testbeds.list_testbeds())}   &lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
    def button_event(&amp;quot;invoke_editing&amp;quot;) do&lt;br /&gt;
    %JS{}&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;active&amp;quot;, to: &amp;quot;#editing_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#editing_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#preview_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;active&amp;quot;, to: &amp;quot;#preview_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;active&amp;quot;, to: &amp;quot;#preview&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#preview&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#editing&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;active&amp;quot;, to: &amp;quot;#editing&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def button_event(&amp;quot;invoke_preview&amp;quot;) do&lt;br /&gt;
    %JS{}&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;active&amp;quot;, to: &amp;quot;#preview_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#preview_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#editing_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;active&amp;quot;, to: &amp;quot;#editing_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;active&amp;quot;, to: &amp;quot;#editing&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#editing&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#preview&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;active&amp;quot;, to: &amp;quot;#preview&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;send&amp;quot;, params, socket) do&lt;br /&gt;
    hide_modal(&amp;quot;notes-modal-0&amp;quot;)&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do  &lt;br /&gt;
     ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
		&amp;lt;.modal id={&amp;quot;notes-modal-#{testbed.id}&amp;quot;}&amp;gt;&lt;br /&gt;
		    &amp;lt;.button phx-click={button_event(&amp;quot;invoke_editing&amp;quot;)} id=&amp;quot;editing_button&amp;quot; class=&amp;quot;hidden&amp;quot;&amp;gt;&lt;br /&gt;
		      Preview&lt;br /&gt;
		    &amp;lt;/.button&amp;gt;&lt;br /&gt;
		    &amp;lt;.button phx-click={button_event(&amp;quot;invoke_preview&amp;quot;)} id=&amp;quot;preview_button&amp;quot;&amp;gt;&lt;br /&gt;
		      Edit Me&lt;br /&gt;
		    &amp;lt;/.button&amp;gt;&lt;br /&gt;
		    &amp;lt;div id=&amp;quot;editing&amp;quot;&amp;gt; PREVIEWING THE WORK&amp;lt;/div&amp;gt;&lt;br /&gt;
		    &amp;lt;form phx-submit = &amp;quot;send&amp;quot;   id=&amp;quot;preview&amp;quot; class=&amp;quot;hidden&amp;quot;&amp;gt;&lt;br /&gt;
		      &amp;lt;textarea value = {testbed.note}&amp;gt;&amp;lt;/textarea&amp;gt;&lt;br /&gt;
		      &amp;lt;.button type=&amp;quot;submit&amp;quot; phx-click={hide_modal(&amp;quot;notes-modal-#{testbed.id}&amp;quot;)}&amp;gt;SAVE WORK&amp;lt;/.button&amp;gt;&lt;br /&gt;
		    &amp;lt;/form&amp;gt;&lt;br /&gt;
		&amp;lt;/.modal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;%= if testbed.note do %&amp;gt;&lt;br /&gt;
      &amp;lt;div phx-click={show_modal(&amp;quot;notes-modal-#{testbed.id}&amp;quot;)}&amp;gt;READ ME  ...&amp;lt;%= testbed.note %&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
	   &lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
       &lt;br /&gt;
      &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
import {HfInference} from &amp;quot;@huggingface/inference&amp;quot;;&lt;br /&gt;
import dotenv from &amp;quot;dotenv&amp;quot;;&lt;br /&gt;
dotenv.config()&lt;br /&gt;
&lt;br /&gt;
const HF_ACCESS_TOKEN = process.env.HF_ACCESS_TOKEN&lt;br /&gt;
&lt;br /&gt;
const hf = new HfInference(HF_ACCESS_TOKEN);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*______Uncomment for this example______________________&lt;br /&gt;
&lt;br /&gt;
const model = &amp;quot;nlpconnect/vit-gpt2-image-captioning&amp;quot;;&lt;br /&gt;
const imageURL = &amp;quot;https://i.imgur.com/lTvb7Et.png&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
const response = await fetch(imageURL);&lt;br /&gt;
const imageBlob = await response.blob();&lt;br /&gt;
&lt;br /&gt;
const result  = await hf.imageToText({&lt;br /&gt;
	data: imageBlob,&lt;br /&gt;
	model: model,&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
_______________________________________________________*/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*________Another example ___________________*/&lt;br /&gt;
&lt;br /&gt;
const result = await hf.summarization({&lt;br /&gt;
	model: 'facebook/bart-large-cnn',&lt;br /&gt;
	inputs: &amp;quot;The role of a dumb man is to get smarter oogy bookie boo&amp;quot;,&lt;br /&gt;
	parameters:{&lt;br /&gt;
		max_length: 100&lt;br /&gt;
	}&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
console.log(result);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
________________________________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://fly.io/phoenix-files/sdeb-toggling-element/&lt;br /&gt;
https://www.youtube.com/watch?v=vBgZvQapqhs&lt;br /&gt;
&lt;br /&gt;
https://blog.testdouble.com/posts/2022-11-28-how-to-use-javascript-with-phoenix-liveview/&lt;br /&gt;
&lt;br /&gt;
https://hexdocs.pm/phoenix_live_view/0.19.3/Phoenix.Component.html&lt;br /&gt;
_______________________________________&lt;br /&gt;
https://www.smashingmagazine.com/2011/10/quick-look-math-animations-javascript/&lt;br /&gt;
* Depth first traversal&lt;br /&gt;
* Breadth first traversal&lt;br /&gt;
&lt;br /&gt;
https://dev.to/codesphere/10-algorithms-every-developer-should-learn-3lnm&lt;br /&gt;
&lt;br /&gt;
https://www.youtube.com/watch?v=fPz40W9mfCg&lt;br /&gt;
&lt;br /&gt;
__________________________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.GroupLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  alias App.TestBeds&lt;br /&gt;
  alias App.Groups&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    {:ok, assign(socket, testbeds: TestBeds.list_testbeds(), groups: Groups.list_groups())}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;select-group&amp;quot;, params, socket)  do  &lt;br /&gt;
         &lt;br /&gt;
       IO.inspect params&lt;br /&gt;
       {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div class=&amp;quot;grid grid-columns-2 grid-flow-col gap-4&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;column-1&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;%= testbed.name %&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;column-2&amp;quot;&amp;gt;    &lt;br /&gt;
            &amp;lt;form phx-change=&amp;quot;select-group&amp;quot;  &amp;gt;&lt;br /&gt;
               &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;testbed_id&amp;quot; value={testbed.id}/&amp;gt;&lt;br /&gt;
               &amp;lt;select id=&amp;quot;group-selection&amp;quot;  name=&amp;quot;group-id&amp;quot; &amp;gt;&lt;br /&gt;
                &amp;lt;%= for group &amp;lt;- @groups do %&amp;gt;&lt;br /&gt;
                  &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}  &amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
               &amp;lt;/select&amp;gt;&lt;br /&gt;
            &amp;lt;/form&amp;gt;&lt;br /&gt;
         &amp;lt;/div&amp;gt;&lt;br /&gt;
       &amp;lt;% end %&amp;gt;&lt;br /&gt;
   &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
____________________________&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.GroupLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  alias App.TestBeds&lt;br /&gt;
  alias App.Groups&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
&lt;br /&gt;
    {:ok, assign(socket, testbeds: TestBeds.list_testbeds(), groups: Groups.list_groups(), messages: [])}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;select-group&amp;quot;, params, socket)  do  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
      group = App.Groups.get_group!(params[&amp;quot;group-id&amp;quot;])&lt;br /&gt;
       # IO.inspect group&lt;br /&gt;
       testbed = App.TestBeds.get_test_bed!(params[&amp;quot;testbed_id&amp;quot;])&lt;br /&gt;
     &lt;br /&gt;
       App.TestBeds.update_test_bed(testbed, %{group_id: group.id})&lt;br /&gt;
         &lt;br /&gt;
    &lt;br /&gt;
       {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def updated_groups(testbed_id)  do  &lt;br /&gt;
       groups = App.Groups.list_groups&lt;br /&gt;
       tail = Enum.filter(groups, fn(item)-&amp;gt; item.id !== testbed_id end)&lt;br /&gt;
       head = Enum.filter(groups, fn(item)-&amp;gt; item.id == testbed_id end)&lt;br /&gt;
              |&amp;gt;Enum.at(0)&lt;br /&gt;
     [head | tail]&lt;br /&gt;
         &lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
 # def handle_event(&amp;quot;groups&amp;quot;, params, socket)do  &lt;br /&gt;
 #       selected_testbed = %{name: &amp;quot;my testbed name&amp;quot;, id: 3}&lt;br /&gt;
 #       groups = App.Groups.list_groups&lt;br /&gt;
 #       tail = Enum.filter(groups, fn(item)-&amp;gt; item.id !== selected_testbed.id end)&lt;br /&gt;
 #       head = Enum.filter(groups, fn(item)-&amp;gt; item.id == selected_testbed.id end)&lt;br /&gt;
 #              |&amp;gt;Enum.at(0)&lt;br /&gt;
         &lt;br /&gt;
 &lt;br /&gt;
 #       # result = Enum.filter([1, 2, 3], fn x -&amp;gt; x.id !== 1 end)&lt;br /&gt;
 #      IO.inspect [head | tail]&lt;br /&gt;
         &lt;br /&gt;
 #      #&lt;br /&gt;
 #      {:noreply, socket, assigns.message:}&lt;br /&gt;
 #  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    &lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
       &amp;lt;%!-- &amp;lt;div phx-click = &amp;quot;groups&amp;quot;&amp;gt;CLICK ME&amp;lt;/div&amp;gt; --%&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;grid grid-cols-4 gap-4 p-8 rounded shadow bg-white&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;h2&amp;gt; Name&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;%= testbed.name %&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;h2&amp;gt; Group&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;form phx-change=&amp;quot;select-group&amp;quot; name=&amp;quot;testbed_id&amp;quot;  &amp;gt;&lt;br /&gt;
               &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;testbed_id&amp;quot; value={testbed.id}/&amp;gt;&lt;br /&gt;
               &amp;lt;select id=&amp;quot;group-selection&amp;quot;  name=&amp;quot;group-id&amp;quot; class=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
                &amp;lt;%= for group &amp;lt;- updated_groups(testbed.id) do %&amp;gt;&lt;br /&gt;
                  &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}  &amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
                  &amp;lt;!-- Write code to reorder with testbed.group_id matching group_id --&amp;gt;&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
               &amp;lt;/select&amp;gt;&lt;br /&gt;
            &amp;lt;/form&amp;gt;&lt;br /&gt;
          &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
       &amp;lt;% end %&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_____________________________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
   use AppWeb, :live_view  &lt;br /&gt;
     alias App.Testbeds&lt;br /&gt;
  alias App.Groups&lt;br /&gt;
   def mount(_params, _session, socket)  do&lt;br /&gt;
	     {:ok, assign(socket, testbeds: Testbeds.list_testbeds(), groups: Groups.list_groups())}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
   def handle_event(&amp;quot;select-group&amp;quot;, params, socket)  do  &lt;br /&gt;
       group = App.Groups.get_group!(params[&amp;quot;group-id&amp;quot;])&lt;br /&gt;
       testbed = App.Testbeds.get_testbed!(params[&amp;quot;testbed_id&amp;quot;])&lt;br /&gt;
       result = App.Testbeds.update_testbed(testbed, %{group_id: group.id})&lt;br /&gt;
       IO.inspect result&lt;br /&gt;
      &lt;br /&gt;
       {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
    def updated_groups(testbed_id)  do  &lt;br /&gt;
       testbed = App.Testbeds.get_testbed!(testbed_id)&lt;br /&gt;
       groups = App.Groups.list_groups&lt;br /&gt;
       tail = Enum.filter(groups, fn(item)-&amp;gt; item.id !== testbed.group_id end)&lt;br /&gt;
       head = Enum.filter(groups, fn(item)-&amp;gt; item.id == testbed.group_id end)&lt;br /&gt;
              |&amp;gt;Enum.at(0)&lt;br /&gt;
 &lt;br /&gt;
       [head | tail]&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    &lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;grid grid-cols-4 gap-4 p-8 rounded shadow bg-white&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;h2&amp;gt; Name&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;%= testbed.name %&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;h2&amp;gt; Group&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;form phx-change=&amp;quot;select-group&amp;quot; name=&amp;quot;testbed_id&amp;quot;  &amp;gt;&lt;br /&gt;
               &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;testbed_id&amp;quot; value={testbed.id}/&amp;gt;&lt;br /&gt;
               &amp;lt;select id=&amp;quot;group-selection&amp;quot;  name=&amp;quot;group-id&amp;quot; class=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
                &amp;lt;%= for group &amp;lt;- updated_groups(testbed.id) do %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
                  &amp;lt;%!-- &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}&amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt; --%&amp;gt;&lt;br /&gt;
                  &amp;lt;!-- Write code to reorder with testbed.group_id matching group_id --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
                  &amp;lt;%= if group !== nil do %&amp;gt;&lt;br /&gt;
                      &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}&amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
       &lt;br /&gt;
                  &amp;lt;% end %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
               &amp;lt;/select&amp;gt;&lt;br /&gt;
            &amp;lt;/form&amp;gt;&lt;br /&gt;
          &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
       &amp;lt;% end %&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  has_many :testbeds, TestBed, on_delete: :restrict   # Has many&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://elixirforum.com/t/ecto-has-many-on-delete-protect/49550&lt;br /&gt;
&lt;br /&gt;
https://hexdocs.pm/ecto/Ecto.Changeset.html#unique_constraint/3&lt;br /&gt;
&lt;br /&gt;
____________________________________________________________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== How to Create a Mix Project and Use It in Another Mix Project ==&lt;br /&gt;
&lt;br /&gt;
To create and use a **Mix project** inside another **Mix project** in Elixir, follow the steps below:&lt;br /&gt;
&lt;br /&gt;
=== 1. Create a New Mix Project ===&lt;br /&gt;
&lt;br /&gt;
First, you need to create a new Mix project. Let's call this project `library_project`. Run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mix new library_project --module LibraryProject&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will create a new Elixir Mix project named `library_project`. The `--module` flag specifies the name of the module that will be created (in this case `LibraryProject`).&lt;br /&gt;
&lt;br /&gt;
The directory structure of `library_project` will look like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
library_project/&lt;br /&gt;
  |_ lib/&lt;br /&gt;
      |_ library_project.ex&lt;br /&gt;
  |_ mix.exs&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can then add some basic functionality inside the `library_project/lib/library_project.ex` file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule LibraryProject do&lt;br /&gt;
  def hello do&lt;br /&gt;
    IO.puts &amp;quot;Hello from LibraryProject!&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now, `library_project` is ready to be used by another Mix project.&lt;br /&gt;
&lt;br /&gt;
=== 2. Create a Second Mix Project ===&lt;br /&gt;
&lt;br /&gt;
Next, create the second Mix project where you want to use `library_project`. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mix new app_project --module AppProject&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will create another Elixir project called `app_project`.&lt;br /&gt;
&lt;br /&gt;
The directory structure for this project will look like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
app_project/&lt;br /&gt;
  |_ lib/&lt;br /&gt;
      |_ app_project.ex&lt;br /&gt;
  |_ mix.exs&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 3. Add `library_project` as a Dependency in `app_project` ===&lt;br /&gt;
&lt;br /&gt;
Now, you want to make `library_project` available in `app_project`. There are two main ways to do this:&lt;br /&gt;
&lt;br /&gt;
==== Option 1: Local Dependency (via `path`) ====&lt;br /&gt;
&lt;br /&gt;
If `library_project` is a local project (i.e., it's stored in a different directory), you can add it to the `mix.exs` of `app_project` as a local dependency by specifying the path to `library_project`.&lt;br /&gt;
&lt;br /&gt;
Edit the `mix.exs` of `app_project`:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule AppProject.MixProject do&lt;br /&gt;
  use Mix.Project&lt;br /&gt;
&lt;br /&gt;
  def project do&lt;br /&gt;
    [&lt;br /&gt;
      app: :app_project,&lt;br /&gt;
      version: &amp;quot;0.1.0&amp;quot;,&lt;br /&gt;
      elixir: &amp;quot;~&amp;gt; 1.14&amp;quot;,&lt;br /&gt;
      start_permanent: Mix.env() == :prod,&lt;br /&gt;
      deps: deps()&lt;br /&gt;
    ]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  defp deps do&lt;br /&gt;
    [&lt;br /&gt;
      {:library_project, path: &amp;quot;../library_project&amp;quot;}  # Add the local dependency&lt;br /&gt;
    ]&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here, `{:library_project, path: &amp;quot;../library_project&amp;quot;}` tells Mix to use the local `library_project` located in the `../library_project` directory (relative to `app_project`).&lt;br /&gt;
&lt;br /&gt;
After updating the `mix.exs`, run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd app_project&lt;br /&gt;
mix deps.get&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will fetch the dependency and compile `library_project`.&lt;br /&gt;
&lt;br /&gt;
==== Option 2: Publish and Fetch as a Hex Package ====&lt;br /&gt;
&lt;br /&gt;
If you want to use `library_project` as a package in another project (for example, by publishing it to **Hex.pm**, Elixir’s package manager), you need to publish it to Hex and then add it as a dependency.&lt;br /&gt;
&lt;br /&gt;
1. Publish `library_project` to Hex (if it's public or for your private use).&lt;br /&gt;
2. Add `library_project` to your `app_project`’s `mix.exs` dependencies:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defp deps do&lt;br /&gt;
  [&lt;br /&gt;
    {:library_project, &amp;quot;~&amp;gt; 0.1.0&amp;quot;}  # Specify the published version from Hex&lt;br /&gt;
  ]&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Run `mix deps.get` to fetch the package from Hex.&lt;br /&gt;
&lt;br /&gt;
=== 4. Use `library_project` in `app_project` ===&lt;br /&gt;
&lt;br /&gt;
Now, you can use the functionality from `library_project` inside your `app_project`. For example, in `app_project/lib/app_project.ex`, you can call the function from `library_project`:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule AppProject do&lt;br /&gt;
  def start do&lt;br /&gt;
    IO.puts &amp;quot;Starting app_project!&amp;quot;&lt;br /&gt;
    LibraryProject.hello()  # Call the function from the library_project&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 5. Run the App ===&lt;br /&gt;
&lt;br /&gt;
Finally, you can run your `app_project`:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd app_project&lt;br /&gt;
mix run -e &amp;quot;AppProject.start()&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will print:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Starting app_project!&lt;br /&gt;
Hello from LibraryProject!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Recap of the Process ==&lt;br /&gt;
1. **Create the `library_project`**: Use `mix new` to generate a library project.&lt;br /&gt;
2. **Create the `app_project`**: Create the second project where you will use the library.&lt;br /&gt;
3. **Add the `library_project` as a dependency**:&lt;br /&gt;
   - Use the `path` option to point to the local project or publish it to Hex for public access.&lt;br /&gt;
4. **Use the `library_project` in the `app_project`**: Call functions or use modules from the library inside the second project.&lt;br /&gt;
5. **Run the app**: Use `mix run` to execute the project.&lt;br /&gt;
&lt;br /&gt;
This way, you can reuse code from one Mix project in another by adding it as a dependency.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==z==&lt;br /&gt;
Overloaded functions are extremely common in Elixir applications. They are&lt;br /&gt;
regularly used for recursive functions and for changing behavior based on&lt;br /&gt;
configuration.&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>http://elixirblocks.com/index.php?title=Understanding_Forms_and_Changesets&amp;diff=1895</id>
		<title>Understanding Forms and Changesets</title>
		<link rel="alternate" type="text/html" href="http://elixirblocks.com/index.php?title=Understanding_Forms_and_Changesets&amp;diff=1895"/>
		<updated>2025-03-23T21:42:06Z</updated>

		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{In_progress}}&lt;br /&gt;
&lt;br /&gt;
This tutorial assumes you have a basic understanding of Elixir and that you have explored Phoenix. It also assumes that you understand HTML forms. &lt;br /&gt;
&lt;br /&gt;
The methodology of this tutorial includes converting a conventional HTML form into a Phoenix template that uses Elixir to communicate with back end code. You also learn how changesets integrate with controllers. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Getting Started=&lt;br /&gt;
&lt;br /&gt;
To begin, create a new empty Phoenix app named app. If you do not know how to do that follow this tutorial:&lt;br /&gt;
&lt;br /&gt;
[[How to Create an Empty Phoenix Application|How to Create an Empty Phoenix Application]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Creating an HTML Form and Post Request==&lt;br /&gt;
&lt;br /&gt;
In the [[router]] create these two routes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  scope &amp;quot;/&amp;quot;, AppWeb do&lt;br /&gt;
    pipe_through :browser&lt;br /&gt;
&lt;br /&gt;
    get &amp;quot;/&amp;quot;, PageController, :index       # First route&lt;br /&gt;
    post &amp;quot;/create&amp;quot;, PageController, :new  # Second route&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Place the code below in a file named  '''page_controller.ex'''. Place the file in the controller directory.&lt;br /&gt;
&lt;br /&gt;
'''app/lib/app_web/controllers/page_controller.ex'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.PageController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  def index(conn, params) do&lt;br /&gt;
    IO.inspect params&lt;br /&gt;
    csrf_token = Plug.CSRFProtection.get_csrf_token()&lt;br /&gt;
    render(conn, :index, data: &amp;quot;Hello World&amp;quot;,form: %{},csrf_token: csrf_token)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def new(conn, params) do&lt;br /&gt;
      IO.inspect params&lt;br /&gt;
      redirect(conn, to: &amp;quot;/&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In the controllers directory create a file named '''page_html.ex'''&lt;br /&gt;
&lt;br /&gt;
In this file, copy this code.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageHTML do&lt;br /&gt;
  use AppWeb, :html&lt;br /&gt;
&lt;br /&gt;
  embed_templates &amp;quot;page_html/*&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In the controllers directory create another directory named '''page_html''' (technically you can place this directory outside the controllers and it will still work).&lt;br /&gt;
&lt;br /&gt;
'''app/lib/app_web/controllers/page_html'''&lt;br /&gt;
&lt;br /&gt;
This directory will contain heex templates for the PageController.&lt;br /&gt;
&lt;br /&gt;
In the page_html directory place a file named '''index.html.heex'''.&lt;br /&gt;
&lt;br /&gt;
Inside the file copy the following code.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;%=@data%&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;form method=&amp;quot;POST&amp;quot; action=&amp;quot;/create&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;_csrf_token&amp;quot; value={@csrf_token} /&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;example&amp;quot; /&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;submit&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;/form&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Run the server:   mix phx.server&lt;br /&gt;
&lt;br /&gt;
You should see a form field and a submit button with the text &amp;quot;Hello World&amp;quot; above them. Type into the form and submit it, the terminal will display your input. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you replace the form with the built in form helper, you can remove the csrf code. CSRF protection comes built in with the form helper. Delete or comment out the code in index.html.heex and replace it with the code below.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;.form :let={f} action={~p&amp;quot;/create&amp;quot;}&amp;gt;&lt;br /&gt;
    &amp;lt;.input field={f[:x]} name=&amp;quot;submitted-data&amp;quot; /&amp;gt;&lt;br /&gt;
  &amp;lt;/.form&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Delete or comment out the code in page_controller.ex and replace it with the code below.&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  def index(conn, params) do&lt;br /&gt;
    IO.inspect params&lt;br /&gt;
    render(conn, :index, data: &amp;quot;Hello World&amp;quot;,form: %{})&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def new(conn, params) do&lt;br /&gt;
      IO.inspect params&lt;br /&gt;
      redirect(conn, to: &amp;quot;/&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When you run the server and visit the landing page, you should see the page render without error.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Form Changesets===&lt;br /&gt;
Without Changesets we have these two problems:&lt;br /&gt;
&lt;br /&gt;
* We lose what we typed.&lt;br /&gt;
* The app doesn’t tell us what our errors were.&lt;br /&gt;
&lt;br /&gt;
Changesets solve both of these problems.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Schema and Live View Form==&lt;br /&gt;
&lt;br /&gt;
===Schema===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule App.Todo do&lt;br /&gt;
  use Ecto.Schema&lt;br /&gt;
  import Ecto.Changeset&lt;br /&gt;
&lt;br /&gt;
  schema &amp;quot;todos&amp;quot; do&lt;br /&gt;
    field :description, :string&lt;br /&gt;
    field :title, :string&lt;br /&gt;
&lt;br /&gt;
    timestamps(type: :utc_datetime)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  @doc false&lt;br /&gt;
  def changeset(todo, attrs) do&lt;br /&gt;
    todo&lt;br /&gt;
    |&amp;gt; cast(attrs, [:title, :description])&lt;br /&gt;
    |&amp;gt; validate_required([:title, :description])&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Live View Form ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  alias App.Todo&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    changeset = Todo.changeset(%Todo{}, %{})&lt;br /&gt;
    &lt;br /&gt;
    {:ok,&lt;br /&gt;
     socket&lt;br /&gt;
     |&amp;gt; assign(:changeset, changeset)&lt;br /&gt;
     |&amp;gt; assign(:todo, %Todo{})&lt;br /&gt;
     |&amp;gt; assign(:saved, false)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;save&amp;quot;, %{&amp;quot;todo&amp;quot; =&amp;gt; todo_params}, socket) do&lt;br /&gt;
   case save_todo(todo_params) do&lt;br /&gt;
     {:ok, _todo} -&amp;gt;&lt;br /&gt;
       {:noreply,&lt;br /&gt;
        socket&lt;br /&gt;
        |&amp;gt; assign(:changeset, Todo.changeset(%Todo{}, %{}))&lt;br /&gt;
        |&amp;gt; assign(:saved, true)}&lt;br /&gt;
&lt;br /&gt;
     {:error, %Ecto.Changeset{} = changeset} -&amp;gt;&lt;br /&gt;
       {:noreply, assign(socket, changeset: changeset, saved: false)}&lt;br /&gt;
   end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 defp save_todo(todo_params) do&lt;br /&gt;
   %Todo{}&lt;br /&gt;
   |&amp;gt; Todo.changeset(todo_params)&lt;br /&gt;
   |&amp;gt; App.Repo.insert()&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    &amp;lt;.form :let={f} for={@changeset} phx-submit=&amp;quot;save&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;.input field={f[:title]} type=&amp;quot;text&amp;quot; label=&amp;quot;Title&amp;quot; /&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;.input field={f[:description]} type=&amp;quot;textarea&amp;quot; label=&amp;quot;Description&amp;quot; /&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;.button&amp;gt;Save&amp;lt;/.button&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;/.form&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;%= if @saved do %&amp;gt;&lt;br /&gt;
      &amp;lt;div class=&amp;quot;alert alert-info&amp;quot;&amp;gt;&lt;br /&gt;
        Todo saved successfully!&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://adopt-liveview.lubien.dev/guides/simple-forms-with-ecto/en&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===A Working Form Without Changesets ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.SandLive do &lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
&lt;br /&gt;
  alias App.Todos&lt;br /&gt;
  alias App.Todos.Todo&lt;br /&gt;
&lt;br /&gt;
  def mount(params,session,socket) do  &lt;br /&gt;
    &lt;br /&gt;
    {:ok, assign(socket, data: &amp;quot;some data&amp;quot;)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    &lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;  &lt;br /&gt;
        &amp;lt;div&amp;gt;&lt;br /&gt;
            &amp;lt;.form  :let={f}  phx-submit=&amp;quot;save&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;.input field={f[:name]} type=&amp;quot;text&amp;quot; label=&amp;quot;Name&amp;quot; value=&amp;quot;&amp;quot; /&amp;gt;&lt;br /&gt;
                &amp;lt;.button&amp;gt;SAVE &amp;lt;/.button&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
            &amp;lt;/.form&amp;gt;&lt;br /&gt;
&lt;br /&gt;
          {@data}&lt;br /&gt;
&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
      &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;save&amp;quot;,params, socket) do &lt;br /&gt;
      IO.inspect params&lt;br /&gt;
&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Same Example Without Changeset and With Flash Message ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.SandLive do &lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
&lt;br /&gt;
  alias App.Todos&lt;br /&gt;
  alias App.Todos.Todo&lt;br /&gt;
&lt;br /&gt;
  def mount(params,session,socket) do  &lt;br /&gt;
    {:ok, assign(socket, data: &amp;quot;some data&amp;quot;)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    &lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;  &lt;br /&gt;
        &amp;lt;div&amp;gt;&lt;br /&gt;
            &amp;lt;.form  :let={f}  phx-submit=&amp;quot;save&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;.input field={f[:name]} type=&amp;quot;text&amp;quot; label=&amp;quot;Name&amp;quot; value=&amp;quot;&amp;quot; /&amp;gt;&lt;br /&gt;
                &amp;lt;.button&amp;gt;SAVE &amp;lt;/.button&amp;gt;&lt;br /&gt;
            &amp;lt;/.form&amp;gt;&lt;br /&gt;
          {@data}&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
      &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;save&amp;quot;, %{&amp;quot;name&amp;quot; =&amp;gt; name} = params, socket) do &lt;br /&gt;
    IO.inspect params&lt;br /&gt;
    &lt;br /&gt;
    # Create todo without using a changeset directly&lt;br /&gt;
    result = Todos.create_todo(%{&amp;quot;name&amp;quot; =&amp;gt; name})&lt;br /&gt;
    &lt;br /&gt;
    case result do&lt;br /&gt;
      {:ok, _todo} -&amp;gt;&lt;br /&gt;
        {:noreply, socket &lt;br /&gt;
        |&amp;gt; put_flash(:info, &amp;quot;User created successfully.&amp;quot;) &lt;br /&gt;
        |&amp;gt; redirect(to: &amp;quot;/&amp;quot;)}&lt;br /&gt;
      {:error, _reason} -&amp;gt;&lt;br /&gt;
        {:noreply, socket |&amp;gt; put_flash(:error, &amp;quot;Failed to create user.&amp;quot;)}&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===The Same Example with a Changeset ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
    use AppWeb, :live_view&lt;br /&gt;
  &lt;br /&gt;
    alias App.Todos&lt;br /&gt;
    alias App.Todos.Todo&lt;br /&gt;
  &lt;br /&gt;
    def mount(_params, _session, socket) do&lt;br /&gt;
      changeset = Todos.change_todo(%Todo{})&lt;br /&gt;
      {:ok, assign(socket, changeset: changeset)}&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    def render(assigns) do&lt;br /&gt;
      ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
      &amp;lt;h1&amp;gt;Create User&amp;lt;/h1&amp;gt;&lt;br /&gt;
      &amp;lt;.form :let={f} for={@changeset} phx-submit=&amp;quot;save&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;.input field={f[:name]} type=&amp;quot;text&amp;quot; label=&amp;quot;Name&amp;quot; /&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
      &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;.button&amp;gt;Save&amp;lt;/.button&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;/.form&amp;gt;&lt;br /&gt;
      &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    def handle_event(&amp;quot;save&amp;quot;, %{&amp;quot;todo&amp;quot; =&amp;gt; todo_params}, socket) do&lt;br /&gt;
&lt;br /&gt;
      result =  Todos.create_todo(todo_params)&lt;br /&gt;
      IO.inspect result&lt;br /&gt;
&lt;br /&gt;
      case Todos.create_todo(todo_params) do&lt;br /&gt;
        {:ok, _todo} -&amp;gt;&lt;br /&gt;
          {:noreply, socket &lt;br /&gt;
          |&amp;gt; put_flash(:info, &amp;quot;User created successfully.&amp;quot;) &lt;br /&gt;
          |&amp;gt; redirect(to: &amp;quot;/&amp;quot;)}&lt;br /&gt;
&lt;br /&gt;
        {:error, %Ecto.Changeset{} = changeset} -&amp;gt;&lt;br /&gt;
          {:noreply, assign(socket, changeset: changeset)}&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Troubleshooting ChangeSets Example ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.SandLive do&lt;br /&gt;
    use AppWeb, :live_view&lt;br /&gt;
  &lt;br /&gt;
    alias App.Todos&lt;br /&gt;
    alias App.Todos.Todo&lt;br /&gt;
  &lt;br /&gt;
    def mount(_params, _session, socket) do&lt;br /&gt;
      # Create an empty changeset for the form&lt;br /&gt;
      changeset = Todos.change_todo(%Todo{})&lt;br /&gt;
      # Initialize debug_info to an empty map&lt;br /&gt;
      {:ok, assign(socket, data: &amp;quot;some data&amp;quot;, changeset: changeset, debug_info: %{})}&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    def render(assigns) do&lt;br /&gt;
      ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
      &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;.form :let={f} for={@changeset} phx-submit=&amp;quot;save&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;.input field={f[:name]} type=&amp;quot;text&amp;quot; label=&amp;quot;Name&amp;quot; /&amp;gt;&lt;br /&gt;
          &amp;lt;.button&amp;gt;SAVE&amp;lt;/.button&amp;gt;&lt;br /&gt;
        &amp;lt;/.form&amp;gt;&lt;br /&gt;
        &amp;lt;p&amp;gt;{@data}&amp;lt;/p&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
        &amp;lt;%= if map_size(@debug_info) &amp;gt; 0 do %&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;mt-4&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;h3 class=&amp;quot;text-lg font-bold&amp;quot;&amp;gt;Debug Info:&amp;lt;/h3&amp;gt;&lt;br /&gt;
            &amp;lt;pre class=&amp;quot;bg-gray-100 p-2 text-sm overflow-auto&amp;quot;&amp;gt;&amp;lt;%= inspect(@debug_info, pretty: true) %&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
          &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;% end %&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
      &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    def handle_event(&amp;quot;save&amp;quot;, %{&amp;quot;todo&amp;quot; =&amp;gt; todo_params} = params, socket) do&lt;br /&gt;
      # Log the raw params first&lt;br /&gt;
      IO.inspect(params, label: &amp;quot;Raw form parameters&amp;quot;)&lt;br /&gt;
      &lt;br /&gt;
      # Create a changeset without saving (for inspection)&lt;br /&gt;
      inspection_changeset = Todo.changeset(%Todo{}, todo_params)&lt;br /&gt;
      IO.inspect(inspection_changeset, label: &amp;quot;Changeset before save&amp;quot;)&lt;br /&gt;
      &lt;br /&gt;
      # Note the cast fields&lt;br /&gt;
      IO.inspect(inspection_changeset.changes, label: &amp;quot;Fields that will change&amp;quot;)&lt;br /&gt;
      &lt;br /&gt;
      # Note any errors that would occur&lt;br /&gt;
      IO.inspect(inspection_changeset.errors, label: &amp;quot;Validation errors&amp;quot;)&lt;br /&gt;
      &lt;br /&gt;
      # Now proceed with the actual save&lt;br /&gt;
      result = Todos.create_todo(todo_params)&lt;br /&gt;
      &lt;br /&gt;
      case result do&lt;br /&gt;
        {:ok, todo} -&amp;gt;&lt;br /&gt;
          # Log the created record&lt;br /&gt;
          IO.inspect(todo, label: &amp;quot;Created todo&amp;quot;)&lt;br /&gt;
          &lt;br /&gt;
          {:noreply,&lt;br /&gt;
           socket&lt;br /&gt;
           |&amp;gt; assign(debug_info: %{&lt;br /&gt;
              raw_params: params,&lt;br /&gt;
              changeset: inspection_changeset,&lt;br /&gt;
              changes: inspection_changeset.changes,&lt;br /&gt;
              errors: inspection_changeset.errors,&lt;br /&gt;
              created_record: todo&lt;br /&gt;
           })&lt;br /&gt;
           |&amp;gt; put_flash(:info, &amp;quot;User created successfully.&amp;quot;)&lt;br /&gt;
           |&amp;gt; redirect(to: &amp;quot;/sandbox&amp;quot;)}&lt;br /&gt;
  &lt;br /&gt;
        {:error, changeset} -&amp;gt;&lt;br /&gt;
          # Log the error changeset&lt;br /&gt;
          IO.inspect(changeset, label: &amp;quot;Error changeset&amp;quot;)&lt;br /&gt;
          &lt;br /&gt;
          {:noreply, &lt;br /&gt;
           socket &lt;br /&gt;
           |&amp;gt; assign(changeset: changeset, debug_info: %{&lt;br /&gt;
              raw_params: params,&lt;br /&gt;
              error_changeset: changeset,&lt;br /&gt;
              errors: changeset.errors&lt;br /&gt;
           })&lt;br /&gt;
           |&amp;gt; put_flash(:error, &amp;quot;Failed to create user.&amp;quot;)}&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Changeset with Modern to_form (follow this exmple)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.SandLive do&lt;br /&gt;
    use AppWeb, :live_view&lt;br /&gt;
  &lt;br /&gt;
    alias App.Todos&lt;br /&gt;
    alias App.Todos.Todo&lt;br /&gt;
  &lt;br /&gt;
    def mount(_params, _session, socket) do&lt;br /&gt;
      changeset = Todos.change_todo(%Todo{})&lt;br /&gt;
      {:ok, assign(socket, form: to_form(changeset), data: &amp;quot;some data&amp;quot;)}&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    def render(assigns) do&lt;br /&gt;
      ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
      &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;.form for={@form} phx-change=&amp;quot;validate&amp;quot; phx-submit=&amp;quot;save&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;.input field={@form[:name]} type=&amp;quot;text&amp;quot; label=&amp;quot;Name&amp;quot; /&amp;gt;&lt;br /&gt;
          &amp;lt;.button&amp;gt;SAVE&amp;lt;/.button&amp;gt;&lt;br /&gt;
        &amp;lt;/.form&amp;gt;&lt;br /&gt;
        {@data}&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
      &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    &lt;br /&gt;
    def handle_event(&amp;quot;validate&amp;quot;, %{&amp;quot;todo&amp;quot; =&amp;gt; todo_params}, socket) do&lt;br /&gt;
      changeset =&lt;br /&gt;
        %Todo{}&lt;br /&gt;
        |&amp;gt; Todos.change_todo(todo_params)&lt;br /&gt;
        |&amp;gt; Map.put(:action, :validate)&lt;br /&gt;
        &lt;br /&gt;
      {:noreply, assign(socket, form: to_form(changeset))}&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    def handle_event(&amp;quot;save&amp;quot;, %{&amp;quot;todo&amp;quot; =&amp;gt; todo_params}, socket) do&lt;br /&gt;
      case Todos.create_todo(todo_params) do&lt;br /&gt;
        {:ok, _todo} -&amp;gt;&lt;br /&gt;
          {:noreply,&lt;br /&gt;
           socket&lt;br /&gt;
           |&amp;gt; put_flash(:info, &amp;quot;Todo created successfully.&amp;quot;)&lt;br /&gt;
           |&amp;gt; redirect(to: &amp;quot;/&amp;quot;)}&lt;br /&gt;
  &lt;br /&gt;
        {:error, %Ecto.Changeset{} = changeset} -&amp;gt;&lt;br /&gt;
          {:noreply, assign(socket, form: to_form(changeset))}&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
______________________________________________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Phoenix LiveView Forms &amp;amp; Changeset Tutorial =&lt;br /&gt;
&lt;br /&gt;
Here's a concise tutorial to help you learn and recall the syntax for Phoenix LiveView forms with Ecto changesets.&lt;br /&gt;
&lt;br /&gt;
== The Changeset Flow ==&lt;br /&gt;
&lt;br /&gt;
Think of the changeset as the &amp;quot;form manager&amp;quot; that follows this pattern:&lt;br /&gt;
&lt;br /&gt;
# '''Initialize''' - Create an empty changeset for the form&lt;br /&gt;
# '''Validate''' - Update changeset when user types (phx-change)&lt;br /&gt;
# '''Submit''' - Process final changeset when user submits (phx-submit)&lt;br /&gt;
&lt;br /&gt;
== Key Components ==&lt;br /&gt;
&lt;br /&gt;
=== 1. Initial Setup in Mount ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;elixir&amp;quot;&amp;gt;&lt;br /&gt;
def mount(_params, _session, socket) do&lt;br /&gt;
  changeset = Todos.change_todo(%Todo{})&lt;br /&gt;
  {:ok, assign(socket, form: to_form(changeset), data: &amp;quot;some data&amp;quot;)}&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Memory Trick''': &amp;quot;Mount needs a blank changeset to start the form&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== 2. Rendering the Form ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;elixir&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;.form for={@form} phx-change=&amp;quot;validate&amp;quot; phx-submit=&amp;quot;save&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;.input field={@form[:name]} type=&amp;quot;text&amp;quot; label=&amp;quot;Name&amp;quot; /&amp;gt;&lt;br /&gt;
  &amp;lt;.button&amp;gt;SAVE&amp;lt;/.button&amp;gt;&lt;br /&gt;
&amp;lt;/.form&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Memory Trick''': &amp;quot;phx-change validates as you type, phx-submit saves when done&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== 3. Validation Handler ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;elixir&amp;quot;&amp;gt;&lt;br /&gt;
def handle_event(&amp;quot;validate&amp;quot;, %{&amp;quot;todo&amp;quot; =&amp;gt; todo_params}, socket) do&lt;br /&gt;
  changeset =&lt;br /&gt;
    %Todo{}&lt;br /&gt;
    |&amp;gt; Todos.change_todo(todo_params)&lt;br /&gt;
    |&amp;gt; Map.put(:action, :validate)&lt;br /&gt;
    &lt;br /&gt;
  {:noreply, assign(socket, form: to_form(changeset))}&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Memory Tricks''': &lt;br /&gt;
* &amp;quot;Validate always starts with an empty struct (%Todo{})&amp;quot;&lt;br /&gt;
* &amp;quot;Map.put(:action, :validate) shows errors but doesn't save&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== 4. Save Handler ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;elixir&amp;quot;&amp;gt;&lt;br /&gt;
def handle_event(&amp;quot;save&amp;quot;, %{&amp;quot;todo&amp;quot; =&amp;gt; todo_params}, socket) do&lt;br /&gt;
  case Todos.create_todo(todo_params) do&lt;br /&gt;
    {:ok, _todo} -&amp;gt;&lt;br /&gt;
      {:noreply,&lt;br /&gt;
       socket&lt;br /&gt;
       |&amp;gt; put_flash(:info, &amp;quot;Todo created successfully.&amp;quot;)&lt;br /&gt;
       |&amp;gt; redirect(to: &amp;quot;/&amp;quot;)}&lt;br /&gt;
&lt;br /&gt;
    {:error, %Ecto.Changeset{} = changeset} -&amp;gt;&lt;br /&gt;
      {:noreply, assign(socket, form: to_form(changeset))}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Memory Trick''': &amp;quot;Save has two paths: success (redirect) or error (show form again)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Changeset Flow Mnemonic: &amp;quot;CIVC&amp;quot; ==&lt;br /&gt;
&lt;br /&gt;
# '''C'''reate changeset in mount&lt;br /&gt;
# '''I'''nput through the form&lt;br /&gt;
# '''V'''alidate with phx-change&lt;br /&gt;
# '''C'''omplete with phx-submit&lt;br /&gt;
&lt;br /&gt;
== Additional Tips ==&lt;br /&gt;
&lt;br /&gt;
* '''Pattern Matching''': Notice how form data comes in as &amp;lt;code&amp;gt;%{&amp;quot;todo&amp;quot; =&amp;gt; todo_params}&amp;lt;/code&amp;gt; - it's automatically namespaced by your schema.&lt;br /&gt;
&lt;br /&gt;
* '''The to_form Function''': Always convert changesets to forms with &amp;lt;code&amp;gt;to_form(changeset)&amp;lt;/code&amp;gt; before passing to the template.&lt;br /&gt;
&lt;br /&gt;
* '''Empty vs. Populated Structs''': &lt;br /&gt;
** Use empty &amp;lt;code&amp;gt;%Todo{}&amp;lt;/code&amp;gt; for validation&lt;br /&gt;
** Use populated struct for editing existing records&lt;br /&gt;
&lt;br /&gt;
* '''Error Handling''': On save failure, you just re-assign the form with the error changeset, and Phoenix shows the errors.&lt;br /&gt;
&lt;br /&gt;
This pattern is consistent across nearly all LiveView forms in Phoenix - master this flow and you'll be able to handle virtually any form scenario.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Same Code with Simple_Form ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.SandLive do&lt;br /&gt;
    use AppWeb, :live_view&lt;br /&gt;
  &lt;br /&gt;
    alias App.Todos&lt;br /&gt;
    alias App.Todos.Todo&lt;br /&gt;
  &lt;br /&gt;
    def mount(_params, _session, socket) do&lt;br /&gt;
      changeset = Todos.change_todo(%Todo{})&lt;br /&gt;
      {:ok, assign(socket, form: to_form(changeset))}&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    def render(assigns) do&lt;br /&gt;
      ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
      &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;.simple_form for={@form} phx-change=&amp;quot;validate&amp;quot; phx-submit=&amp;quot;save&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;.input field={@form[:name]} type=&amp;quot;text&amp;quot; label=&amp;quot;Name&amp;quot; /&amp;gt;&lt;br /&gt;
          &amp;lt;:actions&amp;gt;&lt;br /&gt;
            &amp;lt;.button&amp;gt;SAVE&amp;lt;/.button&amp;gt;&lt;br /&gt;
          &amp;lt;/:actions&amp;gt;&lt;br /&gt;
        &amp;lt;/.simple_form&amp;gt;&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
      &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    def handle_event(&amp;quot;validate&amp;quot;, %{&amp;quot;todo&amp;quot; =&amp;gt; todo_params}, socket) do&lt;br /&gt;
      changeset =&lt;br /&gt;
        %Todo{}&lt;br /&gt;
        |&amp;gt; Todos.change_todo(todo_params)&lt;br /&gt;
        |&amp;gt; Map.put(:action, :validate)&lt;br /&gt;
        &lt;br /&gt;
      {:noreply, assign(socket, form: to_form(changeset))}&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    def handle_event(&amp;quot;save&amp;quot;, %{&amp;quot;todo&amp;quot; =&amp;gt; todo_params}, socket) do&lt;br /&gt;
      case Todos.create_todo(todo_params) do&lt;br /&gt;
        {:ok, _todo} -&amp;gt;&lt;br /&gt;
          {:noreply,&lt;br /&gt;
           socket&lt;br /&gt;
           |&amp;gt; put_flash(:info, &amp;quot;Todo created successfully.&amp;quot;)&lt;br /&gt;
           |&amp;gt; redirect(to: &amp;quot;/&amp;quot;)}&lt;br /&gt;
        {:error, %Ecto.Changeset{} = changeset} -&amp;gt;&lt;br /&gt;
          {:noreply, assign(socket, form: to_form(changeset))}&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>http://elixirblocks.com/index.php?title=Understanding_Forms_and_Changesets&amp;diff=1894</id>
		<title>Understanding Forms and Changesets</title>
		<link rel="alternate" type="text/html" href="http://elixirblocks.com/index.php?title=Understanding_Forms_and_Changesets&amp;diff=1894"/>
		<updated>2025-03-23T20:52:13Z</updated>

		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{In_progress}}&lt;br /&gt;
&lt;br /&gt;
This tutorial assumes you have a basic understanding of Elixir and that you have explored Phoenix. It also assumes that you understand HTML forms. &lt;br /&gt;
&lt;br /&gt;
The methodology of this tutorial includes converting a conventional HTML form into a Phoenix template that uses Elixir to communicate with back end code. You also learn how changesets integrate with controllers. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Getting Started=&lt;br /&gt;
&lt;br /&gt;
To begin, create a new empty Phoenix app named app. If you do not know how to do that follow this tutorial:&lt;br /&gt;
&lt;br /&gt;
[[How to Create an Empty Phoenix Application|How to Create an Empty Phoenix Application]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Creating an HTML Form and Post Request==&lt;br /&gt;
&lt;br /&gt;
In the [[router]] create these two routes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  scope &amp;quot;/&amp;quot;, AppWeb do&lt;br /&gt;
    pipe_through :browser&lt;br /&gt;
&lt;br /&gt;
    get &amp;quot;/&amp;quot;, PageController, :index       # First route&lt;br /&gt;
    post &amp;quot;/create&amp;quot;, PageController, :new  # Second route&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Place the code below in a file named  '''page_controller.ex'''. Place the file in the controller directory.&lt;br /&gt;
&lt;br /&gt;
'''app/lib/app_web/controllers/page_controller.ex'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.PageController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  def index(conn, params) do&lt;br /&gt;
    IO.inspect params&lt;br /&gt;
    csrf_token = Plug.CSRFProtection.get_csrf_token()&lt;br /&gt;
    render(conn, :index, data: &amp;quot;Hello World&amp;quot;,form: %{},csrf_token: csrf_token)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def new(conn, params) do&lt;br /&gt;
      IO.inspect params&lt;br /&gt;
      redirect(conn, to: &amp;quot;/&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In the controllers directory create a file named '''page_html.ex'''&lt;br /&gt;
&lt;br /&gt;
In this file, copy this code.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageHTML do&lt;br /&gt;
  use AppWeb, :html&lt;br /&gt;
&lt;br /&gt;
  embed_templates &amp;quot;page_html/*&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In the controllers directory create another directory named '''page_html''' (technically you can place this directory outside the controllers and it will still work).&lt;br /&gt;
&lt;br /&gt;
'''app/lib/app_web/controllers/page_html'''&lt;br /&gt;
&lt;br /&gt;
This directory will contain heex templates for the PageController.&lt;br /&gt;
&lt;br /&gt;
In the page_html directory place a file named '''index.html.heex'''.&lt;br /&gt;
&lt;br /&gt;
Inside the file copy the following code.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;%=@data%&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;form method=&amp;quot;POST&amp;quot; action=&amp;quot;/create&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;_csrf_token&amp;quot; value={@csrf_token} /&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;example&amp;quot; /&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;submit&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;/form&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Run the server:   mix phx.server&lt;br /&gt;
&lt;br /&gt;
You should see a form field and a submit button with the text &amp;quot;Hello World&amp;quot; above them. Type into the form and submit it, the terminal will display your input. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you replace the form with the built in form helper, you can remove the csrf code. CSRF protection comes built in with the form helper. Delete or comment out the code in index.html.heex and replace it with the code below.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;.form :let={f} action={~p&amp;quot;/create&amp;quot;}&amp;gt;&lt;br /&gt;
    &amp;lt;.input field={f[:x]} name=&amp;quot;submitted-data&amp;quot; /&amp;gt;&lt;br /&gt;
  &amp;lt;/.form&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Delete or comment out the code in page_controller.ex and replace it with the code below.&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  def index(conn, params) do&lt;br /&gt;
    IO.inspect params&lt;br /&gt;
    render(conn, :index, data: &amp;quot;Hello World&amp;quot;,form: %{})&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def new(conn, params) do&lt;br /&gt;
      IO.inspect params&lt;br /&gt;
      redirect(conn, to: &amp;quot;/&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When you run the server and visit the landing page, you should see the page render without error.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Form Changesets===&lt;br /&gt;
Without Changesets we have these two problems:&lt;br /&gt;
&lt;br /&gt;
* We lose what we typed.&lt;br /&gt;
* The app doesn’t tell us what our errors were.&lt;br /&gt;
&lt;br /&gt;
Changesets solve both of these problems.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Schema and Live View Form==&lt;br /&gt;
&lt;br /&gt;
===Schema===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule App.Todo do&lt;br /&gt;
  use Ecto.Schema&lt;br /&gt;
  import Ecto.Changeset&lt;br /&gt;
&lt;br /&gt;
  schema &amp;quot;todos&amp;quot; do&lt;br /&gt;
    field :description, :string&lt;br /&gt;
    field :title, :string&lt;br /&gt;
&lt;br /&gt;
    timestamps(type: :utc_datetime)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  @doc false&lt;br /&gt;
  def changeset(todo, attrs) do&lt;br /&gt;
    todo&lt;br /&gt;
    |&amp;gt; cast(attrs, [:title, :description])&lt;br /&gt;
    |&amp;gt; validate_required([:title, :description])&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Live View Form ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  alias App.Todo&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    changeset = Todo.changeset(%Todo{}, %{})&lt;br /&gt;
    &lt;br /&gt;
    {:ok,&lt;br /&gt;
     socket&lt;br /&gt;
     |&amp;gt; assign(:changeset, changeset)&lt;br /&gt;
     |&amp;gt; assign(:todo, %Todo{})&lt;br /&gt;
     |&amp;gt; assign(:saved, false)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;save&amp;quot;, %{&amp;quot;todo&amp;quot; =&amp;gt; todo_params}, socket) do&lt;br /&gt;
   case save_todo(todo_params) do&lt;br /&gt;
     {:ok, _todo} -&amp;gt;&lt;br /&gt;
       {:noreply,&lt;br /&gt;
        socket&lt;br /&gt;
        |&amp;gt; assign(:changeset, Todo.changeset(%Todo{}, %{}))&lt;br /&gt;
        |&amp;gt; assign(:saved, true)}&lt;br /&gt;
&lt;br /&gt;
     {:error, %Ecto.Changeset{} = changeset} -&amp;gt;&lt;br /&gt;
       {:noreply, assign(socket, changeset: changeset, saved: false)}&lt;br /&gt;
   end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 defp save_todo(todo_params) do&lt;br /&gt;
   %Todo{}&lt;br /&gt;
   |&amp;gt; Todo.changeset(todo_params)&lt;br /&gt;
   |&amp;gt; App.Repo.insert()&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    &amp;lt;.form :let={f} for={@changeset} phx-submit=&amp;quot;save&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;.input field={f[:title]} type=&amp;quot;text&amp;quot; label=&amp;quot;Title&amp;quot; /&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;.input field={f[:description]} type=&amp;quot;textarea&amp;quot; label=&amp;quot;Description&amp;quot; /&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;.button&amp;gt;Save&amp;lt;/.button&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;/.form&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;%= if @saved do %&amp;gt;&lt;br /&gt;
      &amp;lt;div class=&amp;quot;alert alert-info&amp;quot;&amp;gt;&lt;br /&gt;
        Todo saved successfully!&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://adopt-liveview.lubien.dev/guides/simple-forms-with-ecto/en&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===A Working Form Without Changesets ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.SandLive do &lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
&lt;br /&gt;
  alias App.Todos&lt;br /&gt;
  alias App.Todos.Todo&lt;br /&gt;
&lt;br /&gt;
  def mount(params,session,socket) do  &lt;br /&gt;
    &lt;br /&gt;
    {:ok, assign(socket, data: &amp;quot;some data&amp;quot;)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    &lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;  &lt;br /&gt;
        &amp;lt;div&amp;gt;&lt;br /&gt;
            &amp;lt;.form  :let={f}  phx-submit=&amp;quot;save&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;.input field={f[:name]} type=&amp;quot;text&amp;quot; label=&amp;quot;Name&amp;quot; value=&amp;quot;&amp;quot; /&amp;gt;&lt;br /&gt;
                &amp;lt;.button&amp;gt;SAVE &amp;lt;/.button&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
            &amp;lt;/.form&amp;gt;&lt;br /&gt;
&lt;br /&gt;
          {@data}&lt;br /&gt;
&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
      &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;save&amp;quot;,params, socket) do &lt;br /&gt;
      IO.inspect params&lt;br /&gt;
&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Same Example Without Changeset and With Flash Message ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.SandLive do &lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
&lt;br /&gt;
  alias App.Todos&lt;br /&gt;
  alias App.Todos.Todo&lt;br /&gt;
&lt;br /&gt;
  def mount(params,session,socket) do  &lt;br /&gt;
    {:ok, assign(socket, data: &amp;quot;some data&amp;quot;)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    &lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;  &lt;br /&gt;
        &amp;lt;div&amp;gt;&lt;br /&gt;
            &amp;lt;.form  :let={f}  phx-submit=&amp;quot;save&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;.input field={f[:name]} type=&amp;quot;text&amp;quot; label=&amp;quot;Name&amp;quot; value=&amp;quot;&amp;quot; /&amp;gt;&lt;br /&gt;
                &amp;lt;.button&amp;gt;SAVE &amp;lt;/.button&amp;gt;&lt;br /&gt;
            &amp;lt;/.form&amp;gt;&lt;br /&gt;
          {@data}&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
      &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;save&amp;quot;, %{&amp;quot;name&amp;quot; =&amp;gt; name} = params, socket) do &lt;br /&gt;
    IO.inspect params&lt;br /&gt;
    &lt;br /&gt;
    # Create todo without using a changeset directly&lt;br /&gt;
    result = Todos.create_todo(%{&amp;quot;name&amp;quot; =&amp;gt; name})&lt;br /&gt;
    &lt;br /&gt;
    case result do&lt;br /&gt;
      {:ok, _todo} -&amp;gt;&lt;br /&gt;
        {:noreply, socket &lt;br /&gt;
        |&amp;gt; put_flash(:info, &amp;quot;User created successfully.&amp;quot;) &lt;br /&gt;
        |&amp;gt; redirect(to: &amp;quot;/&amp;quot;)}&lt;br /&gt;
      {:error, _reason} -&amp;gt;&lt;br /&gt;
        {:noreply, socket |&amp;gt; put_flash(:error, &amp;quot;Failed to create user.&amp;quot;)}&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===The Same Example with a Changeset ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
    use AppWeb, :live_view&lt;br /&gt;
  &lt;br /&gt;
    alias App.Todos&lt;br /&gt;
    alias App.Todos.Todo&lt;br /&gt;
  &lt;br /&gt;
    def mount(_params, _session, socket) do&lt;br /&gt;
      changeset = Todos.change_todo(%Todo{})&lt;br /&gt;
      {:ok, assign(socket, changeset: changeset)}&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    def render(assigns) do&lt;br /&gt;
      ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
      &amp;lt;h1&amp;gt;Create User&amp;lt;/h1&amp;gt;&lt;br /&gt;
      &amp;lt;.form :let={f} for={@changeset} phx-submit=&amp;quot;save&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;.input field={f[:name]} type=&amp;quot;text&amp;quot; label=&amp;quot;Name&amp;quot; /&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
      &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;.button&amp;gt;Save&amp;lt;/.button&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;/.form&amp;gt;&lt;br /&gt;
      &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    def handle_event(&amp;quot;save&amp;quot;, %{&amp;quot;todo&amp;quot; =&amp;gt; todo_params}, socket) do&lt;br /&gt;
&lt;br /&gt;
      result =  Todos.create_todo(todo_params)&lt;br /&gt;
      IO.inspect result&lt;br /&gt;
&lt;br /&gt;
      case Todos.create_todo(todo_params) do&lt;br /&gt;
        {:ok, _todo} -&amp;gt;&lt;br /&gt;
          {:noreply, socket &lt;br /&gt;
          |&amp;gt; put_flash(:info, &amp;quot;User created successfully.&amp;quot;) &lt;br /&gt;
          |&amp;gt; redirect(to: &amp;quot;/&amp;quot;)}&lt;br /&gt;
&lt;br /&gt;
        {:error, %Ecto.Changeset{} = changeset} -&amp;gt;&lt;br /&gt;
          {:noreply, assign(socket, changeset: changeset)}&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Troubleshooting ChangeSets Example ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.SandLive do&lt;br /&gt;
    use AppWeb, :live_view&lt;br /&gt;
  &lt;br /&gt;
    alias App.Todos&lt;br /&gt;
    alias App.Todos.Todo&lt;br /&gt;
  &lt;br /&gt;
    def mount(_params, _session, socket) do&lt;br /&gt;
      # Create an empty changeset for the form&lt;br /&gt;
      changeset = Todos.change_todo(%Todo{})&lt;br /&gt;
      # Initialize debug_info to an empty map&lt;br /&gt;
      {:ok, assign(socket, data: &amp;quot;some data&amp;quot;, changeset: changeset, debug_info: %{})}&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    def render(assigns) do&lt;br /&gt;
      ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
      &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;.form :let={f} for={@changeset} phx-submit=&amp;quot;save&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;.input field={f[:name]} type=&amp;quot;text&amp;quot; label=&amp;quot;Name&amp;quot; /&amp;gt;&lt;br /&gt;
          &amp;lt;.button&amp;gt;SAVE&amp;lt;/.button&amp;gt;&lt;br /&gt;
        &amp;lt;/.form&amp;gt;&lt;br /&gt;
        &amp;lt;p&amp;gt;{@data}&amp;lt;/p&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
        &amp;lt;%= if map_size(@debug_info) &amp;gt; 0 do %&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;mt-4&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;h3 class=&amp;quot;text-lg font-bold&amp;quot;&amp;gt;Debug Info:&amp;lt;/h3&amp;gt;&lt;br /&gt;
            &amp;lt;pre class=&amp;quot;bg-gray-100 p-2 text-sm overflow-auto&amp;quot;&amp;gt;&amp;lt;%= inspect(@debug_info, pretty: true) %&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
          &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;% end %&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
      &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    def handle_event(&amp;quot;save&amp;quot;, %{&amp;quot;todo&amp;quot; =&amp;gt; todo_params} = params, socket) do&lt;br /&gt;
      # Log the raw params first&lt;br /&gt;
      IO.inspect(params, label: &amp;quot;Raw form parameters&amp;quot;)&lt;br /&gt;
      &lt;br /&gt;
      # Create a changeset without saving (for inspection)&lt;br /&gt;
      inspection_changeset = Todo.changeset(%Todo{}, todo_params)&lt;br /&gt;
      IO.inspect(inspection_changeset, label: &amp;quot;Changeset before save&amp;quot;)&lt;br /&gt;
      &lt;br /&gt;
      # Note the cast fields&lt;br /&gt;
      IO.inspect(inspection_changeset.changes, label: &amp;quot;Fields that will change&amp;quot;)&lt;br /&gt;
      &lt;br /&gt;
      # Note any errors that would occur&lt;br /&gt;
      IO.inspect(inspection_changeset.errors, label: &amp;quot;Validation errors&amp;quot;)&lt;br /&gt;
      &lt;br /&gt;
      # Now proceed with the actual save&lt;br /&gt;
      result = Todos.create_todo(todo_params)&lt;br /&gt;
      &lt;br /&gt;
      case result do&lt;br /&gt;
        {:ok, todo} -&amp;gt;&lt;br /&gt;
          # Log the created record&lt;br /&gt;
          IO.inspect(todo, label: &amp;quot;Created todo&amp;quot;)&lt;br /&gt;
          &lt;br /&gt;
          {:noreply,&lt;br /&gt;
           socket&lt;br /&gt;
           |&amp;gt; assign(debug_info: %{&lt;br /&gt;
              raw_params: params,&lt;br /&gt;
              changeset: inspection_changeset,&lt;br /&gt;
              changes: inspection_changeset.changes,&lt;br /&gt;
              errors: inspection_changeset.errors,&lt;br /&gt;
              created_record: todo&lt;br /&gt;
           })&lt;br /&gt;
           |&amp;gt; put_flash(:info, &amp;quot;User created successfully.&amp;quot;)&lt;br /&gt;
           |&amp;gt; redirect(to: &amp;quot;/sandbox&amp;quot;)}&lt;br /&gt;
  &lt;br /&gt;
        {:error, changeset} -&amp;gt;&lt;br /&gt;
          # Log the error changeset&lt;br /&gt;
          IO.inspect(changeset, label: &amp;quot;Error changeset&amp;quot;)&lt;br /&gt;
          &lt;br /&gt;
          {:noreply, &lt;br /&gt;
           socket &lt;br /&gt;
           |&amp;gt; assign(changeset: changeset, debug_info: %{&lt;br /&gt;
              raw_params: params,&lt;br /&gt;
              error_changeset: changeset,&lt;br /&gt;
              errors: changeset.errors&lt;br /&gt;
           })&lt;br /&gt;
           |&amp;gt; put_flash(:error, &amp;quot;Failed to create user.&amp;quot;)}&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Changeset with Modern to_form (follow this exmple)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.SandLive do&lt;br /&gt;
    use AppWeb, :live_view&lt;br /&gt;
  &lt;br /&gt;
    alias App.Todos&lt;br /&gt;
    alias App.Todos.Todo&lt;br /&gt;
  &lt;br /&gt;
    def mount(_params, _session, socket) do&lt;br /&gt;
      changeset = Todos.change_todo(%Todo{})&lt;br /&gt;
      {:ok, assign(socket, form: to_form(changeset), data: &amp;quot;some data&amp;quot;)}&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    def render(assigns) do&lt;br /&gt;
      ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
      &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;.form for={@form} phx-change=&amp;quot;validate&amp;quot; phx-submit=&amp;quot;save&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;.input field={@form[:name]} type=&amp;quot;text&amp;quot; label=&amp;quot;Name&amp;quot; /&amp;gt;&lt;br /&gt;
          &amp;lt;.button&amp;gt;SAVE&amp;lt;/.button&amp;gt;&lt;br /&gt;
        &amp;lt;/.form&amp;gt;&lt;br /&gt;
        {@data}&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
      &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    &lt;br /&gt;
    def handle_event(&amp;quot;validate&amp;quot;, %{&amp;quot;todo&amp;quot; =&amp;gt; todo_params}, socket) do&lt;br /&gt;
      changeset =&lt;br /&gt;
        %Todo{}&lt;br /&gt;
        |&amp;gt; Todos.change_todo(todo_params)&lt;br /&gt;
        |&amp;gt; Map.put(:action, :validate)&lt;br /&gt;
        &lt;br /&gt;
      {:noreply, assign(socket, form: to_form(changeset))}&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    def handle_event(&amp;quot;save&amp;quot;, %{&amp;quot;todo&amp;quot; =&amp;gt; todo_params}, socket) do&lt;br /&gt;
      case Todos.create_todo(todo_params) do&lt;br /&gt;
        {:ok, _todo} -&amp;gt;&lt;br /&gt;
          {:noreply,&lt;br /&gt;
           socket&lt;br /&gt;
           |&amp;gt; put_flash(:info, &amp;quot;Todo created successfully.&amp;quot;)&lt;br /&gt;
           |&amp;gt; redirect(to: &amp;quot;/&amp;quot;)}&lt;br /&gt;
  &lt;br /&gt;
        {:error, %Ecto.Changeset{} = changeset} -&amp;gt;&lt;br /&gt;
          {:noreply, assign(socket, form: to_form(changeset))}&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
______________________________________________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Phoenix LiveView Forms &amp;amp; Changeset Tutorial =&lt;br /&gt;
&lt;br /&gt;
Here's a concise tutorial to help you learn and recall the syntax for Phoenix LiveView forms with Ecto changesets.&lt;br /&gt;
&lt;br /&gt;
== The Changeset Flow ==&lt;br /&gt;
&lt;br /&gt;
Think of the changeset as the &amp;quot;form manager&amp;quot; that follows this pattern:&lt;br /&gt;
&lt;br /&gt;
# '''Initialize''' - Create an empty changeset for the form&lt;br /&gt;
# '''Validate''' - Update changeset when user types (phx-change)&lt;br /&gt;
# '''Submit''' - Process final changeset when user submits (phx-submit)&lt;br /&gt;
&lt;br /&gt;
== Key Components ==&lt;br /&gt;
&lt;br /&gt;
=== 1. Initial Setup in Mount ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;elixir&amp;quot;&amp;gt;&lt;br /&gt;
def mount(_params, _session, socket) do&lt;br /&gt;
  changeset = Todos.change_todo(%Todo{})&lt;br /&gt;
  {:ok, assign(socket, form: to_form(changeset), data: &amp;quot;some data&amp;quot;)}&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Memory Trick''': &amp;quot;Mount needs a blank changeset to start the form&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== 2. Rendering the Form ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;elixir&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;.form for={@form} phx-change=&amp;quot;validate&amp;quot; phx-submit=&amp;quot;save&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;.input field={@form[:name]} type=&amp;quot;text&amp;quot; label=&amp;quot;Name&amp;quot; /&amp;gt;&lt;br /&gt;
  &amp;lt;.button&amp;gt;SAVE&amp;lt;/.button&amp;gt;&lt;br /&gt;
&amp;lt;/.form&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Memory Trick''': &amp;quot;phx-change validates as you type, phx-submit saves when done&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== 3. Validation Handler ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;elixir&amp;quot;&amp;gt;&lt;br /&gt;
def handle_event(&amp;quot;validate&amp;quot;, %{&amp;quot;todo&amp;quot; =&amp;gt; todo_params}, socket) do&lt;br /&gt;
  changeset =&lt;br /&gt;
    %Todo{}&lt;br /&gt;
    |&amp;gt; Todos.change_todo(todo_params)&lt;br /&gt;
    |&amp;gt; Map.put(:action, :validate)&lt;br /&gt;
    &lt;br /&gt;
  {:noreply, assign(socket, form: to_form(changeset))}&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Memory Tricks''': &lt;br /&gt;
* &amp;quot;Validate always starts with an empty struct (%Todo{})&amp;quot;&lt;br /&gt;
* &amp;quot;Map.put(:action, :validate) shows errors but doesn't save&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== 4. Save Handler ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;elixir&amp;quot;&amp;gt;&lt;br /&gt;
def handle_event(&amp;quot;save&amp;quot;, %{&amp;quot;todo&amp;quot; =&amp;gt; todo_params}, socket) do&lt;br /&gt;
  case Todos.create_todo(todo_params) do&lt;br /&gt;
    {:ok, _todo} -&amp;gt;&lt;br /&gt;
      {:noreply,&lt;br /&gt;
       socket&lt;br /&gt;
       |&amp;gt; put_flash(:info, &amp;quot;Todo created successfully.&amp;quot;)&lt;br /&gt;
       |&amp;gt; redirect(to: &amp;quot;/&amp;quot;)}&lt;br /&gt;
&lt;br /&gt;
    {:error, %Ecto.Changeset{} = changeset} -&amp;gt;&lt;br /&gt;
      {:noreply, assign(socket, form: to_form(changeset))}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Memory Trick''': &amp;quot;Save has two paths: success (redirect) or error (show form again)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Changeset Flow Mnemonic: &amp;quot;CIVC&amp;quot; ==&lt;br /&gt;
&lt;br /&gt;
# '''C'''reate changeset in mount&lt;br /&gt;
# '''I'''nput through the form&lt;br /&gt;
# '''V'''alidate with phx-change&lt;br /&gt;
# '''C'''omplete with phx-submit&lt;br /&gt;
&lt;br /&gt;
== Additional Tips ==&lt;br /&gt;
&lt;br /&gt;
* '''Pattern Matching''': Notice how form data comes in as &amp;lt;code&amp;gt;%{&amp;quot;todo&amp;quot; =&amp;gt; todo_params}&amp;lt;/code&amp;gt; - it's automatically namespaced by your schema.&lt;br /&gt;
&lt;br /&gt;
* '''The to_form Function''': Always convert changesets to forms with &amp;lt;code&amp;gt;to_form(changeset)&amp;lt;/code&amp;gt; before passing to the template.&lt;br /&gt;
&lt;br /&gt;
* '''Empty vs. Populated Structs''': &lt;br /&gt;
** Use empty &amp;lt;code&amp;gt;%Todo{}&amp;lt;/code&amp;gt; for validation&lt;br /&gt;
** Use populated struct for editing existing records&lt;br /&gt;
&lt;br /&gt;
* '''Error Handling''': On save failure, you just re-assign the form with the error changeset, and Phoenix shows the errors.&lt;br /&gt;
&lt;br /&gt;
This pattern is consistent across nearly all LiveView forms in Phoenix - master this flow and you'll be able to handle virtually any form scenario.&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>http://elixirblocks.com/index.php?title=Understanding_Forms_and_Changesets&amp;diff=1893</id>
		<title>Understanding Forms and Changesets</title>
		<link rel="alternate" type="text/html" href="http://elixirblocks.com/index.php?title=Understanding_Forms_and_Changesets&amp;diff=1893"/>
		<updated>2025-03-23T18:32:05Z</updated>

		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{In_progress}}&lt;br /&gt;
&lt;br /&gt;
This tutorial assumes you have a basic understanding of Elixir and that you have explored Phoenix. It also assumes that you understand HTML forms. &lt;br /&gt;
&lt;br /&gt;
The methodology of this tutorial includes converting a conventional HTML form into a Phoenix template that uses Elixir to communicate with back end code. You also learn how changesets integrate with controllers. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Getting Started=&lt;br /&gt;
&lt;br /&gt;
To begin, create a new empty Phoenix app named app. If you do not know how to do that follow this tutorial:&lt;br /&gt;
&lt;br /&gt;
[[How to Create an Empty Phoenix Application|How to Create an Empty Phoenix Application]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Creating an HTML Form and Post Request==&lt;br /&gt;
&lt;br /&gt;
In the [[router]] create these two routes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  scope &amp;quot;/&amp;quot;, AppWeb do&lt;br /&gt;
    pipe_through :browser&lt;br /&gt;
&lt;br /&gt;
    get &amp;quot;/&amp;quot;, PageController, :index       # First route&lt;br /&gt;
    post &amp;quot;/create&amp;quot;, PageController, :new  # Second route&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Place the code below in a file named  '''page_controller.ex'''. Place the file in the controller directory.&lt;br /&gt;
&lt;br /&gt;
'''app/lib/app_web/controllers/page_controller.ex'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.PageController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  def index(conn, params) do&lt;br /&gt;
    IO.inspect params&lt;br /&gt;
    csrf_token = Plug.CSRFProtection.get_csrf_token()&lt;br /&gt;
    render(conn, :index, data: &amp;quot;Hello World&amp;quot;,form: %{},csrf_token: csrf_token)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def new(conn, params) do&lt;br /&gt;
      IO.inspect params&lt;br /&gt;
      redirect(conn, to: &amp;quot;/&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In the controllers directory create a file named '''page_html.ex'''&lt;br /&gt;
&lt;br /&gt;
In this file, copy this code.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageHTML do&lt;br /&gt;
  use AppWeb, :html&lt;br /&gt;
&lt;br /&gt;
  embed_templates &amp;quot;page_html/*&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In the controllers directory create another directory named '''page_html''' (technically you can place this directory outside the controllers and it will still work).&lt;br /&gt;
&lt;br /&gt;
'''app/lib/app_web/controllers/page_html'''&lt;br /&gt;
&lt;br /&gt;
This directory will contain heex templates for the PageController.&lt;br /&gt;
&lt;br /&gt;
In the page_html directory place a file named '''index.html.heex'''.&lt;br /&gt;
&lt;br /&gt;
Inside the file copy the following code.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;%=@data%&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;form method=&amp;quot;POST&amp;quot; action=&amp;quot;/create&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;_csrf_token&amp;quot; value={@csrf_token} /&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;example&amp;quot; /&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;submit&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;/form&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Run the server:   mix phx.server&lt;br /&gt;
&lt;br /&gt;
You should see a form field and a submit button with the text &amp;quot;Hello World&amp;quot; above them. Type into the form and submit it, the terminal will display your input. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you replace the form with the built in form helper, you can remove the csrf code. CSRF protection comes built in with the form helper. Delete or comment out the code in index.html.heex and replace it with the code below.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;.form :let={f} action={~p&amp;quot;/create&amp;quot;}&amp;gt;&lt;br /&gt;
    &amp;lt;.input field={f[:x]} name=&amp;quot;submitted-data&amp;quot; /&amp;gt;&lt;br /&gt;
  &amp;lt;/.form&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Delete or comment out the code in page_controller.ex and replace it with the code below.&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  def index(conn, params) do&lt;br /&gt;
    IO.inspect params&lt;br /&gt;
    render(conn, :index, data: &amp;quot;Hello World&amp;quot;,form: %{})&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def new(conn, params) do&lt;br /&gt;
      IO.inspect params&lt;br /&gt;
      redirect(conn, to: &amp;quot;/&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When you run the server and visit the landing page, you should see the page render without error.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Form Changesets===&lt;br /&gt;
Without Changesets we have these two problems:&lt;br /&gt;
&lt;br /&gt;
* We lose what we typed.&lt;br /&gt;
* The app doesn’t tell us what our errors were.&lt;br /&gt;
&lt;br /&gt;
Changesets solve both of these problems.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Schema and Live View Form==&lt;br /&gt;
&lt;br /&gt;
===Schema===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule App.Todo do&lt;br /&gt;
  use Ecto.Schema&lt;br /&gt;
  import Ecto.Changeset&lt;br /&gt;
&lt;br /&gt;
  schema &amp;quot;todos&amp;quot; do&lt;br /&gt;
    field :description, :string&lt;br /&gt;
    field :title, :string&lt;br /&gt;
&lt;br /&gt;
    timestamps(type: :utc_datetime)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  @doc false&lt;br /&gt;
  def changeset(todo, attrs) do&lt;br /&gt;
    todo&lt;br /&gt;
    |&amp;gt; cast(attrs, [:title, :description])&lt;br /&gt;
    |&amp;gt; validate_required([:title, :description])&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Live View Form ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  alias App.Todo&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    changeset = Todo.changeset(%Todo{}, %{})&lt;br /&gt;
    &lt;br /&gt;
    {:ok,&lt;br /&gt;
     socket&lt;br /&gt;
     |&amp;gt; assign(:changeset, changeset)&lt;br /&gt;
     |&amp;gt; assign(:todo, %Todo{})&lt;br /&gt;
     |&amp;gt; assign(:saved, false)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;save&amp;quot;, %{&amp;quot;todo&amp;quot; =&amp;gt; todo_params}, socket) do&lt;br /&gt;
   case save_todo(todo_params) do&lt;br /&gt;
     {:ok, _todo} -&amp;gt;&lt;br /&gt;
       {:noreply,&lt;br /&gt;
        socket&lt;br /&gt;
        |&amp;gt; assign(:changeset, Todo.changeset(%Todo{}, %{}))&lt;br /&gt;
        |&amp;gt; assign(:saved, true)}&lt;br /&gt;
&lt;br /&gt;
     {:error, %Ecto.Changeset{} = changeset} -&amp;gt;&lt;br /&gt;
       {:noreply, assign(socket, changeset: changeset, saved: false)}&lt;br /&gt;
   end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 defp save_todo(todo_params) do&lt;br /&gt;
   %Todo{}&lt;br /&gt;
   |&amp;gt; Todo.changeset(todo_params)&lt;br /&gt;
   |&amp;gt; App.Repo.insert()&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    &amp;lt;.form :let={f} for={@changeset} phx-submit=&amp;quot;save&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;.input field={f[:title]} type=&amp;quot;text&amp;quot; label=&amp;quot;Title&amp;quot; /&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;.input field={f[:description]} type=&amp;quot;textarea&amp;quot; label=&amp;quot;Description&amp;quot; /&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;.button&amp;gt;Save&amp;lt;/.button&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;/.form&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;%= if @saved do %&amp;gt;&lt;br /&gt;
      &amp;lt;div class=&amp;quot;alert alert-info&amp;quot;&amp;gt;&lt;br /&gt;
        Todo saved successfully!&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://adopt-liveview.lubien.dev/guides/simple-forms-with-ecto/en&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===A Working Form Without Changesets ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.SandLive do &lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
&lt;br /&gt;
  alias App.Todos&lt;br /&gt;
  alias App.Todos.Todo&lt;br /&gt;
&lt;br /&gt;
  def mount(params,session,socket) do  &lt;br /&gt;
    &lt;br /&gt;
    {:ok, assign(socket, data: &amp;quot;some data&amp;quot;)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    &lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;  &lt;br /&gt;
        &amp;lt;div&amp;gt;&lt;br /&gt;
            &amp;lt;.form  :let={f}  phx-submit=&amp;quot;save&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;.input field={f[:name]} type=&amp;quot;text&amp;quot; label=&amp;quot;Name&amp;quot; value=&amp;quot;&amp;quot; /&amp;gt;&lt;br /&gt;
                &amp;lt;.button&amp;gt;SAVE &amp;lt;/.button&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
            &amp;lt;/.form&amp;gt;&lt;br /&gt;
&lt;br /&gt;
          {@data}&lt;br /&gt;
&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
      &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;save&amp;quot;,params, socket) do &lt;br /&gt;
      IO.inspect params&lt;br /&gt;
&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Same Example Without Changeset and With Flash Message ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.SandLive do &lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
&lt;br /&gt;
  alias App.Todos&lt;br /&gt;
  alias App.Todos.Todo&lt;br /&gt;
&lt;br /&gt;
  def mount(params,session,socket) do  &lt;br /&gt;
    {:ok, assign(socket, data: &amp;quot;some data&amp;quot;)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    &lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;  &lt;br /&gt;
        &amp;lt;div&amp;gt;&lt;br /&gt;
            &amp;lt;.form  :let={f}  phx-submit=&amp;quot;save&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;.input field={f[:name]} type=&amp;quot;text&amp;quot; label=&amp;quot;Name&amp;quot; value=&amp;quot;&amp;quot; /&amp;gt;&lt;br /&gt;
                &amp;lt;.button&amp;gt;SAVE &amp;lt;/.button&amp;gt;&lt;br /&gt;
            &amp;lt;/.form&amp;gt;&lt;br /&gt;
          {@data}&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
      &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;save&amp;quot;, %{&amp;quot;name&amp;quot; =&amp;gt; name} = params, socket) do &lt;br /&gt;
    IO.inspect params&lt;br /&gt;
    &lt;br /&gt;
    # Create todo without using a changeset directly&lt;br /&gt;
    result = Todos.create_todo(%{&amp;quot;name&amp;quot; =&amp;gt; name})&lt;br /&gt;
    &lt;br /&gt;
    case result do&lt;br /&gt;
      {:ok, _todo} -&amp;gt;&lt;br /&gt;
        {:noreply, socket &lt;br /&gt;
        |&amp;gt; put_flash(:info, &amp;quot;User created successfully.&amp;quot;) &lt;br /&gt;
        |&amp;gt; redirect(to: &amp;quot;/&amp;quot;)}&lt;br /&gt;
      {:error, _reason} -&amp;gt;&lt;br /&gt;
        {:noreply, socket |&amp;gt; put_flash(:error, &amp;quot;Failed to create user.&amp;quot;)}&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===The Same Example with a Changeset ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
    use AppWeb, :live_view&lt;br /&gt;
  &lt;br /&gt;
    alias App.Todos&lt;br /&gt;
    alias App.Todos.Todo&lt;br /&gt;
  &lt;br /&gt;
    def mount(_params, _session, socket) do&lt;br /&gt;
      changeset = Todos.change_todo(%Todo{})&lt;br /&gt;
      {:ok, assign(socket, changeset: changeset)}&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    def render(assigns) do&lt;br /&gt;
      ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
      &amp;lt;h1&amp;gt;Create User&amp;lt;/h1&amp;gt;&lt;br /&gt;
      &amp;lt;.form :let={f} for={@changeset} phx-submit=&amp;quot;save&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;.input field={f[:name]} type=&amp;quot;text&amp;quot; label=&amp;quot;Name&amp;quot; /&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
      &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;.button&amp;gt;Save&amp;lt;/.button&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;/.form&amp;gt;&lt;br /&gt;
      &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    def handle_event(&amp;quot;save&amp;quot;, %{&amp;quot;todo&amp;quot; =&amp;gt; todo_params}, socket) do&lt;br /&gt;
&lt;br /&gt;
      result =  Todos.create_todo(todo_params)&lt;br /&gt;
      IO.inspect result&lt;br /&gt;
&lt;br /&gt;
      case Todos.create_todo(todo_params) do&lt;br /&gt;
        {:ok, _todo} -&amp;gt;&lt;br /&gt;
          {:noreply, socket &lt;br /&gt;
          |&amp;gt; put_flash(:info, &amp;quot;User created successfully.&amp;quot;) &lt;br /&gt;
          |&amp;gt; redirect(to: &amp;quot;/&amp;quot;)}&lt;br /&gt;
&lt;br /&gt;
        {:error, %Ecto.Changeset{} = changeset} -&amp;gt;&lt;br /&gt;
          {:noreply, assign(socket, changeset: changeset)}&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Troubleshooting ChangeSets Example ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.SandLive do&lt;br /&gt;
    use AppWeb, :live_view&lt;br /&gt;
  &lt;br /&gt;
    alias App.Todos&lt;br /&gt;
    alias App.Todos.Todo&lt;br /&gt;
  &lt;br /&gt;
    def mount(_params, _session, socket) do&lt;br /&gt;
      # Create an empty changeset for the form&lt;br /&gt;
      changeset = Todos.change_todo(%Todo{})&lt;br /&gt;
      # Initialize debug_info to an empty map&lt;br /&gt;
      {:ok, assign(socket, data: &amp;quot;some data&amp;quot;, changeset: changeset, debug_info: %{})}&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    def render(assigns) do&lt;br /&gt;
      ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
      &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;.form :let={f} for={@changeset} phx-submit=&amp;quot;save&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;.input field={f[:name]} type=&amp;quot;text&amp;quot; label=&amp;quot;Name&amp;quot; /&amp;gt;&lt;br /&gt;
          &amp;lt;.button&amp;gt;SAVE&amp;lt;/.button&amp;gt;&lt;br /&gt;
        &amp;lt;/.form&amp;gt;&lt;br /&gt;
        &amp;lt;p&amp;gt;{@data}&amp;lt;/p&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
        &amp;lt;%= if map_size(@debug_info) &amp;gt; 0 do %&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;mt-4&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;h3 class=&amp;quot;text-lg font-bold&amp;quot;&amp;gt;Debug Info:&amp;lt;/h3&amp;gt;&lt;br /&gt;
            &amp;lt;pre class=&amp;quot;bg-gray-100 p-2 text-sm overflow-auto&amp;quot;&amp;gt;&amp;lt;%= inspect(@debug_info, pretty: true) %&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
          &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;% end %&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
      &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    def handle_event(&amp;quot;save&amp;quot;, %{&amp;quot;todo&amp;quot; =&amp;gt; todo_params} = params, socket) do&lt;br /&gt;
      # Log the raw params first&lt;br /&gt;
      IO.inspect(params, label: &amp;quot;Raw form parameters&amp;quot;)&lt;br /&gt;
      &lt;br /&gt;
      # Create a changeset without saving (for inspection)&lt;br /&gt;
      inspection_changeset = Todo.changeset(%Todo{}, todo_params)&lt;br /&gt;
      IO.inspect(inspection_changeset, label: &amp;quot;Changeset before save&amp;quot;)&lt;br /&gt;
      &lt;br /&gt;
      # Note the cast fields&lt;br /&gt;
      IO.inspect(inspection_changeset.changes, label: &amp;quot;Fields that will change&amp;quot;)&lt;br /&gt;
      &lt;br /&gt;
      # Note any errors that would occur&lt;br /&gt;
      IO.inspect(inspection_changeset.errors, label: &amp;quot;Validation errors&amp;quot;)&lt;br /&gt;
      &lt;br /&gt;
      # Now proceed with the actual save&lt;br /&gt;
      result = Todos.create_todo(todo_params)&lt;br /&gt;
      &lt;br /&gt;
      case result do&lt;br /&gt;
        {:ok, todo} -&amp;gt;&lt;br /&gt;
          # Log the created record&lt;br /&gt;
          IO.inspect(todo, label: &amp;quot;Created todo&amp;quot;)&lt;br /&gt;
          &lt;br /&gt;
          {:noreply,&lt;br /&gt;
           socket&lt;br /&gt;
           |&amp;gt; assign(debug_info: %{&lt;br /&gt;
              raw_params: params,&lt;br /&gt;
              changeset: inspection_changeset,&lt;br /&gt;
              changes: inspection_changeset.changes,&lt;br /&gt;
              errors: inspection_changeset.errors,&lt;br /&gt;
              created_record: todo&lt;br /&gt;
           })&lt;br /&gt;
           |&amp;gt; put_flash(:info, &amp;quot;User created successfully.&amp;quot;)&lt;br /&gt;
           |&amp;gt; redirect(to: &amp;quot;/sandbox&amp;quot;)}&lt;br /&gt;
  &lt;br /&gt;
        {:error, changeset} -&amp;gt;&lt;br /&gt;
          # Log the error changeset&lt;br /&gt;
          IO.inspect(changeset, label: &amp;quot;Error changeset&amp;quot;)&lt;br /&gt;
          &lt;br /&gt;
          {:noreply, &lt;br /&gt;
           socket &lt;br /&gt;
           |&amp;gt; assign(changeset: changeset, debug_info: %{&lt;br /&gt;
              raw_params: params,&lt;br /&gt;
              error_changeset: changeset,&lt;br /&gt;
              errors: changeset.errors&lt;br /&gt;
           })&lt;br /&gt;
           |&amp;gt; put_flash(:error, &amp;quot;Failed to create user.&amp;quot;)}&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Changeset with Modern to_form (follow this exmple)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.SandLive do&lt;br /&gt;
    use AppWeb, :live_view&lt;br /&gt;
  &lt;br /&gt;
    alias App.Todos&lt;br /&gt;
    alias App.Todos.Todo&lt;br /&gt;
  &lt;br /&gt;
    def mount(_params, _session, socket) do&lt;br /&gt;
      changeset = Todos.change_todo(%Todo{})&lt;br /&gt;
      {:ok, assign(socket, form: to_form(changeset), data: &amp;quot;some data&amp;quot;)}&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    def render(assigns) do&lt;br /&gt;
      ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
      &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;.form for={@form} phx-change=&amp;quot;validate&amp;quot; phx-submit=&amp;quot;save&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;.input field={@form[:name]} type=&amp;quot;text&amp;quot; label=&amp;quot;Name&amp;quot; /&amp;gt;&lt;br /&gt;
          &amp;lt;.button&amp;gt;SAVE&amp;lt;/.button&amp;gt;&lt;br /&gt;
        &amp;lt;/.form&amp;gt;&lt;br /&gt;
        {@data}&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
      &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    &lt;br /&gt;
    def handle_event(&amp;quot;validate&amp;quot;, %{&amp;quot;todo&amp;quot; =&amp;gt; todo_params}, socket) do&lt;br /&gt;
      changeset =&lt;br /&gt;
        %Todo{}&lt;br /&gt;
        |&amp;gt; Todos.change_todo(todo_params)&lt;br /&gt;
        |&amp;gt; Map.put(:action, :validate)&lt;br /&gt;
        &lt;br /&gt;
      {:noreply, assign(socket, form: to_form(changeset))}&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    def handle_event(&amp;quot;save&amp;quot;, %{&amp;quot;todo&amp;quot; =&amp;gt; todo_params}, socket) do&lt;br /&gt;
      case Todos.create_todo(todo_params) do&lt;br /&gt;
        {:ok, _todo} -&amp;gt;&lt;br /&gt;
          {:noreply,&lt;br /&gt;
           socket&lt;br /&gt;
           |&amp;gt; put_flash(:info, &amp;quot;Todo created successfully.&amp;quot;)&lt;br /&gt;
           |&amp;gt; redirect(to: &amp;quot;/&amp;quot;)}&lt;br /&gt;
  &lt;br /&gt;
        {:error, %Ecto.Changeset{} = changeset} -&amp;gt;&lt;br /&gt;
          {:noreply, assign(socket, form: to_form(changeset))}&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>http://elixirblocks.com/index.php?title=Understanding_Forms_and_Changesets&amp;diff=1892</id>
		<title>Understanding Forms and Changesets</title>
		<link rel="alternate" type="text/html" href="http://elixirblocks.com/index.php?title=Understanding_Forms_and_Changesets&amp;diff=1892"/>
		<updated>2025-03-23T03:34:49Z</updated>

		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{In_progress}}&lt;br /&gt;
&lt;br /&gt;
This tutorial assumes you have a basic understanding of Elixir and that you have explored Phoenix. It also assumes that you understand HTML forms. &lt;br /&gt;
&lt;br /&gt;
The methodology of this tutorial includes converting a conventional HTML form into a Phoenix template that uses Elixir to communicate with back end code. You also learn how changesets integrate with controllers. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Getting Started=&lt;br /&gt;
&lt;br /&gt;
To begin, create a new empty Phoenix app named app. If you do not know how to do that follow this tutorial:&lt;br /&gt;
&lt;br /&gt;
[[How to Create an Empty Phoenix Application|How to Create an Empty Phoenix Application]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Creating an HTML Form and Post Request==&lt;br /&gt;
&lt;br /&gt;
In the [[router]] create these two routes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  scope &amp;quot;/&amp;quot;, AppWeb do&lt;br /&gt;
    pipe_through :browser&lt;br /&gt;
&lt;br /&gt;
    get &amp;quot;/&amp;quot;, PageController, :index       # First route&lt;br /&gt;
    post &amp;quot;/create&amp;quot;, PageController, :new  # Second route&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Place the code below in a file named  '''page_controller.ex'''. Place the file in the controller directory.&lt;br /&gt;
&lt;br /&gt;
'''app/lib/app_web/controllers/page_controller.ex'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.PageController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  def index(conn, params) do&lt;br /&gt;
    IO.inspect params&lt;br /&gt;
    csrf_token = Plug.CSRFProtection.get_csrf_token()&lt;br /&gt;
    render(conn, :index, data: &amp;quot;Hello World&amp;quot;,form: %{},csrf_token: csrf_token)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def new(conn, params) do&lt;br /&gt;
      IO.inspect params&lt;br /&gt;
      redirect(conn, to: &amp;quot;/&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In the controllers directory create a file named '''page_html.ex'''&lt;br /&gt;
&lt;br /&gt;
In this file, copy this code.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageHTML do&lt;br /&gt;
  use AppWeb, :html&lt;br /&gt;
&lt;br /&gt;
  embed_templates &amp;quot;page_html/*&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In the controllers directory create another directory named '''page_html''' (technically you can place this directory outside the controllers and it will still work).&lt;br /&gt;
&lt;br /&gt;
'''app/lib/app_web/controllers/page_html'''&lt;br /&gt;
&lt;br /&gt;
This directory will contain heex templates for the PageController.&lt;br /&gt;
&lt;br /&gt;
In the page_html directory place a file named '''index.html.heex'''.&lt;br /&gt;
&lt;br /&gt;
Inside the file copy the following code.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;%=@data%&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;form method=&amp;quot;POST&amp;quot; action=&amp;quot;/create&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;_csrf_token&amp;quot; value={@csrf_token} /&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;example&amp;quot; /&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;submit&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;/form&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Run the server:   mix phx.server&lt;br /&gt;
&lt;br /&gt;
You should see a form field and a submit button with the text &amp;quot;Hello World&amp;quot; above them. Type into the form and submit it, the terminal will display your input. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you replace the form with the built in form helper, you can remove the csrf code. CSRF protection comes built in with the form helper. Delete or comment out the code in index.html.heex and replace it with the code below.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;.form :let={f} action={~p&amp;quot;/create&amp;quot;}&amp;gt;&lt;br /&gt;
    &amp;lt;.input field={f[:x]} name=&amp;quot;submitted-data&amp;quot; /&amp;gt;&lt;br /&gt;
  &amp;lt;/.form&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Delete or comment out the code in page_controller.ex and replace it with the code below.&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  def index(conn, params) do&lt;br /&gt;
    IO.inspect params&lt;br /&gt;
    render(conn, :index, data: &amp;quot;Hello World&amp;quot;,form: %{})&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def new(conn, params) do&lt;br /&gt;
      IO.inspect params&lt;br /&gt;
      redirect(conn, to: &amp;quot;/&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When you run the server and visit the landing page, you should see the page render without error.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Form Changesets===&lt;br /&gt;
Without Changesets we have these two problems:&lt;br /&gt;
&lt;br /&gt;
* We lose what we typed.&lt;br /&gt;
* The app doesn’t tell us what our errors were.&lt;br /&gt;
&lt;br /&gt;
Changesets solve both of these problems.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Schema and Live View Form==&lt;br /&gt;
&lt;br /&gt;
===Schema===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule App.Todo do&lt;br /&gt;
  use Ecto.Schema&lt;br /&gt;
  import Ecto.Changeset&lt;br /&gt;
&lt;br /&gt;
  schema &amp;quot;todos&amp;quot; do&lt;br /&gt;
    field :description, :string&lt;br /&gt;
    field :title, :string&lt;br /&gt;
&lt;br /&gt;
    timestamps(type: :utc_datetime)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  @doc false&lt;br /&gt;
  def changeset(todo, attrs) do&lt;br /&gt;
    todo&lt;br /&gt;
    |&amp;gt; cast(attrs, [:title, :description])&lt;br /&gt;
    |&amp;gt; validate_required([:title, :description])&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Live View Form ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  alias App.Todo&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    changeset = Todo.changeset(%Todo{}, %{})&lt;br /&gt;
    &lt;br /&gt;
    {:ok,&lt;br /&gt;
     socket&lt;br /&gt;
     |&amp;gt; assign(:changeset, changeset)&lt;br /&gt;
     |&amp;gt; assign(:todo, %Todo{})&lt;br /&gt;
     |&amp;gt; assign(:saved, false)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;save&amp;quot;, %{&amp;quot;todo&amp;quot; =&amp;gt; todo_params}, socket) do&lt;br /&gt;
   case save_todo(todo_params) do&lt;br /&gt;
     {:ok, _todo} -&amp;gt;&lt;br /&gt;
       {:noreply,&lt;br /&gt;
        socket&lt;br /&gt;
        |&amp;gt; assign(:changeset, Todo.changeset(%Todo{}, %{}))&lt;br /&gt;
        |&amp;gt; assign(:saved, true)}&lt;br /&gt;
&lt;br /&gt;
     {:error, %Ecto.Changeset{} = changeset} -&amp;gt;&lt;br /&gt;
       {:noreply, assign(socket, changeset: changeset, saved: false)}&lt;br /&gt;
   end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 defp save_todo(todo_params) do&lt;br /&gt;
   %Todo{}&lt;br /&gt;
   |&amp;gt; Todo.changeset(todo_params)&lt;br /&gt;
   |&amp;gt; App.Repo.insert()&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    &amp;lt;.form :let={f} for={@changeset} phx-submit=&amp;quot;save&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;.input field={f[:title]} type=&amp;quot;text&amp;quot; label=&amp;quot;Title&amp;quot; /&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;.input field={f[:description]} type=&amp;quot;textarea&amp;quot; label=&amp;quot;Description&amp;quot; /&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;.button&amp;gt;Save&amp;lt;/.button&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;/.form&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;%= if @saved do %&amp;gt;&lt;br /&gt;
      &amp;lt;div class=&amp;quot;alert alert-info&amp;quot;&amp;gt;&lt;br /&gt;
        Todo saved successfully!&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://adopt-liveview.lubien.dev/guides/simple-forms-with-ecto/en&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===A Working Form Without Changesets ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.SandLive do &lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
&lt;br /&gt;
  alias App.Todos&lt;br /&gt;
  alias App.Todos.Todo&lt;br /&gt;
&lt;br /&gt;
  def mount(params,session,socket) do  &lt;br /&gt;
    &lt;br /&gt;
    {:ok, assign(socket, data: &amp;quot;some data&amp;quot;)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    &lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;  &lt;br /&gt;
        &amp;lt;div&amp;gt;&lt;br /&gt;
            &amp;lt;.form  :let={f}  phx-submit=&amp;quot;save&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;.input field={f[:name]} type=&amp;quot;text&amp;quot; label=&amp;quot;Name&amp;quot; value=&amp;quot;&amp;quot; /&amp;gt;&lt;br /&gt;
                &amp;lt;.button&amp;gt;SAVE &amp;lt;/.button&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
            &amp;lt;/.form&amp;gt;&lt;br /&gt;
&lt;br /&gt;
          {@data}&lt;br /&gt;
&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
      &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;save&amp;quot;,params, socket) do &lt;br /&gt;
      IO.inspect params&lt;br /&gt;
&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Same Example Without Changeset and With Flash Message ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.SandLive do &lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
&lt;br /&gt;
  alias App.Todos&lt;br /&gt;
  alias App.Todos.Todo&lt;br /&gt;
&lt;br /&gt;
  def mount(params,session,socket) do  &lt;br /&gt;
    {:ok, assign(socket, data: &amp;quot;some data&amp;quot;)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    &lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;  &lt;br /&gt;
        &amp;lt;div&amp;gt;&lt;br /&gt;
            &amp;lt;.form  :let={f}  phx-submit=&amp;quot;save&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;.input field={f[:name]} type=&amp;quot;text&amp;quot; label=&amp;quot;Name&amp;quot; value=&amp;quot;&amp;quot; /&amp;gt;&lt;br /&gt;
                &amp;lt;.button&amp;gt;SAVE &amp;lt;/.button&amp;gt;&lt;br /&gt;
            &amp;lt;/.form&amp;gt;&lt;br /&gt;
          {@data}&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
      &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;save&amp;quot;, %{&amp;quot;name&amp;quot; =&amp;gt; name} = params, socket) do &lt;br /&gt;
    IO.inspect params&lt;br /&gt;
    &lt;br /&gt;
    # Create todo without using a changeset directly&lt;br /&gt;
    result = Todos.create_todo(%{&amp;quot;name&amp;quot; =&amp;gt; name})&lt;br /&gt;
    &lt;br /&gt;
    case result do&lt;br /&gt;
      {:ok, _todo} -&amp;gt;&lt;br /&gt;
        {:noreply, socket &lt;br /&gt;
        |&amp;gt; put_flash(:info, &amp;quot;User created successfully.&amp;quot;) &lt;br /&gt;
        |&amp;gt; redirect(to: &amp;quot;/&amp;quot;)}&lt;br /&gt;
      {:error, _reason} -&amp;gt;&lt;br /&gt;
        {:noreply, socket |&amp;gt; put_flash(:error, &amp;quot;Failed to create user.&amp;quot;)}&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===The Same Example with a Changeset ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
    use AppWeb, :live_view&lt;br /&gt;
  &lt;br /&gt;
    alias App.Todos&lt;br /&gt;
    alias App.Todos.Todo&lt;br /&gt;
  &lt;br /&gt;
    def mount(_params, _session, socket) do&lt;br /&gt;
      changeset = Todos.change_todo(%Todo{})&lt;br /&gt;
      {:ok, assign(socket, changeset: changeset)}&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    def render(assigns) do&lt;br /&gt;
      ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
      &amp;lt;h1&amp;gt;Create User&amp;lt;/h1&amp;gt;&lt;br /&gt;
      &amp;lt;.form :let={f} for={@changeset} phx-submit=&amp;quot;save&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;.input field={f[:name]} type=&amp;quot;text&amp;quot; label=&amp;quot;Name&amp;quot; /&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
      &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;.button&amp;gt;Save&amp;lt;/.button&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;/.form&amp;gt;&lt;br /&gt;
      &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    def handle_event(&amp;quot;save&amp;quot;, %{&amp;quot;todo&amp;quot; =&amp;gt; todo_params}, socket) do&lt;br /&gt;
&lt;br /&gt;
      result =  Todos.create_todo(todo_params)&lt;br /&gt;
      IO.inspect result&lt;br /&gt;
&lt;br /&gt;
      case Todos.create_todo(todo_params) do&lt;br /&gt;
        {:ok, _todo} -&amp;gt;&lt;br /&gt;
          {:noreply, socket &lt;br /&gt;
          |&amp;gt; put_flash(:info, &amp;quot;User created successfully.&amp;quot;) &lt;br /&gt;
          |&amp;gt; redirect(to: &amp;quot;/&amp;quot;)}&lt;br /&gt;
&lt;br /&gt;
        {:error, %Ecto.Changeset{} = changeset} -&amp;gt;&lt;br /&gt;
          {:noreply, assign(socket, changeset: changeset)}&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Troubleshooting ChangeSets Example ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.SandLive do&lt;br /&gt;
    use AppWeb, :live_view&lt;br /&gt;
  &lt;br /&gt;
    alias App.Todos&lt;br /&gt;
    alias App.Todos.Todo&lt;br /&gt;
  &lt;br /&gt;
    def mount(_params, _session, socket) do&lt;br /&gt;
      # Create an empty changeset for the form&lt;br /&gt;
      changeset = Todos.change_todo(%Todo{})&lt;br /&gt;
      # Initialize debug_info to an empty map&lt;br /&gt;
      {:ok, assign(socket, data: &amp;quot;some data&amp;quot;, changeset: changeset, debug_info: %{})}&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    def render(assigns) do&lt;br /&gt;
      ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
      &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;.form :let={f} for={@changeset} phx-submit=&amp;quot;save&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;.input field={f[:name]} type=&amp;quot;text&amp;quot; label=&amp;quot;Name&amp;quot; /&amp;gt;&lt;br /&gt;
          &amp;lt;.button&amp;gt;SAVE&amp;lt;/.button&amp;gt;&lt;br /&gt;
        &amp;lt;/.form&amp;gt;&lt;br /&gt;
        &amp;lt;p&amp;gt;{@data}&amp;lt;/p&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
        &amp;lt;%= if map_size(@debug_info) &amp;gt; 0 do %&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;mt-4&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;h3 class=&amp;quot;text-lg font-bold&amp;quot;&amp;gt;Debug Info:&amp;lt;/h3&amp;gt;&lt;br /&gt;
            &amp;lt;pre class=&amp;quot;bg-gray-100 p-2 text-sm overflow-auto&amp;quot;&amp;gt;&amp;lt;%= inspect(@debug_info, pretty: true) %&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
          &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;% end %&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
      &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    def handle_event(&amp;quot;save&amp;quot;, %{&amp;quot;todo&amp;quot; =&amp;gt; todo_params} = params, socket) do&lt;br /&gt;
      # Log the raw params first&lt;br /&gt;
      IO.inspect(params, label: &amp;quot;Raw form parameters&amp;quot;)&lt;br /&gt;
      &lt;br /&gt;
      # Create a changeset without saving (for inspection)&lt;br /&gt;
      inspection_changeset = Todo.changeset(%Todo{}, todo_params)&lt;br /&gt;
      IO.inspect(inspection_changeset, label: &amp;quot;Changeset before save&amp;quot;)&lt;br /&gt;
      &lt;br /&gt;
      # Note the cast fields&lt;br /&gt;
      IO.inspect(inspection_changeset.changes, label: &amp;quot;Fields that will change&amp;quot;)&lt;br /&gt;
      &lt;br /&gt;
      # Note any errors that would occur&lt;br /&gt;
      IO.inspect(inspection_changeset.errors, label: &amp;quot;Validation errors&amp;quot;)&lt;br /&gt;
      &lt;br /&gt;
      # Now proceed with the actual save&lt;br /&gt;
      result = Todos.create_todo(todo_params)&lt;br /&gt;
      &lt;br /&gt;
      case result do&lt;br /&gt;
        {:ok, todo} -&amp;gt;&lt;br /&gt;
          # Log the created record&lt;br /&gt;
          IO.inspect(todo, label: &amp;quot;Created todo&amp;quot;)&lt;br /&gt;
          &lt;br /&gt;
          {:noreply,&lt;br /&gt;
           socket&lt;br /&gt;
           |&amp;gt; assign(debug_info: %{&lt;br /&gt;
              raw_params: params,&lt;br /&gt;
              changeset: inspection_changeset,&lt;br /&gt;
              changes: inspection_changeset.changes,&lt;br /&gt;
              errors: inspection_changeset.errors,&lt;br /&gt;
              created_record: todo&lt;br /&gt;
           })&lt;br /&gt;
           |&amp;gt; put_flash(:info, &amp;quot;User created successfully.&amp;quot;)&lt;br /&gt;
           |&amp;gt; redirect(to: &amp;quot;/sandbox&amp;quot;)}&lt;br /&gt;
  &lt;br /&gt;
        {:error, changeset} -&amp;gt;&lt;br /&gt;
          # Log the error changeset&lt;br /&gt;
          IO.inspect(changeset, label: &amp;quot;Error changeset&amp;quot;)&lt;br /&gt;
          &lt;br /&gt;
          {:noreply, &lt;br /&gt;
           socket &lt;br /&gt;
           |&amp;gt; assign(changeset: changeset, debug_info: %{&lt;br /&gt;
              raw_params: params,&lt;br /&gt;
              error_changeset: changeset,&lt;br /&gt;
              errors: changeset.errors&lt;br /&gt;
           })&lt;br /&gt;
           |&amp;gt; put_flash(:error, &amp;quot;Failed to create user.&amp;quot;)}&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>http://elixirblocks.com/index.php?title=Understanding_Forms_and_Changesets&amp;diff=1891</id>
		<title>Understanding Forms and Changesets</title>
		<link rel="alternate" type="text/html" href="http://elixirblocks.com/index.php?title=Understanding_Forms_and_Changesets&amp;diff=1891"/>
		<updated>2025-03-23T02:28:03Z</updated>

		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{In_progress}}&lt;br /&gt;
&lt;br /&gt;
This tutorial assumes you have a basic understanding of Elixir and that you have explored Phoenix. It also assumes that you understand HTML forms. &lt;br /&gt;
&lt;br /&gt;
The methodology of this tutorial includes converting a conventional HTML form into a Phoenix template that uses Elixir to communicate with back end code. You also learn how changesets integrate with controllers. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Getting Started=&lt;br /&gt;
&lt;br /&gt;
To begin, create a new empty Phoenix app named app. If you do not know how to do that follow this tutorial:&lt;br /&gt;
&lt;br /&gt;
[[How to Create an Empty Phoenix Application|How to Create an Empty Phoenix Application]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Creating an HTML Form and Post Request==&lt;br /&gt;
&lt;br /&gt;
In the [[router]] create these two routes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  scope &amp;quot;/&amp;quot;, AppWeb do&lt;br /&gt;
    pipe_through :browser&lt;br /&gt;
&lt;br /&gt;
    get &amp;quot;/&amp;quot;, PageController, :index       # First route&lt;br /&gt;
    post &amp;quot;/create&amp;quot;, PageController, :new  # Second route&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Place the code below in a file named  '''page_controller.ex'''. Place the file in the controller directory.&lt;br /&gt;
&lt;br /&gt;
'''app/lib/app_web/controllers/page_controller.ex'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.PageController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  def index(conn, params) do&lt;br /&gt;
    IO.inspect params&lt;br /&gt;
    csrf_token = Plug.CSRFProtection.get_csrf_token()&lt;br /&gt;
    render(conn, :index, data: &amp;quot;Hello World&amp;quot;,form: %{},csrf_token: csrf_token)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def new(conn, params) do&lt;br /&gt;
      IO.inspect params&lt;br /&gt;
      redirect(conn, to: &amp;quot;/&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In the controllers directory create a file named '''page_html.ex'''&lt;br /&gt;
&lt;br /&gt;
In this file, copy this code.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageHTML do&lt;br /&gt;
  use AppWeb, :html&lt;br /&gt;
&lt;br /&gt;
  embed_templates &amp;quot;page_html/*&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In the controllers directory create another directory named '''page_html''' (technically you can place this directory outside the controllers and it will still work).&lt;br /&gt;
&lt;br /&gt;
'''app/lib/app_web/controllers/page_html'''&lt;br /&gt;
&lt;br /&gt;
This directory will contain heex templates for the PageController.&lt;br /&gt;
&lt;br /&gt;
In the page_html directory place a file named '''index.html.heex'''.&lt;br /&gt;
&lt;br /&gt;
Inside the file copy the following code.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;%=@data%&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;form method=&amp;quot;POST&amp;quot; action=&amp;quot;/create&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;_csrf_token&amp;quot; value={@csrf_token} /&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;example&amp;quot; /&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;submit&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;/form&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Run the server:   mix phx.server&lt;br /&gt;
&lt;br /&gt;
You should see a form field and a submit button with the text &amp;quot;Hello World&amp;quot; above them. Type into the form and submit it, the terminal will display your input. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you replace the form with the built in form helper, you can remove the csrf code. CSRF protection comes built in with the form helper. Delete or comment out the code in index.html.heex and replace it with the code below.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;.form :let={f} action={~p&amp;quot;/create&amp;quot;}&amp;gt;&lt;br /&gt;
    &amp;lt;.input field={f[:x]} name=&amp;quot;submitted-data&amp;quot; /&amp;gt;&lt;br /&gt;
  &amp;lt;/.form&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Delete or comment out the code in page_controller.ex and replace it with the code below.&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  def index(conn, params) do&lt;br /&gt;
    IO.inspect params&lt;br /&gt;
    render(conn, :index, data: &amp;quot;Hello World&amp;quot;,form: %{})&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def new(conn, params) do&lt;br /&gt;
      IO.inspect params&lt;br /&gt;
      redirect(conn, to: &amp;quot;/&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When you run the server and visit the landing page, you should see the page render without error.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Form Changesets===&lt;br /&gt;
Without Changesets we have these two problems:&lt;br /&gt;
&lt;br /&gt;
* We lose what we typed.&lt;br /&gt;
* The app doesn’t tell us what our errors were.&lt;br /&gt;
&lt;br /&gt;
Changesets solve both of these problems.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Schema and Live View Form==&lt;br /&gt;
&lt;br /&gt;
===Schema===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule App.Todo do&lt;br /&gt;
  use Ecto.Schema&lt;br /&gt;
  import Ecto.Changeset&lt;br /&gt;
&lt;br /&gt;
  schema &amp;quot;todos&amp;quot; do&lt;br /&gt;
    field :description, :string&lt;br /&gt;
    field :title, :string&lt;br /&gt;
&lt;br /&gt;
    timestamps(type: :utc_datetime)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  @doc false&lt;br /&gt;
  def changeset(todo, attrs) do&lt;br /&gt;
    todo&lt;br /&gt;
    |&amp;gt; cast(attrs, [:title, :description])&lt;br /&gt;
    |&amp;gt; validate_required([:title, :description])&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Live View Form ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  alias App.Todo&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    changeset = Todo.changeset(%Todo{}, %{})&lt;br /&gt;
    &lt;br /&gt;
    {:ok,&lt;br /&gt;
     socket&lt;br /&gt;
     |&amp;gt; assign(:changeset, changeset)&lt;br /&gt;
     |&amp;gt; assign(:todo, %Todo{})&lt;br /&gt;
     |&amp;gt; assign(:saved, false)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;save&amp;quot;, %{&amp;quot;todo&amp;quot; =&amp;gt; todo_params}, socket) do&lt;br /&gt;
   case save_todo(todo_params) do&lt;br /&gt;
     {:ok, _todo} -&amp;gt;&lt;br /&gt;
       {:noreply,&lt;br /&gt;
        socket&lt;br /&gt;
        |&amp;gt; assign(:changeset, Todo.changeset(%Todo{}, %{}))&lt;br /&gt;
        |&amp;gt; assign(:saved, true)}&lt;br /&gt;
&lt;br /&gt;
     {:error, %Ecto.Changeset{} = changeset} -&amp;gt;&lt;br /&gt;
       {:noreply, assign(socket, changeset: changeset, saved: false)}&lt;br /&gt;
   end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 defp save_todo(todo_params) do&lt;br /&gt;
   %Todo{}&lt;br /&gt;
   |&amp;gt; Todo.changeset(todo_params)&lt;br /&gt;
   |&amp;gt; App.Repo.insert()&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    &amp;lt;.form :let={f} for={@changeset} phx-submit=&amp;quot;save&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;.input field={f[:title]} type=&amp;quot;text&amp;quot; label=&amp;quot;Title&amp;quot; /&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;.input field={f[:description]} type=&amp;quot;textarea&amp;quot; label=&amp;quot;Description&amp;quot; /&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;.button&amp;gt;Save&amp;lt;/.button&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;/.form&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;%= if @saved do %&amp;gt;&lt;br /&gt;
      &amp;lt;div class=&amp;quot;alert alert-info&amp;quot;&amp;gt;&lt;br /&gt;
        Todo saved successfully!&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://adopt-liveview.lubien.dev/guides/simple-forms-with-ecto/en&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===A Working Form Without Changesets ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.SandLive do &lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
&lt;br /&gt;
  alias App.Todos&lt;br /&gt;
  alias App.Todos.Todo&lt;br /&gt;
&lt;br /&gt;
  def mount(params,session,socket) do  &lt;br /&gt;
    &lt;br /&gt;
    {:ok, assign(socket, data: &amp;quot;some data&amp;quot;)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    &lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;  &lt;br /&gt;
        &amp;lt;div&amp;gt;&lt;br /&gt;
            &amp;lt;.form  :let={f}  phx-submit=&amp;quot;save&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;.input field={f[:name]} type=&amp;quot;text&amp;quot; label=&amp;quot;Name&amp;quot; value=&amp;quot;&amp;quot; /&amp;gt;&lt;br /&gt;
                &amp;lt;.button&amp;gt;SAVE &amp;lt;/.button&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
            &amp;lt;/.form&amp;gt;&lt;br /&gt;
&lt;br /&gt;
          {@data}&lt;br /&gt;
&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
      &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;save&amp;quot;,params, socket) do &lt;br /&gt;
      IO.inspect params&lt;br /&gt;
&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Same Example Without Changeset and With Flash Message ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.SandLive do &lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
&lt;br /&gt;
  alias App.Todos&lt;br /&gt;
  alias App.Todos.Todo&lt;br /&gt;
&lt;br /&gt;
  def mount(params,session,socket) do  &lt;br /&gt;
    {:ok, assign(socket, data: &amp;quot;some data&amp;quot;)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    &lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;  &lt;br /&gt;
        &amp;lt;div&amp;gt;&lt;br /&gt;
            &amp;lt;.form  :let={f}  phx-submit=&amp;quot;save&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;.input field={f[:name]} type=&amp;quot;text&amp;quot; label=&amp;quot;Name&amp;quot; value=&amp;quot;&amp;quot; /&amp;gt;&lt;br /&gt;
                &amp;lt;.button&amp;gt;SAVE &amp;lt;/.button&amp;gt;&lt;br /&gt;
            &amp;lt;/.form&amp;gt;&lt;br /&gt;
          {@data}&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
      &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;save&amp;quot;, %{&amp;quot;name&amp;quot; =&amp;gt; name} = params, socket) do &lt;br /&gt;
    IO.inspect params&lt;br /&gt;
    &lt;br /&gt;
    # Create todo without using a changeset directly&lt;br /&gt;
    result = Todos.create_todo(%{&amp;quot;name&amp;quot; =&amp;gt; name})&lt;br /&gt;
    &lt;br /&gt;
    case result do&lt;br /&gt;
      {:ok, _todo} -&amp;gt;&lt;br /&gt;
        {:noreply, socket &lt;br /&gt;
        |&amp;gt; put_flash(:info, &amp;quot;User created successfully.&amp;quot;) &lt;br /&gt;
        |&amp;gt; redirect(to: &amp;quot;/&amp;quot;)}&lt;br /&gt;
      {:error, _reason} -&amp;gt;&lt;br /&gt;
        {:noreply, socket |&amp;gt; put_flash(:error, &amp;quot;Failed to create user.&amp;quot;)}&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===The Same Example with a Changeset ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
    use AppWeb, :live_view&lt;br /&gt;
  &lt;br /&gt;
    alias App.Todos&lt;br /&gt;
    alias App.Todos.Todo&lt;br /&gt;
  &lt;br /&gt;
    def mount(_params, _session, socket) do&lt;br /&gt;
      changeset = Todos.change_todo(%Todo{})&lt;br /&gt;
      {:ok, assign(socket, changeset: changeset)}&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    def render(assigns) do&lt;br /&gt;
      ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
      &amp;lt;h1&amp;gt;Create User&amp;lt;/h1&amp;gt;&lt;br /&gt;
      &amp;lt;.form :let={f} for={@changeset} phx-submit=&amp;quot;save&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;.input field={f[:name]} type=&amp;quot;text&amp;quot; label=&amp;quot;Name&amp;quot; /&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
      &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;.button&amp;gt;Save&amp;lt;/.button&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;/.form&amp;gt;&lt;br /&gt;
      &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    def handle_event(&amp;quot;save&amp;quot;, %{&amp;quot;todo&amp;quot; =&amp;gt; todo_params}, socket) do&lt;br /&gt;
&lt;br /&gt;
      result =  Todos.create_todo(todo_params)&lt;br /&gt;
      IO.inspect result&lt;br /&gt;
&lt;br /&gt;
      case Todos.create_todo(todo_params) do&lt;br /&gt;
        {:ok, _todo} -&amp;gt;&lt;br /&gt;
          {:noreply, socket &lt;br /&gt;
          |&amp;gt; put_flash(:info, &amp;quot;User created successfully.&amp;quot;) &lt;br /&gt;
          |&amp;gt; redirect(to: &amp;quot;/&amp;quot;)}&lt;br /&gt;
&lt;br /&gt;
        {:error, %Ecto.Changeset{} = changeset} -&amp;gt;&lt;br /&gt;
          {:noreply, assign(socket, changeset: changeset)}&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>http://elixirblocks.com/index.php?title=Understanding_Forms_and_Changesets&amp;diff=1890</id>
		<title>Understanding Forms and Changesets</title>
		<link rel="alternate" type="text/html" href="http://elixirblocks.com/index.php?title=Understanding_Forms_and_Changesets&amp;diff=1890"/>
		<updated>2025-03-22T22:07:29Z</updated>

		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{In_progress}}&lt;br /&gt;
&lt;br /&gt;
This tutorial assumes you have a basic understanding of Elixir and that you have explored Phoenix. It also assumes that you understand HTML forms. &lt;br /&gt;
&lt;br /&gt;
The methodology of this tutorial includes converting a conventional HTML form into a Phoenix template that uses Elixir to communicate with back end code. You also learn how changesets integrate with controllers. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Getting Started=&lt;br /&gt;
&lt;br /&gt;
To begin, create a new empty Phoenix app named app. If you do not know how to do that follow this tutorial:&lt;br /&gt;
&lt;br /&gt;
[[How to Create an Empty Phoenix Application|How to Create an Empty Phoenix Application]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Creating an HTML Form and Post Request==&lt;br /&gt;
&lt;br /&gt;
In the [[router]] create these two routes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  scope &amp;quot;/&amp;quot;, AppWeb do&lt;br /&gt;
    pipe_through :browser&lt;br /&gt;
&lt;br /&gt;
    get &amp;quot;/&amp;quot;, PageController, :index       # First route&lt;br /&gt;
    post &amp;quot;/create&amp;quot;, PageController, :new  # Second route&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Place the code below in a file named  '''page_controller.ex'''. Place the file in the controller directory.&lt;br /&gt;
&lt;br /&gt;
'''app/lib/app_web/controllers/page_controller.ex'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.PageController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  def index(conn, params) do&lt;br /&gt;
    IO.inspect params&lt;br /&gt;
    csrf_token = Plug.CSRFProtection.get_csrf_token()&lt;br /&gt;
    render(conn, :index, data: &amp;quot;Hello World&amp;quot;,form: %{},csrf_token: csrf_token)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def new(conn, params) do&lt;br /&gt;
      IO.inspect params&lt;br /&gt;
      redirect(conn, to: &amp;quot;/&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In the controllers directory create a file named '''page_html.ex'''&lt;br /&gt;
&lt;br /&gt;
In this file, copy this code.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageHTML do&lt;br /&gt;
  use AppWeb, :html&lt;br /&gt;
&lt;br /&gt;
  embed_templates &amp;quot;page_html/*&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In the controllers directory create another directory named '''page_html''' (technically you can place this directory outside the controllers and it will still work).&lt;br /&gt;
&lt;br /&gt;
'''app/lib/app_web/controllers/page_html'''&lt;br /&gt;
&lt;br /&gt;
This directory will contain heex templates for the PageController.&lt;br /&gt;
&lt;br /&gt;
In the page_html directory place a file named '''index.html.heex'''.&lt;br /&gt;
&lt;br /&gt;
Inside the file copy the following code.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;%=@data%&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;form method=&amp;quot;POST&amp;quot; action=&amp;quot;/create&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;_csrf_token&amp;quot; value={@csrf_token} /&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;example&amp;quot; /&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;submit&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;/form&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Run the server:   mix phx.server&lt;br /&gt;
&lt;br /&gt;
You should see a form field and a submit button with the text &amp;quot;Hello World&amp;quot; above them. Type into the form and submit it, the terminal will display your input. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you replace the form with the built in form helper, you can remove the csrf code. CSRF protection comes built in with the form helper. Delete or comment out the code in index.html.heex and replace it with the code below.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;.form :let={f} action={~p&amp;quot;/create&amp;quot;}&amp;gt;&lt;br /&gt;
    &amp;lt;.input field={f[:x]} name=&amp;quot;submitted-data&amp;quot; /&amp;gt;&lt;br /&gt;
  &amp;lt;/.form&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Delete or comment out the code in page_controller.ex and replace it with the code below.&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  def index(conn, params) do&lt;br /&gt;
    IO.inspect params&lt;br /&gt;
    render(conn, :index, data: &amp;quot;Hello World&amp;quot;,form: %{})&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def new(conn, params) do&lt;br /&gt;
      IO.inspect params&lt;br /&gt;
      redirect(conn, to: &amp;quot;/&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When you run the server and visit the landing page, you should see the page render without error.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Form Changesets===&lt;br /&gt;
Without Changesets we have these two problems:&lt;br /&gt;
&lt;br /&gt;
* We lose what we typed.&lt;br /&gt;
* The app doesn’t tell us what our errors were.&lt;br /&gt;
&lt;br /&gt;
Changesets solve both of these problems.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Schema and Live View Form==&lt;br /&gt;
&lt;br /&gt;
===Schema===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule App.Todo do&lt;br /&gt;
  use Ecto.Schema&lt;br /&gt;
  import Ecto.Changeset&lt;br /&gt;
&lt;br /&gt;
  schema &amp;quot;todos&amp;quot; do&lt;br /&gt;
    field :description, :string&lt;br /&gt;
    field :title, :string&lt;br /&gt;
&lt;br /&gt;
    timestamps(type: :utc_datetime)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  @doc false&lt;br /&gt;
  def changeset(todo, attrs) do&lt;br /&gt;
    todo&lt;br /&gt;
    |&amp;gt; cast(attrs, [:title, :description])&lt;br /&gt;
    |&amp;gt; validate_required([:title, :description])&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Live View Form ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  alias App.Todo&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    changeset = Todo.changeset(%Todo{}, %{})&lt;br /&gt;
    &lt;br /&gt;
    {:ok,&lt;br /&gt;
     socket&lt;br /&gt;
     |&amp;gt; assign(:changeset, changeset)&lt;br /&gt;
     |&amp;gt; assign(:todo, %Todo{})&lt;br /&gt;
     |&amp;gt; assign(:saved, false)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;save&amp;quot;, %{&amp;quot;todo&amp;quot; =&amp;gt; todo_params}, socket) do&lt;br /&gt;
   case save_todo(todo_params) do&lt;br /&gt;
     {:ok, _todo} -&amp;gt;&lt;br /&gt;
       {:noreply,&lt;br /&gt;
        socket&lt;br /&gt;
        |&amp;gt; assign(:changeset, Todo.changeset(%Todo{}, %{}))&lt;br /&gt;
        |&amp;gt; assign(:saved, true)}&lt;br /&gt;
&lt;br /&gt;
     {:error, %Ecto.Changeset{} = changeset} -&amp;gt;&lt;br /&gt;
       {:noreply, assign(socket, changeset: changeset, saved: false)}&lt;br /&gt;
   end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 defp save_todo(todo_params) do&lt;br /&gt;
   %Todo{}&lt;br /&gt;
   |&amp;gt; Todo.changeset(todo_params)&lt;br /&gt;
   |&amp;gt; App.Repo.insert()&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    &amp;lt;.form :let={f} for={@changeset} phx-submit=&amp;quot;save&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;.input field={f[:title]} type=&amp;quot;text&amp;quot; label=&amp;quot;Title&amp;quot; /&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;.input field={f[:description]} type=&amp;quot;textarea&amp;quot; label=&amp;quot;Description&amp;quot; /&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;.button&amp;gt;Save&amp;lt;/.button&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;/.form&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;%= if @saved do %&amp;gt;&lt;br /&gt;
      &amp;lt;div class=&amp;quot;alert alert-info&amp;quot;&amp;gt;&lt;br /&gt;
        Todo saved successfully!&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://adopt-liveview.lubien.dev/guides/simple-forms-with-ecto/en&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===A Working Form Without Changesets ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.SandLive do &lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
&lt;br /&gt;
  alias App.Todos&lt;br /&gt;
  alias App.Todos.Todo&lt;br /&gt;
&lt;br /&gt;
  def mount(params,session,socket) do  &lt;br /&gt;
    &lt;br /&gt;
    {:ok, assign(socket, data: &amp;quot;some data&amp;quot;)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    &lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;  &lt;br /&gt;
        &amp;lt;div&amp;gt;&lt;br /&gt;
            &amp;lt;.form  :let={f}  phx-submit=&amp;quot;save&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;.input field={f[:name]} type=&amp;quot;text&amp;quot; label=&amp;quot;Name&amp;quot; value=&amp;quot;&amp;quot; /&amp;gt;&lt;br /&gt;
                &amp;lt;.button&amp;gt;SAVE &amp;lt;/.button&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
            &amp;lt;/.form&amp;gt;&lt;br /&gt;
&lt;br /&gt;
          {@data}&lt;br /&gt;
&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
      &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;save&amp;quot;,params, socket) do &lt;br /&gt;
      IO.inspect params&lt;br /&gt;
&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===The Same Example with a Changeset ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
    use AppWeb, :live_view&lt;br /&gt;
  &lt;br /&gt;
    alias App.Todos&lt;br /&gt;
    alias App.Todos.Todo&lt;br /&gt;
  &lt;br /&gt;
    def mount(_params, _session, socket) do&lt;br /&gt;
      changeset = Todos.change_todo(%Todo{})&lt;br /&gt;
      {:ok, assign(socket, changeset: changeset)}&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    def render(assigns) do&lt;br /&gt;
      ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
      &amp;lt;h1&amp;gt;Create User&amp;lt;/h1&amp;gt;&lt;br /&gt;
      &amp;lt;.form :let={f} for={@changeset} phx-submit=&amp;quot;save&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;.input field={f[:name]} type=&amp;quot;text&amp;quot; label=&amp;quot;Name&amp;quot; /&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
      &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;.button&amp;gt;Save&amp;lt;/.button&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;/.form&amp;gt;&lt;br /&gt;
      &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    def handle_event(&amp;quot;save&amp;quot;, %{&amp;quot;todo&amp;quot; =&amp;gt; todo_params}, socket) do&lt;br /&gt;
&lt;br /&gt;
      result =  Todos.create_todo(todo_params)&lt;br /&gt;
      IO.inspect result&lt;br /&gt;
&lt;br /&gt;
      case Todos.create_todo(todo_params) do&lt;br /&gt;
        {:ok, _todo} -&amp;gt;&lt;br /&gt;
          {:noreply, socket &lt;br /&gt;
          |&amp;gt; put_flash(:info, &amp;quot;User created successfully.&amp;quot;) &lt;br /&gt;
          |&amp;gt; redirect(to: &amp;quot;/&amp;quot;)}&lt;br /&gt;
&lt;br /&gt;
        {:error, %Ecto.Changeset{} = changeset} -&amp;gt;&lt;br /&gt;
          {:noreply, assign(socket, changeset: changeset)}&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>http://elixirblocks.com/index.php?title=Understanding_Forms_and_Changesets&amp;diff=1889</id>
		<title>Understanding Forms and Changesets</title>
		<link rel="alternate" type="text/html" href="http://elixirblocks.com/index.php?title=Understanding_Forms_and_Changesets&amp;diff=1889"/>
		<updated>2025-03-22T22:06:59Z</updated>

		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{In_progress}}&lt;br /&gt;
&lt;br /&gt;
This tutorial assumes you have a basic understanding of Elixir and that you have explored Phoenix. It also assumes that you understand HTML forms. &lt;br /&gt;
&lt;br /&gt;
The methodology of this tutorial includes converting a conventional HTML form into a Phoenix template that uses Elixir to communicate with back end code. You also learn how changesets integrate with controllers. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Getting Started=&lt;br /&gt;
&lt;br /&gt;
To begin, create a new empty Phoenix app named app. If you do not know how to do that follow this tutorial:&lt;br /&gt;
&lt;br /&gt;
[[How to Create an Empty Phoenix Application|How to Create an Empty Phoenix Application]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Creating an HTML Form and Post Request==&lt;br /&gt;
&lt;br /&gt;
In the [[router]] create these two routes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  scope &amp;quot;/&amp;quot;, AppWeb do&lt;br /&gt;
    pipe_through :browser&lt;br /&gt;
&lt;br /&gt;
    get &amp;quot;/&amp;quot;, PageController, :index       # First route&lt;br /&gt;
    post &amp;quot;/create&amp;quot;, PageController, :new  # Second route&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Place the code below in a file named  '''page_controller.ex'''. Place the file in the controller directory.&lt;br /&gt;
&lt;br /&gt;
'''app/lib/app_web/controllers/page_controller.ex'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.PageController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  def index(conn, params) do&lt;br /&gt;
    IO.inspect params&lt;br /&gt;
    csrf_token = Plug.CSRFProtection.get_csrf_token()&lt;br /&gt;
    render(conn, :index, data: &amp;quot;Hello World&amp;quot;,form: %{},csrf_token: csrf_token)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def new(conn, params) do&lt;br /&gt;
      IO.inspect params&lt;br /&gt;
      redirect(conn, to: &amp;quot;/&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In the controllers directory create a file named '''page_html.ex'''&lt;br /&gt;
&lt;br /&gt;
In this file, copy this code.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageHTML do&lt;br /&gt;
  use AppWeb, :html&lt;br /&gt;
&lt;br /&gt;
  embed_templates &amp;quot;page_html/*&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In the controllers directory create another directory named '''page_html''' (technically you can place this directory outside the controllers and it will still work).&lt;br /&gt;
&lt;br /&gt;
'''app/lib/app_web/controllers/page_html'''&lt;br /&gt;
&lt;br /&gt;
This directory will contain heex templates for the PageController.&lt;br /&gt;
&lt;br /&gt;
In the page_html directory place a file named '''index.html.heex'''.&lt;br /&gt;
&lt;br /&gt;
Inside the file copy the following code.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;%=@data%&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;form method=&amp;quot;POST&amp;quot; action=&amp;quot;/create&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;_csrf_token&amp;quot; value={@csrf_token} /&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;example&amp;quot; /&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;submit&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;/form&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Run the server:   mix phx.server&lt;br /&gt;
&lt;br /&gt;
You should see a form field and a submit button with the text &amp;quot;Hello World&amp;quot; above them. Type into the form and submit it, the terminal will display your input. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you replace the form with the built in form helper, you can remove the csrf code. CSRF protection comes built in with the form helper. Delete or comment out the code in index.html.heex and replace it with the code below.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;.form :let={f} action={~p&amp;quot;/create&amp;quot;}&amp;gt;&lt;br /&gt;
    &amp;lt;.input field={f[:x]} name=&amp;quot;submitted-data&amp;quot; /&amp;gt;&lt;br /&gt;
  &amp;lt;/.form&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Delete or comment out the code in page_controller.ex and replace it with the code below.&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  def index(conn, params) do&lt;br /&gt;
    IO.inspect params&lt;br /&gt;
    render(conn, :index, data: &amp;quot;Hello World&amp;quot;,form: %{})&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def new(conn, params) do&lt;br /&gt;
      IO.inspect params&lt;br /&gt;
      redirect(conn, to: &amp;quot;/&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When you run the server and visit the landing page, you should see the page render without error.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Form Changesets===&lt;br /&gt;
Without Changesets we have these two problems:&lt;br /&gt;
&lt;br /&gt;
* We lose what we typed.&lt;br /&gt;
* The app doesn’t tell us what our errors were.&lt;br /&gt;
&lt;br /&gt;
Changesets solve both of these problems.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Schema and Live View Form==&lt;br /&gt;
&lt;br /&gt;
===Schema===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule App.Todo do&lt;br /&gt;
  use Ecto.Schema&lt;br /&gt;
  import Ecto.Changeset&lt;br /&gt;
&lt;br /&gt;
  schema &amp;quot;todos&amp;quot; do&lt;br /&gt;
    field :description, :string&lt;br /&gt;
    field :title, :string&lt;br /&gt;
&lt;br /&gt;
    timestamps(type: :utc_datetime)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  @doc false&lt;br /&gt;
  def changeset(todo, attrs) do&lt;br /&gt;
    todo&lt;br /&gt;
    |&amp;gt; cast(attrs, [:title, :description])&lt;br /&gt;
    |&amp;gt; validate_required([:title, :description])&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Live View Form ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  alias App.Todo&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    changeset = Todo.changeset(%Todo{}, %{})&lt;br /&gt;
    &lt;br /&gt;
    {:ok,&lt;br /&gt;
     socket&lt;br /&gt;
     |&amp;gt; assign(:changeset, changeset)&lt;br /&gt;
     |&amp;gt; assign(:todo, %Todo{})&lt;br /&gt;
     |&amp;gt; assign(:saved, false)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;save&amp;quot;, %{&amp;quot;todo&amp;quot; =&amp;gt; todo_params}, socket) do&lt;br /&gt;
   case save_todo(todo_params) do&lt;br /&gt;
     {:ok, _todo} -&amp;gt;&lt;br /&gt;
       {:noreply,&lt;br /&gt;
        socket&lt;br /&gt;
        |&amp;gt; assign(:changeset, Todo.changeset(%Todo{}, %{}))&lt;br /&gt;
        |&amp;gt; assign(:saved, true)}&lt;br /&gt;
&lt;br /&gt;
     {:error, %Ecto.Changeset{} = changeset} -&amp;gt;&lt;br /&gt;
       {:noreply, assign(socket, changeset: changeset, saved: false)}&lt;br /&gt;
   end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 defp save_todo(todo_params) do&lt;br /&gt;
   %Todo{}&lt;br /&gt;
   |&amp;gt; Todo.changeset(todo_params)&lt;br /&gt;
   |&amp;gt; App.Repo.insert()&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    &amp;lt;.form :let={f} for={@changeset} phx-submit=&amp;quot;save&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;.input field={f[:title]} type=&amp;quot;text&amp;quot; label=&amp;quot;Title&amp;quot; /&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;.input field={f[:description]} type=&amp;quot;textarea&amp;quot; label=&amp;quot;Description&amp;quot; /&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;.button&amp;gt;Save&amp;lt;/.button&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;/.form&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;%= if @saved do %&amp;gt;&lt;br /&gt;
      &amp;lt;div class=&amp;quot;alert alert-info&amp;quot;&amp;gt;&lt;br /&gt;
        Todo saved successfully!&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://adopt-liveview.lubien.dev/guides/simple-forms-with-ecto/en&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===A Working Form Without Changesets ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.SandLive do &lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
&lt;br /&gt;
  alias App.Todos&lt;br /&gt;
  alias App.Todos.Todo&lt;br /&gt;
&lt;br /&gt;
  def mount(params,session,socket) do  &lt;br /&gt;
    &lt;br /&gt;
    {:ok, assign(socket, data: &amp;quot;some data&amp;quot;)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    &lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;  &lt;br /&gt;
        &amp;lt;div&amp;gt;&lt;br /&gt;
            &amp;lt;.form  :let={f}  phx-submit=&amp;quot;save&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;.input field={f[:name]} type=&amp;quot;text&amp;quot; label=&amp;quot;Name&amp;quot; value=&amp;quot;&amp;quot; /&amp;gt;&lt;br /&gt;
                &amp;lt;.button&amp;gt;SAVE &amp;lt;/.button&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
            &amp;lt;/.form&amp;gt;&lt;br /&gt;
&lt;br /&gt;
          {@data}&lt;br /&gt;
&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
      &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;save&amp;quot;,params, socket) do &lt;br /&gt;
      IO.inspect params&lt;br /&gt;
&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===The Same Example with a Changeset ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
    use AppWeb, :live_view&lt;br /&gt;
  &lt;br /&gt;
    alias App.Todos&lt;br /&gt;
    alias App.Todos.Todo&lt;br /&gt;
  &lt;br /&gt;
    def mount(_params, _session, socket) do&lt;br /&gt;
      changeset = Todos.change_todo(%Todo{})&lt;br /&gt;
      {:ok, assign(socket, changeset: changeset)}&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    def render(assigns) do&lt;br /&gt;
      ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
      &amp;lt;h1&amp;gt;Create User&amp;lt;/h1&amp;gt;&lt;br /&gt;
      &amp;lt;.form :let={f} for={@changeset} phx-submit=&amp;quot;save&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;.input field={f[:name]} type=&amp;quot;text&amp;quot; label=&amp;quot;Name&amp;quot; /&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
      &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;.button&amp;gt;Save&amp;lt;/.button&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;/.form&amp;gt;&lt;br /&gt;
      &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    def handle_event(&amp;quot;save&amp;quot;, %{&amp;quot;todo&amp;quot; =&amp;gt; todo_params}, socket) do&lt;br /&gt;
&lt;br /&gt;
      result =  Todos.create_todo(todo_params)&lt;br /&gt;
      IO.inspect result&lt;br /&gt;
&lt;br /&gt;
      case Todos.create_todo(todo_params) do&lt;br /&gt;
        {:ok, _todo} -&amp;gt;&lt;br /&gt;
          {:noreply, socket &lt;br /&gt;
          |&amp;gt; put_flash(:info, &amp;quot;User created successfully.&amp;quot;) &lt;br /&gt;
          |&amp;gt; redirect(to: &amp;quot;/&amp;quot;)}&lt;br /&gt;
&lt;br /&gt;
        {:error, %Ecto.Changeset{} = changeset} -&amp;gt;&lt;br /&gt;
          {:noreply, assign(socket, changeset: changeset)}&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>http://elixirblocks.com/index.php?title=Understanding_Forms_and_Changesets&amp;diff=1888</id>
		<title>Understanding Forms and Changesets</title>
		<link rel="alternate" type="text/html" href="http://elixirblocks.com/index.php?title=Understanding_Forms_and_Changesets&amp;diff=1888"/>
		<updated>2025-03-19T14:08:13Z</updated>

		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{In_progress}}&lt;br /&gt;
&lt;br /&gt;
This tutorial assumes you have a basic understanding of Elixir and that you have explored Phoenix. It also assumes that you understand HTML forms. &lt;br /&gt;
&lt;br /&gt;
The methodology of this tutorial includes converting a conventional HTML form into a Phoenix template that uses Elixir to communicate with back end code. You also learn how changesets integrate with controllers. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Getting Started=&lt;br /&gt;
&lt;br /&gt;
To begin, create a new empty Phoenix app named app. If you do not know how to do that follow this tutorial:&lt;br /&gt;
&lt;br /&gt;
[[How to Create an Empty Phoenix Application|How to Create an Empty Phoenix Application]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Creating an HTML Form and Post Request==&lt;br /&gt;
&lt;br /&gt;
In the [[router]] create these two routes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  scope &amp;quot;/&amp;quot;, AppWeb do&lt;br /&gt;
    pipe_through :browser&lt;br /&gt;
&lt;br /&gt;
    get &amp;quot;/&amp;quot;, PageController, :index       # First route&lt;br /&gt;
    post &amp;quot;/create&amp;quot;, PageController, :new  # Second route&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Place the code below in a file named  '''page_controller.ex'''. Place the file in the controller directory.&lt;br /&gt;
&lt;br /&gt;
'''app/lib/app_web/controllers/page_controller.ex'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.PageController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  def index(conn, params) do&lt;br /&gt;
    IO.inspect params&lt;br /&gt;
    csrf_token = Plug.CSRFProtection.get_csrf_token()&lt;br /&gt;
    render(conn, :index, data: &amp;quot;Hello World&amp;quot;,form: %{},csrf_token: csrf_token)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def new(conn, params) do&lt;br /&gt;
      IO.inspect params&lt;br /&gt;
      redirect(conn, to: &amp;quot;/&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In the controllers directory create a file named '''page_html.ex'''&lt;br /&gt;
&lt;br /&gt;
In this file, copy this code.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageHTML do&lt;br /&gt;
  use AppWeb, :html&lt;br /&gt;
&lt;br /&gt;
  embed_templates &amp;quot;page_html/*&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In the controllers directory create another directory named '''page_html''' (technically you can place this directory outside the controllers and it will still work).&lt;br /&gt;
&lt;br /&gt;
'''app/lib/app_web/controllers/page_html'''&lt;br /&gt;
&lt;br /&gt;
This directory will contain heex templates for the PageController.&lt;br /&gt;
&lt;br /&gt;
In the page_html directory place a file named '''index.html.heex'''.&lt;br /&gt;
&lt;br /&gt;
Inside the file copy the following code.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;%=@data%&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;form method=&amp;quot;POST&amp;quot; action=&amp;quot;/create&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;_csrf_token&amp;quot; value={@csrf_token} /&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;example&amp;quot; /&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;submit&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;/form&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Run the server:   mix phx.server&lt;br /&gt;
&lt;br /&gt;
You should see a form field and a submit button with the text &amp;quot;Hello World&amp;quot; above them. Type into the form and submit it, the terminal will display your input. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you replace the form with the built in form helper, you can remove the csrf code. CSRF protection comes built in with the form helper. Delete or comment out the code in index.html.heex and replace it with the code below.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;.form :let={f} action={~p&amp;quot;/create&amp;quot;}&amp;gt;&lt;br /&gt;
    &amp;lt;.input field={f[:x]} name=&amp;quot;submitted-data&amp;quot; /&amp;gt;&lt;br /&gt;
  &amp;lt;/.form&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Delete or comment out the code in page_controller.ex and replace it with the code below.&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  def index(conn, params) do&lt;br /&gt;
    IO.inspect params&lt;br /&gt;
    render(conn, :index, data: &amp;quot;Hello World&amp;quot;,form: %{})&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def new(conn, params) do&lt;br /&gt;
      IO.inspect params&lt;br /&gt;
      redirect(conn, to: &amp;quot;/&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When you run the server and visit the landing page, you should see the page render without error.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Form Changesets===&lt;br /&gt;
Without Changesets we have these two problems:&lt;br /&gt;
&lt;br /&gt;
* We lose what we typed.&lt;br /&gt;
* The app doesn’t tell us what our errors were.&lt;br /&gt;
&lt;br /&gt;
Changesets solve both of these problems.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Schema and Live View Form==&lt;br /&gt;
&lt;br /&gt;
===Schema===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule App.Todo do&lt;br /&gt;
  use Ecto.Schema&lt;br /&gt;
  import Ecto.Changeset&lt;br /&gt;
&lt;br /&gt;
  schema &amp;quot;todos&amp;quot; do&lt;br /&gt;
    field :description, :string&lt;br /&gt;
    field :title, :string&lt;br /&gt;
&lt;br /&gt;
    timestamps(type: :utc_datetime)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  @doc false&lt;br /&gt;
  def changeset(todo, attrs) do&lt;br /&gt;
    todo&lt;br /&gt;
    |&amp;gt; cast(attrs, [:title, :description])&lt;br /&gt;
    |&amp;gt; validate_required([:title, :description])&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Live View Form ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  alias App.Todo&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    changeset = Todo.changeset(%Todo{}, %{})&lt;br /&gt;
    &lt;br /&gt;
    {:ok,&lt;br /&gt;
     socket&lt;br /&gt;
     |&amp;gt; assign(:changeset, changeset)&lt;br /&gt;
     |&amp;gt; assign(:todo, %Todo{})&lt;br /&gt;
     |&amp;gt; assign(:saved, false)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;save&amp;quot;, %{&amp;quot;todo&amp;quot; =&amp;gt; todo_params}, socket) do&lt;br /&gt;
   case save_todo(todo_params) do&lt;br /&gt;
     {:ok, _todo} -&amp;gt;&lt;br /&gt;
       {:noreply,&lt;br /&gt;
        socket&lt;br /&gt;
        |&amp;gt; assign(:changeset, Todo.changeset(%Todo{}, %{}))&lt;br /&gt;
        |&amp;gt; assign(:saved, true)}&lt;br /&gt;
&lt;br /&gt;
     {:error, %Ecto.Changeset{} = changeset} -&amp;gt;&lt;br /&gt;
       {:noreply, assign(socket, changeset: changeset, saved: false)}&lt;br /&gt;
   end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 defp save_todo(todo_params) do&lt;br /&gt;
   %Todo{}&lt;br /&gt;
   |&amp;gt; Todo.changeset(todo_params)&lt;br /&gt;
   |&amp;gt; App.Repo.insert()&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    &amp;lt;.form :let={f} for={@changeset} phx-submit=&amp;quot;save&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;.input field={f[:title]} type=&amp;quot;text&amp;quot; label=&amp;quot;Title&amp;quot; /&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;.input field={f[:description]} type=&amp;quot;textarea&amp;quot; label=&amp;quot;Description&amp;quot; /&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;.button&amp;gt;Save&amp;lt;/.button&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;/.form&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;%= if @saved do %&amp;gt;&lt;br /&gt;
      &amp;lt;div class=&amp;quot;alert alert-info&amp;quot;&amp;gt;&lt;br /&gt;
        Todo saved successfully!&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://adopt-liveview.lubien.dev/guides/simple-forms-with-ecto/en&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>http://elixirblocks.com/index.php?title=Understanding_Forms_and_Changesets&amp;diff=1887</id>
		<title>Understanding Forms and Changesets</title>
		<link rel="alternate" type="text/html" href="http://elixirblocks.com/index.php?title=Understanding_Forms_and_Changesets&amp;diff=1887"/>
		<updated>2025-03-19T00:50:38Z</updated>

		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{In_progress}}&lt;br /&gt;
&lt;br /&gt;
This tutorial assumes you have a basic understanding of Elixir and that you have explored Phoenix. It also assumes that you understand HTML forms. &lt;br /&gt;
&lt;br /&gt;
The methodology of this tutorial includes converting a conventional HTML form into a Phoenix template that uses Elixir to communicate with back end code. You also learn how changesets integrate with controllers. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Getting Started=&lt;br /&gt;
&lt;br /&gt;
To begin, create a new empty Phoenix app named app. If you do not know how to do that follow this tutorial:&lt;br /&gt;
&lt;br /&gt;
[[How to Create an Empty Phoenix Application|How to Create an Empty Phoenix Application]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Creating an HTML Form and Post Request==&lt;br /&gt;
&lt;br /&gt;
In the [[router]] create these two routes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  scope &amp;quot;/&amp;quot;, AppWeb do&lt;br /&gt;
    pipe_through :browser&lt;br /&gt;
&lt;br /&gt;
    get &amp;quot;/&amp;quot;, PageController, :index       # First route&lt;br /&gt;
    post &amp;quot;/create&amp;quot;, PageController, :new  # Second route&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Place the code below in a file named  '''page_controller.ex'''. Place the file in the controller directory.&lt;br /&gt;
&lt;br /&gt;
'''app/lib/app_web/controllers/page_controller.ex'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.PageController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  def index(conn, params) do&lt;br /&gt;
    IO.inspect params&lt;br /&gt;
    csrf_token = Plug.CSRFProtection.get_csrf_token()&lt;br /&gt;
    render(conn, :index, data: &amp;quot;Hello World&amp;quot;,form: %{},csrf_token: csrf_token)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def new(conn, params) do&lt;br /&gt;
      IO.inspect params&lt;br /&gt;
      redirect(conn, to: &amp;quot;/&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In the controllers directory create a file named '''page_html.ex'''&lt;br /&gt;
&lt;br /&gt;
In this file, copy this code.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageHTML do&lt;br /&gt;
  use AppWeb, :html&lt;br /&gt;
&lt;br /&gt;
  embed_templates &amp;quot;page_html/*&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In the controllers directory create another directory named '''page_html''' (technically you can place this directory outside the controllers and it will still work).&lt;br /&gt;
&lt;br /&gt;
'''app/lib/app_web/controllers/page_html'''&lt;br /&gt;
&lt;br /&gt;
This directory will contain heex templates for the PageController.&lt;br /&gt;
&lt;br /&gt;
In the page_html directory place a file named '''index.html.heex'''.&lt;br /&gt;
&lt;br /&gt;
Inside the file copy the following code.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;%=@data%&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;form method=&amp;quot;POST&amp;quot; action=&amp;quot;/create&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;_csrf_token&amp;quot; value={@csrf_token} /&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;example&amp;quot; /&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;submit&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;/form&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Run the server:   mix phx.server&lt;br /&gt;
&lt;br /&gt;
You should see a form field and a submit button with the text &amp;quot;Hello World&amp;quot; above them. Type into the form and submit it, the terminal will display your input. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you replace the form with the built in form helper, you can remove the csrf code. CSRF protection comes built in with the form helper. Delete or comment out the code in index.html.heex and replace it with the code below.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;.form :let={f} action={~p&amp;quot;/create&amp;quot;}&amp;gt;&lt;br /&gt;
    &amp;lt;.input field={f[:x]} name=&amp;quot;submitted-data&amp;quot; /&amp;gt;&lt;br /&gt;
  &amp;lt;/.form&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Delete or comment out the code in page_controller.ex and replace it with the code below.&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  def index(conn, params) do&lt;br /&gt;
    IO.inspect params&lt;br /&gt;
    render(conn, :index, data: &amp;quot;Hello World&amp;quot;,form: %{})&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def new(conn, params) do&lt;br /&gt;
      IO.inspect params&lt;br /&gt;
      redirect(conn, to: &amp;quot;/&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When you run the server and visit the landing page, you should see the page render without error.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Form Changesets===&lt;br /&gt;
Without Changesets we have these two problems:&lt;br /&gt;
&lt;br /&gt;
* We lose what we typed.&lt;br /&gt;
* The app doesn’t tell us what our errors were.&lt;br /&gt;
&lt;br /&gt;
Changesets solve both of these problems.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Schema and Live View Form==&lt;br /&gt;
&lt;br /&gt;
===Schema===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule App.Todo do&lt;br /&gt;
  use Ecto.Schema&lt;br /&gt;
  import Ecto.Changeset&lt;br /&gt;
&lt;br /&gt;
  schema &amp;quot;todos&amp;quot; do&lt;br /&gt;
    field :description, :string&lt;br /&gt;
    field :title, :string&lt;br /&gt;
&lt;br /&gt;
    timestamps(type: :utc_datetime)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  @doc false&lt;br /&gt;
  def changeset(todo, attrs) do&lt;br /&gt;
    todo&lt;br /&gt;
    |&amp;gt; cast(attrs, [:title, :description])&lt;br /&gt;
    |&amp;gt; validate_required([:title, :description])&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Live View Form ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  alias App.Todo&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    changeset = Todo.changeset(%Todo{}, %{})&lt;br /&gt;
    &lt;br /&gt;
    {:ok,&lt;br /&gt;
     socket&lt;br /&gt;
     |&amp;gt; assign(:changeset, changeset)&lt;br /&gt;
     |&amp;gt; assign(:todo, %Todo{})&lt;br /&gt;
     |&amp;gt; assign(:saved, false)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;save&amp;quot;, %{&amp;quot;todo&amp;quot; =&amp;gt; todo_params}, socket) do&lt;br /&gt;
   case save_todo(todo_params) do&lt;br /&gt;
     {:ok, _todo} -&amp;gt;&lt;br /&gt;
       {:noreply,&lt;br /&gt;
        socket&lt;br /&gt;
        |&amp;gt; assign(:changeset, Todo.changeset(%Todo{}, %{}))&lt;br /&gt;
        |&amp;gt; assign(:saved, true)}&lt;br /&gt;
&lt;br /&gt;
     {:error, %Ecto.Changeset{} = changeset} -&amp;gt;&lt;br /&gt;
       {:noreply, assign(socket, changeset: changeset, saved: false)}&lt;br /&gt;
   end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 defp save_todo(todo_params) do&lt;br /&gt;
   %Todo{}&lt;br /&gt;
   |&amp;gt; Todo.changeset(todo_params)&lt;br /&gt;
   |&amp;gt; App.Repo.insert()&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    &amp;lt;.form :let={f} for={@changeset} phx-submit=&amp;quot;save&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;.input field={f[:title]} type=&amp;quot;text&amp;quot; label=&amp;quot;Title&amp;quot; /&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;.input field={f[:description]} type=&amp;quot;textarea&amp;quot; label=&amp;quot;Description&amp;quot; /&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;.button&amp;gt;Save&amp;lt;/.button&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;/.form&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;%= if @saved do %&amp;gt;&lt;br /&gt;
      &amp;lt;div class=&amp;quot;alert alert-info&amp;quot;&amp;gt;&lt;br /&gt;
        Todo saved successfully!&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>http://elixirblocks.com/index.php?title=How_to_Create_Nested_LiveView_Components&amp;diff=1886</id>
		<title>How to Create Nested LiveView Components</title>
		<link rel="alternate" type="text/html" href="http://elixirblocks.com/index.php?title=How_to_Create_Nested_LiveView_Components&amp;diff=1886"/>
		<updated>2025-03-13T18:32:24Z</updated>

		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This example demonstrates a nested LiveView component.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppxWeb.SandboxLive do&lt;br /&gt;
   use AppxWeb, :live_view  &lt;br /&gt;
   import MyComponent&lt;br /&gt;
   def mount(_params, _session, socket)  do&lt;br /&gt;
	 {:ok, socket}  &lt;br /&gt;
   end&lt;br /&gt;
   def render(assigns) do&lt;br /&gt;
	   ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
	      Hello World! YAY&lt;br /&gt;
	     &amp;lt;MyComponent.greet name=&amp;quot;Jane&amp;quot; /&amp;gt;&lt;br /&gt;
	   &amp;quot;&amp;quot;&amp;quot; &lt;br /&gt;
   end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule MyComponent do&lt;br /&gt;
   use Phoenix.Component&lt;br /&gt;
&lt;br /&gt;
   def greet(assigns) do&lt;br /&gt;
	   ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
	     &amp;lt;p&amp;gt;Hello, &amp;lt;%= @name %&amp;gt;!&amp;lt;/p&amp;gt;&lt;br /&gt;
	   &amp;quot;&amp;quot;&amp;quot; &lt;br /&gt;
   end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
An Example of a Button&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# 1. Create component with phx-click attributes for event handlers and a render slot fo text:   &amp;lt;%= render_slot(@inner_block) %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule Example do&lt;br /&gt;
  use Phoenix.Component&lt;br /&gt;
&lt;br /&gt;
  def simple_button(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    &amp;lt;button&lt;br /&gt;
      style=&amp;quot;background-color: #000000; color: #ffffff; padding: 8px 16px; border-radius: 4px; font-weight: bold;&amp;quot;&lt;br /&gt;
      phx-click={@on_click}&lt;br /&gt;
    &amp;gt;&lt;br /&gt;
      &amp;lt;%= render_slot(@inner_block) %&amp;gt;&lt;br /&gt;
    &amp;lt;/button&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#___________PARENT&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  import Example&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    # Initialize state with a counter&lt;br /&gt;
    socket = assign(socket, count: 0)&lt;br /&gt;
    {:ok, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    &amp;lt;div class=&amp;quot;container mx-auto p-4&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;h1 class=&amp;quot;text-xl font-bold mb-4&amp;quot;&amp;gt;Counter with Button Component&amp;lt;/h1&amp;gt;&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;div class=&amp;quot;mb-4&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;p&amp;gt;Current count: &amp;lt;span class=&amp;quot;font-bold&amp;quot;&amp;gt;&amp;lt;%= @count %&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;!-- # 2 add component to parent. Event handlers will come from parent--&amp;gt;&lt;br /&gt;
      &amp;lt;Example.simple_button on_click=&amp;quot;increment&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;span&amp;gt;Click to increment&amp;lt;/span&amp;gt;&lt;br /&gt;
      &amp;lt;/Example.simple_button&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Event handler in the parent LiveView&lt;br /&gt;
  def handle_event(&amp;quot;increment&amp;quot;, _params, socket) do&lt;br /&gt;
    {:noreply, assign(socket, count: socket.assigns.count + 1)}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>http://elixirblocks.com/index.php?title=Working_with_Sibling_Components&amp;diff=1885</id>
		<title>Working with Sibling Components</title>
		<link rel="alternate" type="text/html" href="http://elixirblocks.com/index.php?title=Working_with_Sibling_Components&amp;diff=1885"/>
		<updated>2025-03-12T14:44:03Z</updated>

		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule Heading do&lt;br /&gt;
  use Phoenix.Component&lt;br /&gt;
&lt;br /&gt;
  def head(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    &amp;lt;ul&amp;gt;&lt;br /&gt;
      &amp;lt;%= for heading &amp;lt;- @headings do %&amp;gt;&lt;br /&gt;
        &amp;lt;li phx-click=&amp;quot;append_content&amp;quot; phx-value-heading={heading}&amp;gt;{heading}!&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;% end %&amp;gt;&lt;br /&gt;
    &amp;lt;/ul&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
#________________________________________________________________&lt;br /&gt;
defmodule Content do&lt;br /&gt;
  use Phoenix.Component&lt;br /&gt;
&lt;br /&gt;
  def content(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    &amp;lt;p&amp;gt;This is content: {@content}!&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
#________________________________________________________________&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  import Heading&lt;br /&gt;
  import Content&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    {:ok, assign(socket, content: &amp;quot;This is some great content here&amp;quot;)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def headings do&lt;br /&gt;
    [&amp;quot;one&amp;quot;, &amp;quot;two&amp;quot;, &amp;quot;three&amp;quot;]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    &amp;lt;Heading.head headings={headings()} /&amp;gt;&lt;br /&gt;
    &amp;lt;Content.content content={@content} /&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;append_content&amp;quot;, %{&amp;quot;heading&amp;quot; =&amp;gt; _heading}, socket) do&lt;br /&gt;
    updated_content = socket.assigns.content &amp;lt;&amp;gt; &amp;quot; hello there&amp;quot;&lt;br /&gt;
    {:noreply, assign(socket, content: updated_content)}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  import Phoenix.Component&lt;br /&gt;
&lt;br /&gt;
  defmodule Heading do&lt;br /&gt;
    use Phoenix.Component&lt;br /&gt;
&lt;br /&gt;
    def head(assigns) do&lt;br /&gt;
      click_handler = assigns[:click_handler] || &amp;quot;append_content&amp;quot; # Default to &amp;quot;append_content&amp;quot; if not passed&lt;br /&gt;
      ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
      &amp;lt;ul&amp;gt;&lt;br /&gt;
        &amp;lt;%= for heading &amp;lt;- @headings do %&amp;gt;&lt;br /&gt;
          &amp;lt;li phx-click={click_handler} phx-value-heading={heading}&amp;gt;{heading}!&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;% end %&amp;gt;&lt;br /&gt;
      &amp;lt;/ul&amp;gt;&lt;br /&gt;
      &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  defmodule Content do&lt;br /&gt;
    use Phoenix.Component&lt;br /&gt;
&lt;br /&gt;
    def content(assigns) do&lt;br /&gt;
      ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
      &amp;lt;p&amp;gt;This is content: {@content}!&amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    {:ok, assign(socket, content: &amp;quot;This is some great content here&amp;quot;)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def headings do&lt;br /&gt;
    [&amp;quot;one&amp;quot;, &amp;quot;two&amp;quot;, &amp;quot;three&amp;quot;]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    # Pass the desired function name as `click_handler` (you can pass any string you want)&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    &amp;lt;Heading.head headings={headings()} click_handler=&amp;quot;custom_action&amp;quot; /&amp;gt;&lt;br /&gt;
    &amp;lt;Content.content content={@content} /&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Default handler for &amp;quot;append_content&amp;quot;&lt;br /&gt;
  def handle_event(&amp;quot;append_content&amp;quot;, %{&amp;quot;heading&amp;quot; =&amp;gt; _heading}, socket) do&lt;br /&gt;
    updated_content = socket.assigns.content &amp;lt;&amp;gt; &amp;quot; hello there&amp;quot;&lt;br /&gt;
    {:noreply, assign(socket, content: updated_content)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Custom handler for a different function&lt;br /&gt;
  def handle_event(&amp;quot;custom_action&amp;quot;, %{&amp;quot;heading&amp;quot; =&amp;gt; _heading}, socket) do&lt;br /&gt;
    updated_content = socket.assigns.content &amp;lt;&amp;gt; &amp;quot; custom action triggered!&amp;quot;&lt;br /&gt;
    {:noreply, assign(socket, content: updated_content)}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>http://elixirblocks.com/index.php?title=Working_with_Sibling_Components&amp;diff=1884</id>
		<title>Working with Sibling Components</title>
		<link rel="alternate" type="text/html" href="http://elixirblocks.com/index.php?title=Working_with_Sibling_Components&amp;diff=1884"/>
		<updated>2025-03-12T13:59:24Z</updated>

		<summary type="html">&lt;p&gt;Admin: Created page with &amp;quot;&amp;lt;source&amp;gt; defmodule Heading do   use Phoenix.Component    def head(assigns) do     ~H&amp;quot;&amp;quot;&amp;quot;     &amp;lt;ul&amp;gt;       &amp;lt;%= for heading &amp;lt;- @headings do %&amp;gt;         &amp;lt;li phx-click=&amp;quot;append_content&amp;quot; phx-value-heading={heading}&amp;gt;{heading}!&amp;lt;/li&amp;gt;       &amp;lt;% end %&amp;gt;     &amp;lt;/ul&amp;gt;     &amp;quot;&amp;quot;&amp;quot;   end end  #________________________________________________________________ defmodule Content do   use Phoenix.Component    def content(assigns) do     ~H&amp;quot;&amp;quot;&amp;quot;     &amp;lt;p&amp;gt;This is content: {@content}!&amp;lt;/p&amp;gt;     &amp;quot;&amp;quot;&amp;quot;   end end #__...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule Heading do&lt;br /&gt;
  use Phoenix.Component&lt;br /&gt;
&lt;br /&gt;
  def head(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    &amp;lt;ul&amp;gt;&lt;br /&gt;
      &amp;lt;%= for heading &amp;lt;- @headings do %&amp;gt;&lt;br /&gt;
        &amp;lt;li phx-click=&amp;quot;append_content&amp;quot; phx-value-heading={heading}&amp;gt;{heading}!&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;% end %&amp;gt;&lt;br /&gt;
    &amp;lt;/ul&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
#________________________________________________________________&lt;br /&gt;
defmodule Content do&lt;br /&gt;
  use Phoenix.Component&lt;br /&gt;
&lt;br /&gt;
  def content(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    &amp;lt;p&amp;gt;This is content: {@content}!&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
#________________________________________________________________&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  import Heading&lt;br /&gt;
  import Content&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    {:ok, assign(socket, content: &amp;quot;This is some great content here&amp;quot;)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def headings do&lt;br /&gt;
    [&amp;quot;one&amp;quot;, &amp;quot;two&amp;quot;, &amp;quot;three&amp;quot;]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    &amp;lt;Heading.head headings={headings()} /&amp;gt;&lt;br /&gt;
    &amp;lt;Content.content content={@content} /&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;append_content&amp;quot;, %{&amp;quot;heading&amp;quot; =&amp;gt; _heading}, socket) do&lt;br /&gt;
    updated_content = socket.assigns.content &amp;lt;&amp;gt; &amp;quot; hello there&amp;quot;&lt;br /&gt;
    {:noreply, assign(socket, content: updated_content)}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>http://elixirblocks.com/index.php?title=User:Admin&amp;diff=1883</id>
		<title>User:Admin</title>
		<link rel="alternate" type="text/html" href="http://elixirblocks.com/index.php?title=User:Admin&amp;diff=1883"/>
		<updated>2025-03-12T09:38:46Z</updated>

		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 defmodule Heading do&lt;br /&gt;
   use Phoenix.Component&lt;br /&gt;
   def head(assigns) do&lt;br /&gt;
	   ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	     &amp;lt;p&amp;gt;Hello, &amp;lt;%= @headings %&amp;gt;!&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	   &amp;quot;&amp;quot;&amp;quot; &lt;br /&gt;
   end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
   use AppWeb, :live_view  &lt;br /&gt;
   import Heading&lt;br /&gt;
   def mount(_params, _session, socket)  do&lt;br /&gt;
	 {:ok, socket}  &lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
   def headings do &lt;br /&gt;
    [&amp;quot;one&amp;quot;,&amp;quot;two&amp;quot;,&amp;quot;three&amp;quot;]&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
   def render(assigns) do&lt;br /&gt;
	   ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	     &amp;lt;Heading.head  headings={headings()} /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	   &amp;quot;&amp;quot;&amp;quot; &lt;br /&gt;
   end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://app.studyraid.com/en/read/11967/381872/component-communication&lt;br /&gt;
&lt;br /&gt;
https://thepugautomatic.com/2020/08/communicating-between-liveviews-on-the-same-page/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
from(a in Article,&lt;br /&gt;
  order_by: [desc: a.inserted_at],  # Assuming 'inserted_at' is the timestamp for when the article was created or updated&lt;br /&gt;
  limit: 8&lt;br /&gt;
)&lt;br /&gt;
|&amp;gt; Repo.all()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.Landing do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  alias App.Testbeds&lt;br /&gt;
  alias App.Testbeds.Testbed&lt;br /&gt;
  alias App.Repo  # Ensure to alias Repo&lt;br /&gt;
  import Ecto.Query  # Import Ecto.Query to work with queries&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    # Default to ordering by name&lt;br /&gt;
    testbeds = Repo.all(from(t in Testbed, order_by: t.name))&lt;br /&gt;
&lt;br /&gt;
    # Assign the testbeds to the socket for rendering&lt;br /&gt;
    {:ok, assign(socket, testbeds: testbeds, sort: :name)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    &amp;lt;h1&amp;gt;Hello World! YAY&amp;lt;/h1&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;div&amp;gt;&lt;br /&gt;
      &amp;lt;!-- Buttons to toggle sorting --&amp;gt;&lt;br /&gt;
      &amp;lt;button phx-click=&amp;quot;sort_by_name&amp;quot;&amp;gt;Sort by Name&amp;lt;/button&amp;gt;&lt;br /&gt;
      &amp;lt;button phx-click=&amp;quot;sort_by_updated_at&amp;quot;&amp;gt;Sort by Updated By&amp;lt;/button&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;ul&amp;gt;&lt;br /&gt;
      &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
        &amp;lt;li&amp;gt;&amp;lt;%= testbed.name %&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;% end %&amp;gt;&lt;br /&gt;
    &amp;lt;/ul&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;sort_by_name&amp;quot;, _params, socket) do&lt;br /&gt;
    testbeds = Repo.all(from(t in Testbed, order_by: t.name))&lt;br /&gt;
    {:noreply, assign(socket, testbeds: testbeds, sort: :name)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;sort_by_updated_at&amp;quot;, _params, socket) do&lt;br /&gt;
    testbeds = Repo.all(from(t in Testbed, order_by: t.inserted_at))&lt;br /&gt;
    {:noreply, assign(socket, testbeds: testbeds, sort: :inserted_at)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
_______________________________________________________&lt;br /&gt;
&lt;br /&gt;
* Create a form with a post request. &lt;br /&gt;
* Create the route needed for that request&lt;br /&gt;
* Create the controller needed for that route&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Form==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;.form action={~p&amp;quot;/todos&amp;quot;} method=&amp;quot;post&amp;quot; class=&amp;quot;mt-10 space-y-8&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    &amp;lt;label for=&amp;quot;contact_name&amp;quot; class=&amp;quot;block text-sm font-semibold leading-6 text-zinc-800&amp;quot;&amp;gt;&lt;br /&gt;
      Name&lt;br /&gt;
    &amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;input&lt;br /&gt;
      id=&amp;quot;todo&amp;quot;&lt;br /&gt;
      type=&amp;quot;text&amp;quot;&lt;br /&gt;
      name=&amp;quot;todo&amp;quot;&lt;br /&gt;
      class=&amp;quot;mt-2 block w-full rounded-lg text-zinc-900 focus:ring-0 sm:text-sm sm:leading-6 border-zinc-300 focus:border-zinc-400&amp;quot;&lt;br /&gt;
    /&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;button&lt;br /&gt;
    type=&amp;quot;submit&amp;quot;&lt;br /&gt;
    class=&amp;quot;rounded-lg bg-zinc-900 hover:bg-zinc-700 py-2 px-3 text-sm font-semibold leading-6 text-white active:text-white/80&amp;quot;&lt;br /&gt;
  &amp;gt;&lt;br /&gt;
    Save Contact&lt;br /&gt;
  &amp;lt;/button&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/.form&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Controller==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# In your TodoController&lt;br /&gt;
defmodule AppWeb.TodoController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  # Action to handle the form submission (POST request)&lt;br /&gt;
  def create(conn, %{&amp;quot;todo&amp;quot; =&amp;gt; todo_name}) do&lt;br /&gt;
    # Here you can handle the form data (e.g., save it to the database)&lt;br /&gt;
    IO.puts(&amp;quot;Received Todo: #{todo_name}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    # For now, let's just redirect to the home page&lt;br /&gt;
    conn&lt;br /&gt;
    |&amp;gt; put_flash(:info, &amp;quot;Todo saved!&amp;quot;)&lt;br /&gt;
    |&amp;gt; redirect(to: &amp;quot;/&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
________________________________________________________&lt;br /&gt;
&lt;br /&gt;
# CRUD Forms&lt;br /&gt;
&lt;br /&gt;
To understand CRUD forms you will need to understand the following concepts. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Ecto Schema&lt;br /&gt;
* Ecto Context&lt;br /&gt;
* Form Basics&lt;br /&gt;
* form/1&lt;br /&gt;
* simple_form/1&lt;br /&gt;
* changesets&lt;br /&gt;
&lt;br /&gt;
We are not going to go in order. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The Context provides CRUD functions for the chosen data schema. Phoenix contexts define the interface through which other parts of the codebase can interact with the app layer.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_______________________&lt;br /&gt;
* Create routes&lt;br /&gt;
* create page with form (submit get request)&lt;br /&gt;
&lt;br /&gt;
(ecto schema, context, changesets)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_______________________________________________________&lt;br /&gt;
In that case, you really should switch it to prod mode. Instead of doing all that above with the &amp;quot;config/secret.exs&amp;quot; file, create the &amp;quot;.env&amp;quot; in the project root, then add DotenvParser.load_file(&amp;quot;.env&amp;quot;) to &amp;quot;config/runtime.exs&amp;quot; as the first line inside the if config_env() == :prod do. In the .env file, set the DATABASE_URL and SECRET_KEY_BASE. Then run it as MIX_ENV=prod mix phx.server.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def get_titles do&lt;br /&gt;
    urls = [&lt;br /&gt;
      &amp;quot;https://cointelegraph.com/rss&amp;quot;,&lt;br /&gt;
      &amp;quot;https://chaski.huffpost.com/us/auto/vertical/us-news&amp;quot;&lt;br /&gt;
      # Add more RSS feed URLs here&lt;br /&gt;
    ]&lt;br /&gt;
&lt;br /&gt;
    urls&lt;br /&gt;
    |&amp;gt; Enum.map(fn url -&amp;gt;&lt;br /&gt;
      with {:ok, feed} &amp;lt;- ElixirRss.fetch_and_parse(url) do&lt;br /&gt;
        Enum.map(feed.entries, &amp;amp; &amp;amp;1.title)&lt;br /&gt;
      else&lt;br /&gt;
        {:error, reason} -&amp;gt; {:error, reason}&lt;br /&gt;
      end&lt;br /&gt;
    end)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule App do&lt;br /&gt;
&lt;br /&gt;
  def get_titles() do&lt;br /&gt;
    data = [&lt;br /&gt;
      &amp;quot;https://cointelegraph.com/rss&amp;quot;,&lt;br /&gt;
      &amp;quot;https://chaski.huffpost.com/us/auto/vertical/us-news&amp;quot;&lt;br /&gt;
      # Add more RSS feed URLs here&lt;br /&gt;
    ]&lt;br /&gt;
&lt;br /&gt;
    data&lt;br /&gt;
    |&amp;gt; Enum.map(fn url -&amp;gt;&lt;br /&gt;
      case ElixirRss.fetch_and_parse(url) do&lt;br /&gt;
        {:ok, feed} -&amp;gt; feed.entries |&amp;gt; Enum.map(fn entry -&amp;gt; entry end)&lt;br /&gt;
        {:error, reason} -&amp;gt; {:error, reason}&lt;br /&gt;
      end&lt;br /&gt;
    end)&lt;br /&gt;
    |&amp;gt; Enum.map(fn entry_list -&amp;gt;&lt;br /&gt;
      entry_list&lt;br /&gt;
      |&amp;gt; Enum.map(fn entry -&amp;gt; entry.title end)&lt;br /&gt;
    end)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def hello do&lt;br /&gt;
    rss_feeds = [&lt;br /&gt;
      &amp;quot;https://cointelegraph.com/rss&amp;quot;,&lt;br /&gt;
      &amp;quot;https://chaski.huffpost.com/us/auto/vertical/us-news&amp;quot;&lt;br /&gt;
      # Add more RSS feed URLs here&lt;br /&gt;
    ]&lt;br /&gt;
&lt;br /&gt;
    rss_feeds&lt;br /&gt;
    |&amp;gt; Enum.map(fn url -&amp;gt;&lt;br /&gt;
      case ElixirRss.fetch_and_parse(url) do&lt;br /&gt;
        {:ok, feed} -&amp;gt; feed.entries |&amp;gt; Enum.map(fn entry -&amp;gt; entry end)&lt;br /&gt;
        {:error, reason} -&amp;gt; {:error, reason}&lt;br /&gt;
      end&lt;br /&gt;
    end)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    if connected?(socket) do&lt;br /&gt;
      Phoenix.PubSub.subscribe(App.PubSub, &amp;quot;message&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
    {:ok, assign(socket, message_item: &amp;quot;different&amp;quot;)}&lt;br /&gt;
  end&lt;br /&gt;
  def handle_info({:pubsub_transmission, text}, socket) do&lt;br /&gt;
    IO.inspect &amp;quot;pub sub working&amp;quot;&lt;br /&gt;
    {:noreply, assign(socket, message_item: text)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def loop(data) do&lt;br /&gt;
     IO.inspect data&lt;br /&gt;
     if data &amp;gt; 0 do&lt;br /&gt;
      IO.inspect &amp;quot;notify&amp;quot;&lt;br /&gt;
      # run code to compare files, loop. If different run pubsub code below&lt;br /&gt;
      :timer.sleep(2000)&lt;br /&gt;
      loop(data-1)&lt;br /&gt;
&lt;br /&gt;
     end&lt;br /&gt;
     if data &amp;lt;= 0 do&lt;br /&gt;
&lt;br /&gt;
      Phoenix.PubSub.broadcast(App.PubSub, &amp;quot;message&amp;quot;, {:pubsub_transmission, &amp;quot;data&amp;quot;})&lt;br /&gt;
      &amp;quot;done&amp;quot;&lt;br /&gt;
     end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;change-text&amp;quot;, _params, socket) do&lt;br /&gt;
    spawn(fn -&amp;gt; loop(3) end)&lt;br /&gt;
    {:noreply, assign(socket, message_item: &amp;quot;START&amp;quot; )}&lt;br /&gt;
  end&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
&lt;br /&gt;
    # AppWeb.PageLive.loop(&amp;quot;xxx&amp;quot;)&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    SANDBOX&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;.button phx-click=&amp;quot;change-text&amp;quot; value={@message_item}&amp;gt;CLICK ME&amp;lt;/.button&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;%= @message_item %&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
elixir :   1.16.2&lt;br /&gt;
&lt;br /&gt;
Erl:   20&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# PostGres&lt;br /&gt;
Created Saturday 18 February 2023&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Launch [PostGres](#PostGres) from Terminal&lt;br /&gt;
------------------------------------------&lt;br /&gt;
sudo -u postgres psql&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Set User Permission&lt;br /&gt;
-------------------&lt;br /&gt;
&amp;lt;https://commandprompt.com/education/how-to-create-a-superuser-in-postgresql/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ALTER USER user_name WITH PASSWORD 'new_password';&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Run Post Gres Commands&lt;br /&gt;
----------------------&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
sudo -i -u postgres&lt;br /&gt;
psql&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Create and Delete Database&lt;br /&gt;
&lt;br /&gt;
CREATE DATABASE name;&lt;br /&gt;
DROP DATABASE name;&lt;br /&gt;
## View user list&lt;br /&gt;
&lt;br /&gt;
\du&lt;br /&gt;
&lt;br /&gt;
 View all databases&lt;br /&gt;
&lt;br /&gt;
postgres=# \l&lt;br /&gt;
&lt;br /&gt;
 Change databases&lt;br /&gt;
&lt;br /&gt;
postgres=# \c    name-of-database&lt;br /&gt;
&lt;br /&gt;
View Tables&lt;br /&gt;
&lt;br /&gt;
After you change databases and are selected on one of them do this:&lt;br /&gt;
&lt;br /&gt;
\dt&lt;br /&gt;
&lt;br /&gt;
SELECT * FROM mytablename;&lt;br /&gt;
&lt;br /&gt;
EMPTY TABLE&lt;br /&gt;
DELETE FROM name-of-table&lt;br /&gt;
&lt;br /&gt;
CREATE TABLE&lt;br /&gt;
&lt;br /&gt;
CREATE TABLE table_name(&lt;br /&gt;
   column1 datatype,&lt;br /&gt;
   column2 datatype,&lt;br /&gt;
   column3 datatype,&lt;br /&gt;
   .....&lt;br /&gt;
   columnN datatype,&lt;br /&gt;
   PRIMARY KEY( one or more columns )&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
INSERT&lt;br /&gt;
&lt;br /&gt;
INSERT INTO ITEMS(id, name) VALUES(1,'htvjbjbgni');     Strings are single quote&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Roadmap==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.ItemsLive do&lt;br /&gt;
    use AppWeb, :live_view  &lt;br /&gt;
    def mount(_params, _session, socket)  do&lt;br /&gt;
      {:ok, assign(socket, switches: [&amp;quot;grindy&amp;quot;,&amp;quot;sonic&amp;quot;,&amp;quot;ogre&amp;quot;])}  &lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    def handle_event(&amp;quot;run&amp;quot;,_params,socket) do  &lt;br /&gt;
        &lt;br /&gt;
        IO.inspect &amp;quot;DOWNLOAD VIA SSH&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        {:noreply, redirect(socket, to: &amp;quot;/download&amp;quot;)}&lt;br /&gt;
&lt;br /&gt;
    end&lt;br /&gt;
   &lt;br /&gt;
&lt;br /&gt;
    def render(assigns) do&lt;br /&gt;
        &lt;br /&gt;
        ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        &amp;lt;ul&amp;gt;&lt;br /&gt;
        &amp;lt;%= for switch &amp;lt;- @switches do %&amp;gt;&lt;br /&gt;
         &amp;lt;a phx-submit=&amp;quot;click&amp;quot; href=&amp;quot;/download&amp;quot;&amp;gt;  &amp;lt;li&amp;gt; &amp;lt;%= switch %&amp;gt;  &amp;lt;/li&amp;gt; &amp;lt;/a&amp;gt;&lt;br /&gt;
&lt;br /&gt;
        &amp;lt;%end%&amp;gt;&lt;br /&gt;
        &amp;lt;/ul&amp;gt;&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot; &lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Notes==&lt;br /&gt;
List of Switches and the option to select the one needed.&lt;br /&gt;
Button to download JSON file.&lt;br /&gt;
Drag and Drop Palette to upload JSON file.&lt;br /&gt;
&lt;br /&gt;
After JSON file is uploaded a button titled &amp;quot;Make Active&amp;quot; is available.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://medium.com/@fraiha26/pushing-events-to-livecomponents-from-js-hooks-w-phoenix-elixir-d5544d4c3dfa&lt;br /&gt;
&lt;br /&gt;
Changeset notes and forms&lt;br /&gt;
&lt;br /&gt;
NOTE: Use case statements for pattern matching&lt;br /&gt;
____________________________________________&lt;br /&gt;
&lt;br /&gt;
Create a basic &amp;lt;.form&amp;gt;&amp;lt;/form&amp;gt; without error handling&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&amp;lt;.form :let={f} for={@changeset}  action={~p&amp;quot;/items&amp;quot;} &amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;.input field={f[:title]} type=&amp;quot;text&amp;quot; label=&amp;quot;Title&amp;quot; /&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
  &amp;lt;.button&amp;gt;Save Item&amp;lt;/.button&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;/.form&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With error handling looks like this:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;.form :let={f} for={@changeset}  action={~p&amp;quot;/items&amp;quot;} &amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;.error :if={@changeset.action}&amp;gt;&lt;br /&gt;
    Oops, something went wrong! Please check the errors below.&lt;br /&gt;
  &amp;lt;/.error&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;.input field={f[:title]} type=&amp;quot;text&amp;quot; label=&amp;quot;Title&amp;quot; /&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
  &amp;lt;.button&amp;gt;Save Item&amp;lt;/.button&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;/.form&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Create the routes for render and post to endpoint.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The controller for the page render needs to pass in the changeset via ```Items.change_item(%Item{})```&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  def new(conn, _params) do&lt;br /&gt;
    changeset = Items.change_item(%Item{})&lt;br /&gt;
    render(conn, :new, changeset: changeset)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Post route without error handling&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  def create(conn, %{&amp;quot;item&amp;quot; =&amp;gt; item_params}) do&lt;br /&gt;
    case Items.create_item(item_params) do&lt;br /&gt;
      {:ok, item} -&amp;gt;&lt;br /&gt;
        conn&lt;br /&gt;
        |&amp;gt; put_flash(:info, &amp;quot;Item created successfully.&amp;quot;)&lt;br /&gt;
        |&amp;gt; redirect(to: ~p&amp;quot;/items/#{item}&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With error handling&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  def create(conn, %{&amp;quot;item&amp;quot; =&amp;gt; item_params}) do&lt;br /&gt;
    case Items.create_item(item_params) do&lt;br /&gt;
      {:ok, item} -&amp;gt;&lt;br /&gt;
        conn&lt;br /&gt;
        |&amp;gt; put_flash(:info, &amp;quot;Item created successfully.&amp;quot;)&lt;br /&gt;
        |&amp;gt; redirect(to: ~p&amp;quot;/items/#{item}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
      {:error, %Ecto.Changeset{} = changeset} -&amp;gt;&lt;br /&gt;
        render(conn, :new, changeset: changeset)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_____________________________________________&lt;br /&gt;
https://medium.com/@vincentlin/phoenix-very-simple-form-c4b121697fcb&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''home.html.heex'''&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&amp;lt;form action=&amp;quot;/submit&amp;quot; method=&amp;quot;post&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;label for=&amp;quot;name&amp;quot;&amp;gt;Name:&amp;lt;/label&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;input type=&amp;quot;text&amp;quot; id=&amp;quot;name&amp;quot; name=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;_csrf_token&amp;quot; value={@csrf_token} /&amp;gt;&lt;br /&gt;
  &amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Submit&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
page_controller.ex&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.PageController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  def home(conn, _params) do&lt;br /&gt;
    # The home page is often custom made,&lt;br /&gt;
&lt;br /&gt;
    csrf_token = Plug.CSRFProtection.get_csrf_token()&lt;br /&gt;
    render(conn, :home, csrf_token: csrf_token)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def submit(conn, _params) do&lt;br /&gt;
    # The home page is often custom made,&lt;br /&gt;
     IO.inspect(_params)&lt;br /&gt;
     IO.inspect &amp;quot;___________________________&amp;quot;&lt;br /&gt;
    csrf_token = Plug.CSRFProtection.get_csrf_token()&lt;br /&gt;
    render(conn, :home, csrf_token: csrf_token)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
router.ex&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  scope &amp;quot;/&amp;quot;, AppWeb do&lt;br /&gt;
    pipe_through :browser&lt;br /&gt;
    post &amp;quot;/submit&amp;quot;, PageController, :submit&lt;br /&gt;
    get &amp;quot;/&amp;quot;, PageController, :home&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ecto.Adapters.SQL.query(Repo, &amp;quot;select * from artists where id=1&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ecto cheatsheet:  https://hexdocs.pm/ecto/crud.html&lt;br /&gt;
__________________________________________________________________&lt;br /&gt;
Most programming languages give you the ability to set global state by creating globally scoped variables. Elixir does not do this. Instead, Elixir provides a tool called a &amp;quot;processes&amp;quot; to persist  state. Elixir applications are composed of these &amp;quot;processes&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
Processes by themselves are complicated to use, thus Elixir provides abstractions to make working with processes easier. One of these abstractions is called a GenServer.&lt;br /&gt;
&lt;br /&gt;
GenServers are not only used to store state, they are also used to invoke work independent of the main application process. &lt;br /&gt;
&lt;br /&gt;
==Creating a GenServer to Store State==&lt;br /&gt;
&lt;br /&gt;
To Create a GenServer, start by creating a basic Module that ''uses'' the GenServer module (image below)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule App do  &lt;br /&gt;
  use GenServer&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We now need to describe the actions we want to perform. Being that this is used to store state, we will use basic CRUD actions: Create, Read, Update, Delete. To begins, empty functions describing each action is created.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule App do&lt;br /&gt;
   def create do &lt;br /&gt;
&lt;br /&gt;
   end&lt;br /&gt;
   def read do &lt;br /&gt;
&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
   def update do  &lt;br /&gt;
&lt;br /&gt;
   end &lt;br /&gt;
&lt;br /&gt;
   def delete do &lt;br /&gt;
&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==What now?==&lt;br /&gt;
&lt;br /&gt;
To fill in the functions with the appropriate code we must first have a basic understanding of how GenServers are structured.&lt;br /&gt;
&lt;br /&gt;
GenServers are composed of the GenServer module invoking callbacks. The callbacks have built in names that you, as a developer have to use.&lt;br /&gt;
&lt;br /&gt;
These callbacks are named:&lt;br /&gt;
&lt;br /&gt;
* init&lt;br /&gt;
* handle_cast&lt;br /&gt;
* handle_call&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To demonstrate, here is an example :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{:ok, pid} = GenServer.start(ModuleNameOfGenServer, %{})&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above function named &amp;quot;start&amp;quot; calls the function named init in the Module below.&lt;br /&gt;
In GenServer syntax the name of the GenServer functions always invoke callbacks that are determined by the language. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule ModuleNameOfGenServer do&lt;br /&gt;
  # 1&lt;br /&gt;
  def init(state \\ %{}) do&lt;br /&gt;
    {:ok, state}&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is a list of the GenServer functions and their corresponding callbacks.&lt;br /&gt;
&lt;br /&gt;
* GenServer.start/1  --&amp;gt;       init/1&lt;br /&gt;
* GenServer.call/3   --&amp;gt;       def handle_call/3&lt;br /&gt;
* GenServer.cast/2   --&amp;gt;       handle_cast/2&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Start and Call ==&lt;br /&gt;
&lt;br /&gt;
Call and Cast can be used to perform the same operations. The &lt;br /&gt;
&lt;br /&gt;
__________________________________________________________&lt;br /&gt;
Genserver timed events&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule Go do&lt;br /&gt;
  use GenServer&lt;br /&gt;
&lt;br /&gt;
  def go() do&lt;br /&gt;
    GenServer.start_link(__MODULE__, [])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def init(list) do&lt;br /&gt;
    :timer.apply_interval(1000, __MODULE__, :add, [self(), &amp;quot;weeeee&amp;quot;])&lt;br /&gt;
    {:ok, list}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def view(pid) do&lt;br /&gt;
    GenServer.call(pid, :view)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_call(:view, _from, list) do&lt;br /&gt;
    {:reply, list, list}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def add(pid, new_item) do&lt;br /&gt;
    GenServer.call(pid, {:item, new_item})&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_call({:item, new_item}, _from, state) do&lt;br /&gt;
    result = [new_item] ++ state&lt;br /&gt;
    {:reply, result, result}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule ShoppingList do&lt;br /&gt;
  use GenServer&lt;br /&gt;
&lt;br /&gt;
  def start_link() do&lt;br /&gt;
    GenServer.start_link(ShoppingList, [])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def init(list) do&lt;br /&gt;
    {:ok, list}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def view(pid) do&lt;br /&gt;
    GenServer.call(pid, :view)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_call(:view, _from, list) do&lt;br /&gt;
    {:reply, list, list}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def add(pid, new_item) do&lt;br /&gt;
    GenServer.call(pid, {:item, new_item})&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_call({:item, new_item}, _from, state) do&lt;br /&gt;
    result = [new_item] ++ state&lt;br /&gt;
    {:reply, result, result}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://blog.appsignal.com/2018/06/12/elixir-alchemy-deconstructing-genservers.html&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule KeyValue do&lt;br /&gt;
  # 1&lt;br /&gt;
  def init(state \\ %{}) do&lt;br /&gt;
    {:ok, state}&lt;br /&gt;
  end&lt;br /&gt;
 &lt;br /&gt;
  # 2&lt;br /&gt;
  def handle_cast({:put, key, value}, state) do&lt;br /&gt;
    {:noreply, Map.put(state, key, value)}&lt;br /&gt;
  end&lt;br /&gt;
 &lt;br /&gt;
  # 3&lt;br /&gt;
  def handle_call({:get, key}, _from, state) do&lt;br /&gt;
    {:reply, Map.fetch!(state, key), state}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
# {:ok, pid} = GenServer.start(KeyValue, %{})&lt;br /&gt;
# GenServer.cast(pid, {:put, :foo, &amp;quot;bar&amp;quot;})&lt;br /&gt;
# GenServer.call(pid, {:get, :foo})&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Send messages via these functions wrapped in module functions .You can look at these are functions used to fire &amp;quot;GenServer Events&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
* start_link&lt;br /&gt;
* GenServer.call&lt;br /&gt;
* GenServer.cast&lt;br /&gt;
&lt;br /&gt;
The corresponding server functions that reply are:&lt;br /&gt;
&lt;br /&gt;
* init&lt;br /&gt;
* handle__call&lt;br /&gt;
* handle_cast&lt;br /&gt;
* &lt;br /&gt;
&lt;br /&gt;
These can be looked at as &amp;quot;listeners&amp;quot; - in JavaScript parlance. &lt;br /&gt;
__________________________________________&lt;br /&gt;
&lt;br /&gt;
If you have experience with programming languages other than Elixir the idea of GenServers may be very foreign and require a strong context shift to learn. This document is intended to simplify the concept.&lt;br /&gt;
&lt;br /&gt;
* What: GenServers are simply a way to hold state and/or invoke actions based on incoming events. &lt;br /&gt;
* when &lt;br /&gt;
* where&lt;br /&gt;
* why&lt;br /&gt;
* how&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
___________________________________________&lt;br /&gt;
GenServer timer example&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule Timer do&lt;br /&gt;
  use GenServer&lt;br /&gt;
&lt;br /&gt;
  def init(_) do&lt;br /&gt;
    :timer.send_interval(1000, :xyz)&lt;br /&gt;
    {:ok, 0}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_info(:xyz, state) do&lt;br /&gt;
    IO.inspect(state)&lt;br /&gt;
    {:noreply, state + 1}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
[&lt;br /&gt;
   {&lt;br /&gt;
     data:{&lt;br /&gt;
        creationTime,&lt;br /&gt;
        publishDate,&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
     featured:{&lt;br /&gt;
        setAmount,&lt;br /&gt;
        items:[]&lt;br /&gt;
     },&lt;br /&gt;
&lt;br /&gt;
     children:{&lt;br /&gt;
        setAmount,&lt;br /&gt;
        items:[]&lt;br /&gt;
     },&lt;br /&gt;
     links:{&lt;br /&gt;
        setAmount,&lt;br /&gt;
        items:[]&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
jason.encode / jason.decode&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  def run(num) do&lt;br /&gt;
&lt;br /&gt;
    Enum.each(0..99999, fn(_x) -&amp;gt;&lt;br /&gt;
      task = Task.async(fn -&amp;gt; num + _x end)&lt;br /&gt;
    IO.inspect Task.await(task)&lt;br /&gt;
  end)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enum.map(feed.entries, fn x -&amp;gt; %{url: x.url, title: x.title} end)&lt;br /&gt;
&lt;br /&gt;
App is split:&lt;br /&gt;
&lt;br /&gt;
App that captures RSS in UI and lets admin select stories. THere are settings to determine the number of FEATURED,CHILD and LINK stories.&lt;br /&gt;
News categories are horizontal and scrollable.&lt;br /&gt;
This exports a json doc with all RSS data for each story.&lt;br /&gt;
The &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
App that reads the json data. This app creates tables and is the front end.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://stephenbussey.com/tags/elixir.html&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule AppWeb.GroupLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  alias App.TestBeds&lt;br /&gt;
  alias App.Groups&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    {:ok, assign(socket, testbeds: TestBeds.list_testbeds(), groups: Groups.list_groups())}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;select-group&amp;quot;, params, socket)  do  &lt;br /&gt;
     group = App.Groups.get_group!(params[&amp;quot;group-id&amp;quot;])&lt;br /&gt;
     testbed = App.TestBeds.get_test_bed!(params[&amp;quot;testbed_id&amp;quot;])&lt;br /&gt;
     App.TestBeds.update_test_bed(testbed, %{group_id: group.id})&lt;br /&gt;
     {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def updated_groups(testbed_id)  do  &lt;br /&gt;
     testbed = App.TestBeds.get_test_bed!(testbed_id)&lt;br /&gt;
     groups = App.Groups.list_groups&lt;br /&gt;
     tail = Enum.filter(groups, fn(item)-&amp;gt; item.id !== testbed.group_id end)&lt;br /&gt;
     head = Enum.filter(groups, fn(item)-&amp;gt; item.id == testbed.group_id end)&lt;br /&gt;
            |&amp;gt;Enum.at(0)&lt;br /&gt;
    [head | tail]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        &amp;lt;%= for testbed &amp;lt;- Enum.sort_by(@testbeds , &amp;amp;(&amp;quot;#{&amp;amp;1.name}&amp;quot;), :asc)do %&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;grid grid-cols-4 gap-4 p-8 rounded shadow bg-white&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;h2&amp;gt; Name&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;%= testbed.name %&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;h2&amp;gt; Group&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div&amp;gt;&lt;br /&gt;
            &amp;lt;form phx-change=&amp;quot;select-group&amp;quot; name=&amp;quot;testbed_id&amp;quot;  &amp;gt;&lt;br /&gt;
               &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;testbed_id&amp;quot; value={testbed.id}/&amp;gt;&lt;br /&gt;
               &amp;lt;select id=&amp;quot;group-selection&amp;quot;  name=&amp;quot;group-id&amp;quot; class=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;%= for group &amp;lt;- updated_groups(testbed.id) do %&amp;gt;&lt;br /&gt;
                  &amp;lt;%= if group !== nil do %&amp;gt;&lt;br /&gt;
                      &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}&amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
                      &amp;lt;%else%&amp;gt;&lt;br /&gt;
                      &amp;lt;option value= {&amp;quot;Unassigned&amp;quot;}&amp;gt;NONE&amp;lt;/option&amp;gt;&lt;br /&gt;
                  &amp;lt;% end %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
               &amp;lt;/select&amp;gt;&lt;br /&gt;
            &amp;lt;/form&amp;gt;&lt;br /&gt;
          &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
       &amp;lt;% end %&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Developer Notes ==&lt;br /&gt;
===Groups Feature ===&lt;br /&gt;
To complete this feature do these things.&lt;br /&gt;
* Run through the steps in [http://elixirblocks.com/index.php?title=Create_Foreign_Key_Relationship_Between_Ecto_Tables  | this document] to create Group table.&lt;br /&gt;
* Groups have these fields  '''name: string''', '''description: string''' and '''color: string'''  &lt;br /&gt;
* Add unique constraint in migration file: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def change do&lt;br /&gt;
     create unique_index(:groups, [:name])&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Port over Group LiveView code (temporarily placed at discussion page).&lt;br /&gt;
* On completion '''possibly''', create a Group named '''No Group''' and set all Testbeds to it.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
________&lt;br /&gt;
https://blog.appsignal.com/2022/10/11/phoenix-liveview-018-new-special-html-attributes.html&lt;br /&gt;
https://blixtdev.com/whats-new-phoenix-1-7/&lt;br /&gt;
https://github.com/devato/inertia_phoenix&lt;br /&gt;
https://phoenixonrails.com/blog/you-can-stop-using-form-for-in-phoenix&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://samuelmullen.com/articles/phoenix_templates_rendering_and_layouts&lt;br /&gt;
&lt;br /&gt;
WorkFlow of Todo App in Both LiveView and DeadView.&lt;br /&gt;
&lt;br /&gt;
Note:&lt;br /&gt;
&lt;br /&gt;
Create foreign key data.&lt;br /&gt;
Create live view. List all testbeds and form to assign each a group by group-name.&lt;br /&gt;
&lt;br /&gt;
Repeat in dead view&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Mental model and data flows&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
home.html.heex&lt;br /&gt;
&amp;lt;a href=&amp;quot;/data&amp;quot; name=&amp;quot;we are the world&amp;quot; &amp;gt;  click me&amp;lt;/a&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;%= @message %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
page controller&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  def home(conn, _params) do&lt;br /&gt;
    IO.inspect _params&lt;br /&gt;
    render(conn, :home, message: &amp;quot;Hello&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
get &amp;quot;/:yay&amp;quot;, PageController, :index&lt;br /&gt;
&lt;br /&gt;
get &amp;quot;/&amp;quot;, PageController, :index&lt;br /&gt;
&lt;br /&gt;
* Explain control flow of &amp;quot;Dead Views&amp;quot; and the Generator HTML Control flow.&lt;br /&gt;
* Proper Way to use Modal&lt;br /&gt;
* How to give Focus to Fields in Modal (or other forms fields)&lt;br /&gt;
* &lt;br /&gt;
* &lt;br /&gt;
* How to Create Database Seed Data.&lt;br /&gt;
* How to structure code so controller code is in one file and HTML Heex is in another&lt;br /&gt;
* How to Use Generators in a Real World Project&lt;br /&gt;
* How to Work with Database Data via Basic Commands and Custom Change sets.&lt;br /&gt;
* How to Render Database Data to LiveView (via Context Commands).&lt;br /&gt;
* How to Create a Chat using PubSub.&lt;br /&gt;
* How to Create Event Handlers in LiveView&lt;br /&gt;
* How to Create a Dynamic Route from Scratch.&lt;br /&gt;
* How to Use Elixirs Template language&lt;br /&gt;
* How to Work with Modal&lt;br /&gt;
* How to Use CSS From Scratch (Without bundler)&lt;br /&gt;
* How to use JS hooks&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
______________________&lt;br /&gt;
https://studioindie.co/blog/heex-guide/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
get &amp;quot;/&amp;quot;, PageController, :some-atom    #This is the route. some-atom is the controller name&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  def some-atom(conn, _params) do                 # controller name&lt;br /&gt;
    # The home page is often custom made,&lt;br /&gt;
    # so skip the default app layout.&lt;br /&gt;
    render(conn, :some-atom, layout: false)      # :some-atom is template name&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Controllers page_html.ex contains &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageHTML do&lt;br /&gt;
  use AppWeb, :html&lt;br /&gt;
&lt;br /&gt;
  embed_templates &amp;quot;page_html/*&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''page_html''' is the name of the folder in '''Controllers/page_html'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Controllers/page_html/some-atom.html.heex  (this is the template) &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__________________________________________&lt;br /&gt;
Set all association with preload:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  def list_groups do&lt;br /&gt;
    Repo.all(Group)&lt;br /&gt;
     |&amp;gt; Repo.preload([:testbeds])&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Insert Child into Parent ===&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
App.get_group!(2) # arg is id&lt;br /&gt;
|&amp;gt; Ecto.build_assoc(:testbeds)&lt;br /&gt;
|&amp;gt; Repo.insert()&lt;br /&gt;
&lt;br /&gt;
Or&lt;br /&gt;
&lt;br /&gt;
group = App.get_group!(2) # arg is id&lt;br /&gt;
&lt;br /&gt;
testbeds = Ecto.build_assoc(group, :testbeds)&lt;br /&gt;
&lt;br /&gt;
App.Group.create_group(testbeds)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
group = App.Groups.get_group!(1)&lt;br /&gt;
thing = Ecto.build_assoc(group, :testbeds, name: &amp;quot;DUMB&amp;quot;)&lt;br /&gt;
alias App.{Repo}&lt;br /&gt;
Repo.insert(thing)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
avatar = %Avatar{nick_name: &amp;quot;Elixir&amp;quot;, pic_url: &amp;quot;http://elixir-lang.org/images/logo.png&amp;quot;}&lt;br /&gt;
user = %User{name: &amp;quot;John Doe&amp;quot;, email: &amp;quot;john.doe@example.com&amp;quot;, avatar: avatar}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://www.reddit.com/r/elixir/comments/oh318k/is_there_a_way_to_avoid_ectoassociationnotloaded/h4mmcfi/?utm_source=share&amp;amp;utm_medium=web3x&amp;amp;utm_name=web3xcss&amp;amp;utm_term=1&amp;amp;utm_content=share_button&lt;br /&gt;
&lt;br /&gt;
# Create Group Table&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
mix phx.gen.html Groups Group groups name:string  &lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Set the resources / &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
mix ecto.migrate&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For testbeds create a migration file and add this field:   group_id:references:groups&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
def change do&lt;br /&gt;
    alter table(:testbeds) do    # customize to your code&lt;br /&gt;
      add :group_id, references(:groups)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Update Groups Schema (Don't forget alias / has_many)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule App.Groups.Group do&lt;br /&gt;
	use Ecto.Schema&lt;br /&gt;
	import Ecto.Changeset&lt;br /&gt;
	alias App.Testbeds.Testbed   # Alias!&lt;br /&gt;
&lt;br /&gt;
	schema &amp;quot;posts&amp;quot; do&lt;br /&gt;
		field :body, :string&lt;br /&gt;
		field :title, :string&lt;br /&gt;
		has_many :testbeds, Testbed    # Has many&lt;br /&gt;
&lt;br /&gt;
		timestamps()&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	@doc false&lt;br /&gt;
	def changeset(post, attrs) do&lt;br /&gt;
		post&lt;br /&gt;
		|&amp;gt; cast(attrs, [:title, :body])&lt;br /&gt;
		|&amp;gt; validate_required([:title, :body])&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
TESTBEDS Schema&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule App.Testbeds.Testbed do&lt;br /&gt;
  use Ecto.Schema&lt;br /&gt;
  import Ecto.Changeset&lt;br /&gt;
  alias App.Groups.Group      # Alias&lt;br /&gt;
  schema &amp;quot;testbeds&amp;quot; do&lt;br /&gt;
    field :name, :string&lt;br /&gt;
    belongs_to :group, Group    # Belongs to&lt;br /&gt;
    timestamps()&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  @doc false&lt;br /&gt;
  def changeset(testbed, attrs) do&lt;br /&gt;
    testbed&lt;br /&gt;
    |&amp;gt; cast(attrs, [:name])&lt;br /&gt;
    |&amp;gt; validate_required([:name])&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
_____________________________________&lt;br /&gt;
Side notes.&lt;br /&gt;
&lt;br /&gt;
defmodule App.Repo.Migrations.CreateTestbeds do&lt;br /&gt;
  use Ecto.Migration&lt;br /&gt;
&lt;br /&gt;
  def change do&lt;br /&gt;
    create table(:testbeds) do&lt;br /&gt;
      add :name, :string&lt;br /&gt;
      add :group_id, references(:groups, on_delete: :nothing)&lt;br /&gt;
&lt;br /&gt;
      timestamps()&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    create index(:testbeds, [:group_id])&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
________________________________&lt;br /&gt;
&lt;br /&gt;
mix phx.gen.context Comments Comment comments name:string content:text post_id:references:posts&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
mix phx.gen.html Testbeds Testbed testbeds name:string  group_id:references:groups&lt;br /&gt;
&lt;br /&gt;
https://graffino.com/web-development/first-steps-in-elixir-and-phoenix-create-a-blog-prototype&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://blog.logrocket.com/getting-started-ecto-phoenix/&lt;br /&gt;
&lt;br /&gt;
https://serokell.io/blog/ecto-guide-for-beginners&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
mix phx.gen.html Testbeds Testbed testbeds name:string&lt;br /&gt;
&lt;br /&gt;
mix phx.gen.html Groups Group groups name:string&lt;br /&gt;
&lt;br /&gt;
Create migration for &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
mix ecto.gen.migration add_testbed_group_reference&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Migration:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  def change do&lt;br /&gt;
    alter table(:testbeds) do    # customize to your code&lt;br /&gt;
      add :group_id, references(:groups)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Manually Change:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule App.Group do&lt;br /&gt;
  use Ecto.Schema&lt;br /&gt;
&lt;br /&gt;
  schema &amp;quot;groups&amp;quot; do&lt;br /&gt;
    field :title, :string&lt;br /&gt;
    field :tagline, :string&lt;br /&gt;
    has_many :testbeds, App.Testbed&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
testbeds&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule App.Repo.Migrations.AddTextbedGroups do&lt;br /&gt;
  use Ecto.Migration&lt;br /&gt;
&lt;br /&gt;
  def change do&lt;br /&gt;
    create table(:testbeds) do&lt;br /&gt;
      add :name, :string&lt;br /&gt;
      add :group_id, references(:groups)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
# lib/app/testbeds.ex&lt;br /&gt;
&lt;br /&gt;
defmodule App.Testbed do&lt;br /&gt;
  use Ecto.Schema&lt;br /&gt;
&lt;br /&gt;
  schema &amp;quot;testbedss&amp;quot; do&lt;br /&gt;
    field :name, :string&lt;br /&gt;
    belongs_to :group, App.Group&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_____________________&lt;br /&gt;
&lt;br /&gt;
%App.TestBeds.TestBed{&lt;br /&gt;
  __meta__: #Ecto.Schema.Metadata&amp;lt;:loaded, &amp;quot;testbeds&amp;quot;&amp;gt;,&lt;br /&gt;
  id: 1,&lt;br /&gt;
  developer: &amp;quot;None&amp;quot;,&lt;br /&gt;
  name: &amp;quot;sdfsd&amp;quot;,&lt;br /&gt;
  owner: &amp;quot;sdfsddf&amp;quot;,&lt;br /&gt;
  note: &amp;quot;sdsfsddf&amp;quot;,&lt;br /&gt;
  status: &amp;quot;Available&amp;quot;,&lt;br /&gt;
  url: &amp;quot;sdf&amp;quot;,&lt;br /&gt;
  version: &amp;quot;ddf&amp;quot;,&lt;br /&gt;
  manager: &amp;quot;sf&amp;quot;,&lt;br /&gt;
  inserted_at: ~N[2023-08-21 13:45:39],&lt;br /&gt;
  updated_at: ~N[2023-08-21 13:45:44]&lt;br /&gt;
}&lt;br /&gt;
________________________________________________________________---&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.SendLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  &lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    {:ok, socket}&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  def handle_event(&amp;quot;send&amp;quot;, %{&amp;quot;text&amp;quot; =&amp;gt; text}, socket) do&lt;br /&gt;
&lt;br /&gt;
    AppWeb.Endpoint.broadcast(topic, &amp;quot;message&amp;quot;, text)&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  defp topic do&lt;br /&gt;
    &amp;quot;chat&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def render(assigns)do   &lt;br /&gt;
   ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
  &amp;lt;h1&amp;gt;Send Message&amp;lt;/h1&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;form phx-submit=&amp;quot;send&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;text&amp;quot; /&amp;gt;&lt;br /&gt;
    &amp;lt;button type=&amp;quot;submit&amp;quot;&amp;gt;Send&amp;lt;/button&amp;gt;&lt;br /&gt;
  &amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
______________________________________________________________&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.ReceiveLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  &lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    if connected?(socket) do&lt;br /&gt;
      AppWeb.Endpoint.subscribe(topic)&lt;br /&gt;
    end&lt;br /&gt;
    {:ok, assign(socket, messages: &amp;quot;&amp;quot;)}&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def handle_info(%{event: &amp;quot;message&amp;quot;, payload: message}, socket) do&lt;br /&gt;
    IO.inspect message&lt;br /&gt;
    {:noreply, assign(socket, messages: message)}&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  defp topic do&lt;br /&gt;
    &amp;quot;chat&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns)do   &lt;br /&gt;
   ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
  &amp;lt;h1&amp;gt;ChatLive&amp;lt;/h1&amp;gt;&lt;br /&gt;
  &amp;lt;%= @messages %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
______________________________________________________________&lt;br /&gt;
When you hover over a list of items this hook finds items with the same name and sets the opacity of all others to 0. You see all the items similar to the one you are hovering over.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
TestbedVersionHover: {&lt;br /&gt;
			// https://jsfiddle.net/IrvinDominin/7K2Z3/&lt;br /&gt;
            mounted() {&lt;br /&gt;
&lt;br /&gt;
                let rows = document.getElementsByClassName(&amp;quot;testbed-version&amp;quot;)&lt;br /&gt;
                // this.ele = element&lt;br /&gt;
				// rows = this.ele;&lt;br /&gt;
                &lt;br /&gt;
				for (var i = 0; i &amp;lt; rows.length; i++) {&lt;br /&gt;
					rows[i].onmouseenter = function (event) {&lt;br /&gt;
						for (var j = 0; j &amp;lt; rows.length; j++) {&lt;br /&gt;
							let preversion = this.textContent;&lt;br /&gt;
							let version = preversion.slice(0,5)&lt;br /&gt;
							let compareVersion = rows[j].textContent.slice(0,5)&lt;br /&gt;
							if (compareVersion === version) continue&lt;br /&gt;
							rows[j].className += &amp;quot; other&amp;quot;;&lt;br /&gt;
						}&lt;br /&gt;
					};&lt;br /&gt;
				&lt;br /&gt;
					rows[i].onmouseleave = function (event) {&lt;br /&gt;
						var hovers = document.getElementsByClassName('other');&lt;br /&gt;
						var len = hovers.length;&lt;br /&gt;
						for (var j = 0; j &amp;lt; len; j++) {&lt;br /&gt;
							hovers[0].className = hovers[0].className.replace(/\sother(\s|$)/, '');&lt;br /&gt;
						}&lt;br /&gt;
					};&lt;br /&gt;
				}&lt;br /&gt;
&lt;br /&gt;
                // this.ele.addEventListener(&amp;quot;click&amp;quot;, (e) =&amp;gt; {&lt;br /&gt;
                //     console.log(e.target)&lt;br /&gt;
                    &lt;br /&gt;
                // });&lt;br /&gt;
&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* How to Create Database Seed Data.&lt;br /&gt;
* How to structure code so controller code is in one file and HTML Heex is in another&lt;br /&gt;
* How to Use Generators in a Real World Project&lt;br /&gt;
* How to Work with Database Data via Basic Commands and Custom Change sets.&lt;br /&gt;
* How to Render Database Data to LiveView (via Context Commands).&lt;br /&gt;
* How to Create a Chat using PubSub.&lt;br /&gt;
* How to Create Event Handlers in LiveView&lt;br /&gt;
* How to Create a Dynamic Route from Scratch.&lt;br /&gt;
* How to Use Elixirs Template language&lt;br /&gt;
* How to Work with Modal&lt;br /&gt;
* How to Use CSS From Scratch (Without bundler)&lt;br /&gt;
* How to use JS hooks&lt;br /&gt;
* Dissect Table Component and Update it to Order List in Reverse.&lt;br /&gt;
&lt;br /&gt;
Selenium&lt;br /&gt;
https://www.builder.io/blog/debug-nodejs&lt;br /&gt;
&lt;br /&gt;
https://marketplace.visualstudio.com/items?itemName=ms-vscode.live-server#running-the-extension&lt;br /&gt;
&lt;br /&gt;
This was added recently (see microsoft/vscode#109276).&lt;br /&gt;
    1. Open the palette (Ctrl + Shift + P)&lt;br /&gt;
    2. Select &amp;quot;Simple Browser: Preview&amp;quot;&lt;br /&gt;
    3. Enter web address&lt;br /&gt;
&lt;br /&gt;
_______________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
const {By, Key, Builder} = require(&amp;quot;selenium-webdriver&amp;quot;);&lt;br /&gt;
const assert = require(&amp;quot;assert&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
require(&amp;quot;chromedriver&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
async function test_case(){&lt;br /&gt;
  let driver = await new Builder().forBrowser(&amp;quot;chrome&amp;quot;).build();&lt;br /&gt;
  await driver.get(&amp;quot;sie&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  await driver.findElement(By.name('password')).clear();&lt;br /&gt;
  await driver.findElement(By.name('identification')).clear();&lt;br /&gt;
  await driver.findElement(By.name('identification')).sendKeys(&amp;quot;bill&amp;quot;);&lt;br /&gt;
  await driver.findElement(By.name('password')).sendKeys(&amp;quot;password&amp;quot;, Key.RETURN);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 setTimeout(()=&amp;gt;{&lt;br /&gt;
   driver.findElement(By.className(&amp;quot;req_lan_license&amp;quot;)).click();&lt;br /&gt;
 },5000)&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageLive do &lt;br /&gt;
&lt;br /&gt;
  use AppWeb, :live_view  &lt;br /&gt;
  alias App.Testbeds &lt;br /&gt;
  def mount(_params, _session, socket)do   &lt;br /&gt;
     {:ok, assign(socket, testbeds: Testbeds.list_testbeds())}   &lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
    def button_event(&amp;quot;invoke_editing&amp;quot;) do&lt;br /&gt;
    %JS{}&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;active&amp;quot;, to: &amp;quot;#editing_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#editing_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#preview_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;active&amp;quot;, to: &amp;quot;#preview_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;active&amp;quot;, to: &amp;quot;#preview&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#preview&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#editing&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;active&amp;quot;, to: &amp;quot;#editing&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def button_event(&amp;quot;invoke_preview&amp;quot;) do&lt;br /&gt;
    %JS{}&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;active&amp;quot;, to: &amp;quot;#preview_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#preview_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#editing_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;active&amp;quot;, to: &amp;quot;#editing_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;active&amp;quot;, to: &amp;quot;#editing&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#editing&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#preview&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;active&amp;quot;, to: &amp;quot;#preview&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;send&amp;quot;, params, socket) do&lt;br /&gt;
    hide_modal(&amp;quot;notes-modal-0&amp;quot;)&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do  &lt;br /&gt;
     ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
		&amp;lt;.modal id={&amp;quot;notes-modal-#{testbed.id}&amp;quot;}&amp;gt;&lt;br /&gt;
		    &amp;lt;.button phx-click={button_event(&amp;quot;invoke_editing&amp;quot;)} id=&amp;quot;editing_button&amp;quot; class=&amp;quot;hidden&amp;quot;&amp;gt;&lt;br /&gt;
		      Preview&lt;br /&gt;
		    &amp;lt;/.button&amp;gt;&lt;br /&gt;
		    &amp;lt;.button phx-click={button_event(&amp;quot;invoke_preview&amp;quot;)} id=&amp;quot;preview_button&amp;quot;&amp;gt;&lt;br /&gt;
		      Edit Me&lt;br /&gt;
		    &amp;lt;/.button&amp;gt;&lt;br /&gt;
		    &amp;lt;div id=&amp;quot;editing&amp;quot;&amp;gt; PREVIEWING THE WORK&amp;lt;/div&amp;gt;&lt;br /&gt;
		    &amp;lt;form phx-submit = &amp;quot;send&amp;quot;   id=&amp;quot;preview&amp;quot; class=&amp;quot;hidden&amp;quot;&amp;gt;&lt;br /&gt;
		      &amp;lt;textarea value = {testbed.note}&amp;gt;&amp;lt;/textarea&amp;gt;&lt;br /&gt;
		      &amp;lt;.button type=&amp;quot;submit&amp;quot; phx-click={hide_modal(&amp;quot;notes-modal-#{testbed.id}&amp;quot;)}&amp;gt;SAVE WORK&amp;lt;/.button&amp;gt;&lt;br /&gt;
		    &amp;lt;/form&amp;gt;&lt;br /&gt;
		&amp;lt;/.modal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;%= if testbed.note do %&amp;gt;&lt;br /&gt;
      &amp;lt;div phx-click={show_modal(&amp;quot;notes-modal-#{testbed.id}&amp;quot;)}&amp;gt;READ ME  ...&amp;lt;%= testbed.note %&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
	   &lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
       &lt;br /&gt;
      &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
import {HfInference} from &amp;quot;@huggingface/inference&amp;quot;;&lt;br /&gt;
import dotenv from &amp;quot;dotenv&amp;quot;;&lt;br /&gt;
dotenv.config()&lt;br /&gt;
&lt;br /&gt;
const HF_ACCESS_TOKEN = process.env.HF_ACCESS_TOKEN&lt;br /&gt;
&lt;br /&gt;
const hf = new HfInference(HF_ACCESS_TOKEN);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*______Uncomment for this example______________________&lt;br /&gt;
&lt;br /&gt;
const model = &amp;quot;nlpconnect/vit-gpt2-image-captioning&amp;quot;;&lt;br /&gt;
const imageURL = &amp;quot;https://i.imgur.com/lTvb7Et.png&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
const response = await fetch(imageURL);&lt;br /&gt;
const imageBlob = await response.blob();&lt;br /&gt;
&lt;br /&gt;
const result  = await hf.imageToText({&lt;br /&gt;
	data: imageBlob,&lt;br /&gt;
	model: model,&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
_______________________________________________________*/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*________Another example ___________________*/&lt;br /&gt;
&lt;br /&gt;
const result = await hf.summarization({&lt;br /&gt;
	model: 'facebook/bart-large-cnn',&lt;br /&gt;
	inputs: &amp;quot;The role of a dumb man is to get smarter oogy bookie boo&amp;quot;,&lt;br /&gt;
	parameters:{&lt;br /&gt;
		max_length: 100&lt;br /&gt;
	}&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
console.log(result);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
________________________________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://fly.io/phoenix-files/sdeb-toggling-element/&lt;br /&gt;
https://www.youtube.com/watch?v=vBgZvQapqhs&lt;br /&gt;
&lt;br /&gt;
https://blog.testdouble.com/posts/2022-11-28-how-to-use-javascript-with-phoenix-liveview/&lt;br /&gt;
&lt;br /&gt;
https://hexdocs.pm/phoenix_live_view/0.19.3/Phoenix.Component.html&lt;br /&gt;
_______________________________________&lt;br /&gt;
https://www.smashingmagazine.com/2011/10/quick-look-math-animations-javascript/&lt;br /&gt;
* Depth first traversal&lt;br /&gt;
* Breadth first traversal&lt;br /&gt;
&lt;br /&gt;
https://dev.to/codesphere/10-algorithms-every-developer-should-learn-3lnm&lt;br /&gt;
&lt;br /&gt;
https://www.youtube.com/watch?v=fPz40W9mfCg&lt;br /&gt;
&lt;br /&gt;
__________________________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.GroupLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  alias App.TestBeds&lt;br /&gt;
  alias App.Groups&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    {:ok, assign(socket, testbeds: TestBeds.list_testbeds(), groups: Groups.list_groups())}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;select-group&amp;quot;, params, socket)  do  &lt;br /&gt;
         &lt;br /&gt;
       IO.inspect params&lt;br /&gt;
       {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div class=&amp;quot;grid grid-columns-2 grid-flow-col gap-4&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;column-1&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;%= testbed.name %&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;column-2&amp;quot;&amp;gt;    &lt;br /&gt;
            &amp;lt;form phx-change=&amp;quot;select-group&amp;quot;  &amp;gt;&lt;br /&gt;
               &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;testbed_id&amp;quot; value={testbed.id}/&amp;gt;&lt;br /&gt;
               &amp;lt;select id=&amp;quot;group-selection&amp;quot;  name=&amp;quot;group-id&amp;quot; &amp;gt;&lt;br /&gt;
                &amp;lt;%= for group &amp;lt;- @groups do %&amp;gt;&lt;br /&gt;
                  &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}  &amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
               &amp;lt;/select&amp;gt;&lt;br /&gt;
            &amp;lt;/form&amp;gt;&lt;br /&gt;
         &amp;lt;/div&amp;gt;&lt;br /&gt;
       &amp;lt;% end %&amp;gt;&lt;br /&gt;
   &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
____________________________&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.GroupLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  alias App.TestBeds&lt;br /&gt;
  alias App.Groups&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
&lt;br /&gt;
    {:ok, assign(socket, testbeds: TestBeds.list_testbeds(), groups: Groups.list_groups(), messages: [])}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;select-group&amp;quot;, params, socket)  do  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
      group = App.Groups.get_group!(params[&amp;quot;group-id&amp;quot;])&lt;br /&gt;
       # IO.inspect group&lt;br /&gt;
       testbed = App.TestBeds.get_test_bed!(params[&amp;quot;testbed_id&amp;quot;])&lt;br /&gt;
     &lt;br /&gt;
       App.TestBeds.update_test_bed(testbed, %{group_id: group.id})&lt;br /&gt;
         &lt;br /&gt;
    &lt;br /&gt;
       {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def updated_groups(testbed_id)  do  &lt;br /&gt;
       groups = App.Groups.list_groups&lt;br /&gt;
       tail = Enum.filter(groups, fn(item)-&amp;gt; item.id !== testbed_id end)&lt;br /&gt;
       head = Enum.filter(groups, fn(item)-&amp;gt; item.id == testbed_id end)&lt;br /&gt;
              |&amp;gt;Enum.at(0)&lt;br /&gt;
     [head | tail]&lt;br /&gt;
         &lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
 # def handle_event(&amp;quot;groups&amp;quot;, params, socket)do  &lt;br /&gt;
 #       selected_testbed = %{name: &amp;quot;my testbed name&amp;quot;, id: 3}&lt;br /&gt;
 #       groups = App.Groups.list_groups&lt;br /&gt;
 #       tail = Enum.filter(groups, fn(item)-&amp;gt; item.id !== selected_testbed.id end)&lt;br /&gt;
 #       head = Enum.filter(groups, fn(item)-&amp;gt; item.id == selected_testbed.id end)&lt;br /&gt;
 #              |&amp;gt;Enum.at(0)&lt;br /&gt;
         &lt;br /&gt;
 &lt;br /&gt;
 #       # result = Enum.filter([1, 2, 3], fn x -&amp;gt; x.id !== 1 end)&lt;br /&gt;
 #      IO.inspect [head | tail]&lt;br /&gt;
         &lt;br /&gt;
 #      #&lt;br /&gt;
 #      {:noreply, socket, assigns.message:}&lt;br /&gt;
 #  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    &lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
       &amp;lt;%!-- &amp;lt;div phx-click = &amp;quot;groups&amp;quot;&amp;gt;CLICK ME&amp;lt;/div&amp;gt; --%&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;grid grid-cols-4 gap-4 p-8 rounded shadow bg-white&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;h2&amp;gt; Name&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;%= testbed.name %&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;h2&amp;gt; Group&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;form phx-change=&amp;quot;select-group&amp;quot; name=&amp;quot;testbed_id&amp;quot;  &amp;gt;&lt;br /&gt;
               &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;testbed_id&amp;quot; value={testbed.id}/&amp;gt;&lt;br /&gt;
               &amp;lt;select id=&amp;quot;group-selection&amp;quot;  name=&amp;quot;group-id&amp;quot; class=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
                &amp;lt;%= for group &amp;lt;- updated_groups(testbed.id) do %&amp;gt;&lt;br /&gt;
                  &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}  &amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
                  &amp;lt;!-- Write code to reorder with testbed.group_id matching group_id --&amp;gt;&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
               &amp;lt;/select&amp;gt;&lt;br /&gt;
            &amp;lt;/form&amp;gt;&lt;br /&gt;
          &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
       &amp;lt;% end %&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_____________________________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
   use AppWeb, :live_view  &lt;br /&gt;
     alias App.Testbeds&lt;br /&gt;
  alias App.Groups&lt;br /&gt;
   def mount(_params, _session, socket)  do&lt;br /&gt;
	     {:ok, assign(socket, testbeds: Testbeds.list_testbeds(), groups: Groups.list_groups())}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
   def handle_event(&amp;quot;select-group&amp;quot;, params, socket)  do  &lt;br /&gt;
       group = App.Groups.get_group!(params[&amp;quot;group-id&amp;quot;])&lt;br /&gt;
       testbed = App.Testbeds.get_testbed!(params[&amp;quot;testbed_id&amp;quot;])&lt;br /&gt;
       result = App.Testbeds.update_testbed(testbed, %{group_id: group.id})&lt;br /&gt;
       IO.inspect result&lt;br /&gt;
      &lt;br /&gt;
       {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
    def updated_groups(testbed_id)  do  &lt;br /&gt;
       testbed = App.Testbeds.get_testbed!(testbed_id)&lt;br /&gt;
       groups = App.Groups.list_groups&lt;br /&gt;
       tail = Enum.filter(groups, fn(item)-&amp;gt; item.id !== testbed.group_id end)&lt;br /&gt;
       head = Enum.filter(groups, fn(item)-&amp;gt; item.id == testbed.group_id end)&lt;br /&gt;
              |&amp;gt;Enum.at(0)&lt;br /&gt;
 &lt;br /&gt;
       [head | tail]&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    &lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;grid grid-cols-4 gap-4 p-8 rounded shadow bg-white&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;h2&amp;gt; Name&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;%= testbed.name %&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;h2&amp;gt; Group&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;form phx-change=&amp;quot;select-group&amp;quot; name=&amp;quot;testbed_id&amp;quot;  &amp;gt;&lt;br /&gt;
               &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;testbed_id&amp;quot; value={testbed.id}/&amp;gt;&lt;br /&gt;
               &amp;lt;select id=&amp;quot;group-selection&amp;quot;  name=&amp;quot;group-id&amp;quot; class=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
                &amp;lt;%= for group &amp;lt;- updated_groups(testbed.id) do %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
                  &amp;lt;%!-- &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}&amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt; --%&amp;gt;&lt;br /&gt;
                  &amp;lt;!-- Write code to reorder with testbed.group_id matching group_id --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
                  &amp;lt;%= if group !== nil do %&amp;gt;&lt;br /&gt;
                      &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}&amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
       &lt;br /&gt;
                  &amp;lt;% end %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
               &amp;lt;/select&amp;gt;&lt;br /&gt;
            &amp;lt;/form&amp;gt;&lt;br /&gt;
          &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
       &amp;lt;% end %&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  has_many :testbeds, TestBed, on_delete: :restrict   # Has many&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://elixirforum.com/t/ecto-has-many-on-delete-protect/49550&lt;br /&gt;
&lt;br /&gt;
https://hexdocs.pm/ecto/Ecto.Changeset.html#unique_constraint/3&lt;br /&gt;
&lt;br /&gt;
____________________________________________________________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== How to Create a Mix Project and Use It in Another Mix Project ==&lt;br /&gt;
&lt;br /&gt;
To create and use a **Mix project** inside another **Mix project** in Elixir, follow the steps below:&lt;br /&gt;
&lt;br /&gt;
=== 1. Create a New Mix Project ===&lt;br /&gt;
&lt;br /&gt;
First, you need to create a new Mix project. Let's call this project `library_project`. Run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mix new library_project --module LibraryProject&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will create a new Elixir Mix project named `library_project`. The `--module` flag specifies the name of the module that will be created (in this case `LibraryProject`).&lt;br /&gt;
&lt;br /&gt;
The directory structure of `library_project` will look like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
library_project/&lt;br /&gt;
  |_ lib/&lt;br /&gt;
      |_ library_project.ex&lt;br /&gt;
  |_ mix.exs&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can then add some basic functionality inside the `library_project/lib/library_project.ex` file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule LibraryProject do&lt;br /&gt;
  def hello do&lt;br /&gt;
    IO.puts &amp;quot;Hello from LibraryProject!&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now, `library_project` is ready to be used by another Mix project.&lt;br /&gt;
&lt;br /&gt;
=== 2. Create a Second Mix Project ===&lt;br /&gt;
&lt;br /&gt;
Next, create the second Mix project where you want to use `library_project`. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mix new app_project --module AppProject&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will create another Elixir project called `app_project`.&lt;br /&gt;
&lt;br /&gt;
The directory structure for this project will look like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
app_project/&lt;br /&gt;
  |_ lib/&lt;br /&gt;
      |_ app_project.ex&lt;br /&gt;
  |_ mix.exs&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 3. Add `library_project` as a Dependency in `app_project` ===&lt;br /&gt;
&lt;br /&gt;
Now, you want to make `library_project` available in `app_project`. There are two main ways to do this:&lt;br /&gt;
&lt;br /&gt;
==== Option 1: Local Dependency (via `path`) ====&lt;br /&gt;
&lt;br /&gt;
If `library_project` is a local project (i.e., it's stored in a different directory), you can add it to the `mix.exs` of `app_project` as a local dependency by specifying the path to `library_project`.&lt;br /&gt;
&lt;br /&gt;
Edit the `mix.exs` of `app_project`:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule AppProject.MixProject do&lt;br /&gt;
  use Mix.Project&lt;br /&gt;
&lt;br /&gt;
  def project do&lt;br /&gt;
    [&lt;br /&gt;
      app: :app_project,&lt;br /&gt;
      version: &amp;quot;0.1.0&amp;quot;,&lt;br /&gt;
      elixir: &amp;quot;~&amp;gt; 1.14&amp;quot;,&lt;br /&gt;
      start_permanent: Mix.env() == :prod,&lt;br /&gt;
      deps: deps()&lt;br /&gt;
    ]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  defp deps do&lt;br /&gt;
    [&lt;br /&gt;
      {:library_project, path: &amp;quot;../library_project&amp;quot;}  # Add the local dependency&lt;br /&gt;
    ]&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here, `{:library_project, path: &amp;quot;../library_project&amp;quot;}` tells Mix to use the local `library_project` located in the `../library_project` directory (relative to `app_project`).&lt;br /&gt;
&lt;br /&gt;
After updating the `mix.exs`, run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd app_project&lt;br /&gt;
mix deps.get&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will fetch the dependency and compile `library_project`.&lt;br /&gt;
&lt;br /&gt;
==== Option 2: Publish and Fetch as a Hex Package ====&lt;br /&gt;
&lt;br /&gt;
If you want to use `library_project` as a package in another project (for example, by publishing it to **Hex.pm**, Elixir’s package manager), you need to publish it to Hex and then add it as a dependency.&lt;br /&gt;
&lt;br /&gt;
1. Publish `library_project` to Hex (if it's public or for your private use).&lt;br /&gt;
2. Add `library_project` to your `app_project`’s `mix.exs` dependencies:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defp deps do&lt;br /&gt;
  [&lt;br /&gt;
    {:library_project, &amp;quot;~&amp;gt; 0.1.0&amp;quot;}  # Specify the published version from Hex&lt;br /&gt;
  ]&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Run `mix deps.get` to fetch the package from Hex.&lt;br /&gt;
&lt;br /&gt;
=== 4. Use `library_project` in `app_project` ===&lt;br /&gt;
&lt;br /&gt;
Now, you can use the functionality from `library_project` inside your `app_project`. For example, in `app_project/lib/app_project.ex`, you can call the function from `library_project`:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule AppProject do&lt;br /&gt;
  def start do&lt;br /&gt;
    IO.puts &amp;quot;Starting app_project!&amp;quot;&lt;br /&gt;
    LibraryProject.hello()  # Call the function from the library_project&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 5. Run the App ===&lt;br /&gt;
&lt;br /&gt;
Finally, you can run your `app_project`:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd app_project&lt;br /&gt;
mix run -e &amp;quot;AppProject.start()&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will print:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Starting app_project!&lt;br /&gt;
Hello from LibraryProject!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Recap of the Process ==&lt;br /&gt;
1. **Create the `library_project`**: Use `mix new` to generate a library project.&lt;br /&gt;
2. **Create the `app_project`**: Create the second project where you will use the library.&lt;br /&gt;
3. **Add the `library_project` as a dependency**:&lt;br /&gt;
   - Use the `path` option to point to the local project or publish it to Hex for public access.&lt;br /&gt;
4. **Use the `library_project` in the `app_project`**: Call functions or use modules from the library inside the second project.&lt;br /&gt;
5. **Run the app**: Use `mix run` to execute the project.&lt;br /&gt;
&lt;br /&gt;
This way, you can reuse code from one Mix project in another by adding it as a dependency.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==z==&lt;br /&gt;
Overloaded functions are extremely common in Elixir applications. They are&lt;br /&gt;
regularly used for recursive functions and for changing behavior based on&lt;br /&gt;
configuration.&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>http://elixirblocks.com/index.php?title=User:Admin&amp;diff=1882</id>
		<title>User:Admin</title>
		<link rel="alternate" type="text/html" href="http://elixirblocks.com/index.php?title=User:Admin&amp;diff=1882"/>
		<updated>2025-03-11T20:47:39Z</updated>

		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;https://app.studyraid.com/en/read/11967/381872/component-communication&lt;br /&gt;
&lt;br /&gt;
https://thepugautomatic.com/2020/08/communicating-between-liveviews-on-the-same-page/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
from(a in Article,&lt;br /&gt;
  order_by: [desc: a.inserted_at],  # Assuming 'inserted_at' is the timestamp for when the article was created or updated&lt;br /&gt;
  limit: 8&lt;br /&gt;
)&lt;br /&gt;
|&amp;gt; Repo.all()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.Landing do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  alias App.Testbeds&lt;br /&gt;
  alias App.Testbeds.Testbed&lt;br /&gt;
  alias App.Repo  # Ensure to alias Repo&lt;br /&gt;
  import Ecto.Query  # Import Ecto.Query to work with queries&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    # Default to ordering by name&lt;br /&gt;
    testbeds = Repo.all(from(t in Testbed, order_by: t.name))&lt;br /&gt;
&lt;br /&gt;
    # Assign the testbeds to the socket for rendering&lt;br /&gt;
    {:ok, assign(socket, testbeds: testbeds, sort: :name)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    &amp;lt;h1&amp;gt;Hello World! YAY&amp;lt;/h1&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;div&amp;gt;&lt;br /&gt;
      &amp;lt;!-- Buttons to toggle sorting --&amp;gt;&lt;br /&gt;
      &amp;lt;button phx-click=&amp;quot;sort_by_name&amp;quot;&amp;gt;Sort by Name&amp;lt;/button&amp;gt;&lt;br /&gt;
      &amp;lt;button phx-click=&amp;quot;sort_by_updated_at&amp;quot;&amp;gt;Sort by Updated By&amp;lt;/button&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;ul&amp;gt;&lt;br /&gt;
      &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
        &amp;lt;li&amp;gt;&amp;lt;%= testbed.name %&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;% end %&amp;gt;&lt;br /&gt;
    &amp;lt;/ul&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;sort_by_name&amp;quot;, _params, socket) do&lt;br /&gt;
    testbeds = Repo.all(from(t in Testbed, order_by: t.name))&lt;br /&gt;
    {:noreply, assign(socket, testbeds: testbeds, sort: :name)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;sort_by_updated_at&amp;quot;, _params, socket) do&lt;br /&gt;
    testbeds = Repo.all(from(t in Testbed, order_by: t.inserted_at))&lt;br /&gt;
    {:noreply, assign(socket, testbeds: testbeds, sort: :inserted_at)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
_______________________________________________________&lt;br /&gt;
&lt;br /&gt;
* Create a form with a post request. &lt;br /&gt;
* Create the route needed for that request&lt;br /&gt;
* Create the controller needed for that route&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Form==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;.form action={~p&amp;quot;/todos&amp;quot;} method=&amp;quot;post&amp;quot; class=&amp;quot;mt-10 space-y-8&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    &amp;lt;label for=&amp;quot;contact_name&amp;quot; class=&amp;quot;block text-sm font-semibold leading-6 text-zinc-800&amp;quot;&amp;gt;&lt;br /&gt;
      Name&lt;br /&gt;
    &amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;input&lt;br /&gt;
      id=&amp;quot;todo&amp;quot;&lt;br /&gt;
      type=&amp;quot;text&amp;quot;&lt;br /&gt;
      name=&amp;quot;todo&amp;quot;&lt;br /&gt;
      class=&amp;quot;mt-2 block w-full rounded-lg text-zinc-900 focus:ring-0 sm:text-sm sm:leading-6 border-zinc-300 focus:border-zinc-400&amp;quot;&lt;br /&gt;
    /&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;button&lt;br /&gt;
    type=&amp;quot;submit&amp;quot;&lt;br /&gt;
    class=&amp;quot;rounded-lg bg-zinc-900 hover:bg-zinc-700 py-2 px-3 text-sm font-semibold leading-6 text-white active:text-white/80&amp;quot;&lt;br /&gt;
  &amp;gt;&lt;br /&gt;
    Save Contact&lt;br /&gt;
  &amp;lt;/button&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/.form&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Controller==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# In your TodoController&lt;br /&gt;
defmodule AppWeb.TodoController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  # Action to handle the form submission (POST request)&lt;br /&gt;
  def create(conn, %{&amp;quot;todo&amp;quot; =&amp;gt; todo_name}) do&lt;br /&gt;
    # Here you can handle the form data (e.g., save it to the database)&lt;br /&gt;
    IO.puts(&amp;quot;Received Todo: #{todo_name}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    # For now, let's just redirect to the home page&lt;br /&gt;
    conn&lt;br /&gt;
    |&amp;gt; put_flash(:info, &amp;quot;Todo saved!&amp;quot;)&lt;br /&gt;
    |&amp;gt; redirect(to: &amp;quot;/&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
________________________________________________________&lt;br /&gt;
&lt;br /&gt;
# CRUD Forms&lt;br /&gt;
&lt;br /&gt;
To understand CRUD forms you will need to understand the following concepts. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Ecto Schema&lt;br /&gt;
* Ecto Context&lt;br /&gt;
* Form Basics&lt;br /&gt;
* form/1&lt;br /&gt;
* simple_form/1&lt;br /&gt;
* changesets&lt;br /&gt;
&lt;br /&gt;
We are not going to go in order. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The Context provides CRUD functions for the chosen data schema. Phoenix contexts define the interface through which other parts of the codebase can interact with the app layer.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_______________________&lt;br /&gt;
* Create routes&lt;br /&gt;
* create page with form (submit get request)&lt;br /&gt;
&lt;br /&gt;
(ecto schema, context, changesets)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_______________________________________________________&lt;br /&gt;
In that case, you really should switch it to prod mode. Instead of doing all that above with the &amp;quot;config/secret.exs&amp;quot; file, create the &amp;quot;.env&amp;quot; in the project root, then add DotenvParser.load_file(&amp;quot;.env&amp;quot;) to &amp;quot;config/runtime.exs&amp;quot; as the first line inside the if config_env() == :prod do. In the .env file, set the DATABASE_URL and SECRET_KEY_BASE. Then run it as MIX_ENV=prod mix phx.server.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def get_titles do&lt;br /&gt;
    urls = [&lt;br /&gt;
      &amp;quot;https://cointelegraph.com/rss&amp;quot;,&lt;br /&gt;
      &amp;quot;https://chaski.huffpost.com/us/auto/vertical/us-news&amp;quot;&lt;br /&gt;
      # Add more RSS feed URLs here&lt;br /&gt;
    ]&lt;br /&gt;
&lt;br /&gt;
    urls&lt;br /&gt;
    |&amp;gt; Enum.map(fn url -&amp;gt;&lt;br /&gt;
      with {:ok, feed} &amp;lt;- ElixirRss.fetch_and_parse(url) do&lt;br /&gt;
        Enum.map(feed.entries, &amp;amp; &amp;amp;1.title)&lt;br /&gt;
      else&lt;br /&gt;
        {:error, reason} -&amp;gt; {:error, reason}&lt;br /&gt;
      end&lt;br /&gt;
    end)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule App do&lt;br /&gt;
&lt;br /&gt;
  def get_titles() do&lt;br /&gt;
    data = [&lt;br /&gt;
      &amp;quot;https://cointelegraph.com/rss&amp;quot;,&lt;br /&gt;
      &amp;quot;https://chaski.huffpost.com/us/auto/vertical/us-news&amp;quot;&lt;br /&gt;
      # Add more RSS feed URLs here&lt;br /&gt;
    ]&lt;br /&gt;
&lt;br /&gt;
    data&lt;br /&gt;
    |&amp;gt; Enum.map(fn url -&amp;gt;&lt;br /&gt;
      case ElixirRss.fetch_and_parse(url) do&lt;br /&gt;
        {:ok, feed} -&amp;gt; feed.entries |&amp;gt; Enum.map(fn entry -&amp;gt; entry end)&lt;br /&gt;
        {:error, reason} -&amp;gt; {:error, reason}&lt;br /&gt;
      end&lt;br /&gt;
    end)&lt;br /&gt;
    |&amp;gt; Enum.map(fn entry_list -&amp;gt;&lt;br /&gt;
      entry_list&lt;br /&gt;
      |&amp;gt; Enum.map(fn entry -&amp;gt; entry.title end)&lt;br /&gt;
    end)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def hello do&lt;br /&gt;
    rss_feeds = [&lt;br /&gt;
      &amp;quot;https://cointelegraph.com/rss&amp;quot;,&lt;br /&gt;
      &amp;quot;https://chaski.huffpost.com/us/auto/vertical/us-news&amp;quot;&lt;br /&gt;
      # Add more RSS feed URLs here&lt;br /&gt;
    ]&lt;br /&gt;
&lt;br /&gt;
    rss_feeds&lt;br /&gt;
    |&amp;gt; Enum.map(fn url -&amp;gt;&lt;br /&gt;
      case ElixirRss.fetch_and_parse(url) do&lt;br /&gt;
        {:ok, feed} -&amp;gt; feed.entries |&amp;gt; Enum.map(fn entry -&amp;gt; entry end)&lt;br /&gt;
        {:error, reason} -&amp;gt; {:error, reason}&lt;br /&gt;
      end&lt;br /&gt;
    end)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    if connected?(socket) do&lt;br /&gt;
      Phoenix.PubSub.subscribe(App.PubSub, &amp;quot;message&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
    {:ok, assign(socket, message_item: &amp;quot;different&amp;quot;)}&lt;br /&gt;
  end&lt;br /&gt;
  def handle_info({:pubsub_transmission, text}, socket) do&lt;br /&gt;
    IO.inspect &amp;quot;pub sub working&amp;quot;&lt;br /&gt;
    {:noreply, assign(socket, message_item: text)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def loop(data) do&lt;br /&gt;
     IO.inspect data&lt;br /&gt;
     if data &amp;gt; 0 do&lt;br /&gt;
      IO.inspect &amp;quot;notify&amp;quot;&lt;br /&gt;
      # run code to compare files, loop. If different run pubsub code below&lt;br /&gt;
      :timer.sleep(2000)&lt;br /&gt;
      loop(data-1)&lt;br /&gt;
&lt;br /&gt;
     end&lt;br /&gt;
     if data &amp;lt;= 0 do&lt;br /&gt;
&lt;br /&gt;
      Phoenix.PubSub.broadcast(App.PubSub, &amp;quot;message&amp;quot;, {:pubsub_transmission, &amp;quot;data&amp;quot;})&lt;br /&gt;
      &amp;quot;done&amp;quot;&lt;br /&gt;
     end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;change-text&amp;quot;, _params, socket) do&lt;br /&gt;
    spawn(fn -&amp;gt; loop(3) end)&lt;br /&gt;
    {:noreply, assign(socket, message_item: &amp;quot;START&amp;quot; )}&lt;br /&gt;
  end&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
&lt;br /&gt;
    # AppWeb.PageLive.loop(&amp;quot;xxx&amp;quot;)&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    SANDBOX&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;.button phx-click=&amp;quot;change-text&amp;quot; value={@message_item}&amp;gt;CLICK ME&amp;lt;/.button&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;%= @message_item %&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
elixir :   1.16.2&lt;br /&gt;
&lt;br /&gt;
Erl:   20&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# PostGres&lt;br /&gt;
Created Saturday 18 February 2023&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Launch [PostGres](#PostGres) from Terminal&lt;br /&gt;
------------------------------------------&lt;br /&gt;
sudo -u postgres psql&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Set User Permission&lt;br /&gt;
-------------------&lt;br /&gt;
&amp;lt;https://commandprompt.com/education/how-to-create-a-superuser-in-postgresql/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ALTER USER user_name WITH PASSWORD 'new_password';&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Run Post Gres Commands&lt;br /&gt;
----------------------&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
sudo -i -u postgres&lt;br /&gt;
psql&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Create and Delete Database&lt;br /&gt;
&lt;br /&gt;
CREATE DATABASE name;&lt;br /&gt;
DROP DATABASE name;&lt;br /&gt;
## View user list&lt;br /&gt;
&lt;br /&gt;
\du&lt;br /&gt;
&lt;br /&gt;
 View all databases&lt;br /&gt;
&lt;br /&gt;
postgres=# \l&lt;br /&gt;
&lt;br /&gt;
 Change databases&lt;br /&gt;
&lt;br /&gt;
postgres=# \c    name-of-database&lt;br /&gt;
&lt;br /&gt;
View Tables&lt;br /&gt;
&lt;br /&gt;
After you change databases and are selected on one of them do this:&lt;br /&gt;
&lt;br /&gt;
\dt&lt;br /&gt;
&lt;br /&gt;
SELECT * FROM mytablename;&lt;br /&gt;
&lt;br /&gt;
EMPTY TABLE&lt;br /&gt;
DELETE FROM name-of-table&lt;br /&gt;
&lt;br /&gt;
CREATE TABLE&lt;br /&gt;
&lt;br /&gt;
CREATE TABLE table_name(&lt;br /&gt;
   column1 datatype,&lt;br /&gt;
   column2 datatype,&lt;br /&gt;
   column3 datatype,&lt;br /&gt;
   .....&lt;br /&gt;
   columnN datatype,&lt;br /&gt;
   PRIMARY KEY( one or more columns )&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
INSERT&lt;br /&gt;
&lt;br /&gt;
INSERT INTO ITEMS(id, name) VALUES(1,'htvjbjbgni');     Strings are single quote&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Roadmap==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.ItemsLive do&lt;br /&gt;
    use AppWeb, :live_view  &lt;br /&gt;
    def mount(_params, _session, socket)  do&lt;br /&gt;
      {:ok, assign(socket, switches: [&amp;quot;grindy&amp;quot;,&amp;quot;sonic&amp;quot;,&amp;quot;ogre&amp;quot;])}  &lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    def handle_event(&amp;quot;run&amp;quot;,_params,socket) do  &lt;br /&gt;
        &lt;br /&gt;
        IO.inspect &amp;quot;DOWNLOAD VIA SSH&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        {:noreply, redirect(socket, to: &amp;quot;/download&amp;quot;)}&lt;br /&gt;
&lt;br /&gt;
    end&lt;br /&gt;
   &lt;br /&gt;
&lt;br /&gt;
    def render(assigns) do&lt;br /&gt;
        &lt;br /&gt;
        ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        &amp;lt;ul&amp;gt;&lt;br /&gt;
        &amp;lt;%= for switch &amp;lt;- @switches do %&amp;gt;&lt;br /&gt;
         &amp;lt;a phx-submit=&amp;quot;click&amp;quot; href=&amp;quot;/download&amp;quot;&amp;gt;  &amp;lt;li&amp;gt; &amp;lt;%= switch %&amp;gt;  &amp;lt;/li&amp;gt; &amp;lt;/a&amp;gt;&lt;br /&gt;
&lt;br /&gt;
        &amp;lt;%end%&amp;gt;&lt;br /&gt;
        &amp;lt;/ul&amp;gt;&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot; &lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Notes==&lt;br /&gt;
List of Switches and the option to select the one needed.&lt;br /&gt;
Button to download JSON file.&lt;br /&gt;
Drag and Drop Palette to upload JSON file.&lt;br /&gt;
&lt;br /&gt;
After JSON file is uploaded a button titled &amp;quot;Make Active&amp;quot; is available.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://medium.com/@fraiha26/pushing-events-to-livecomponents-from-js-hooks-w-phoenix-elixir-d5544d4c3dfa&lt;br /&gt;
&lt;br /&gt;
Changeset notes and forms&lt;br /&gt;
&lt;br /&gt;
NOTE: Use case statements for pattern matching&lt;br /&gt;
____________________________________________&lt;br /&gt;
&lt;br /&gt;
Create a basic &amp;lt;.form&amp;gt;&amp;lt;/form&amp;gt; without error handling&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&amp;lt;.form :let={f} for={@changeset}  action={~p&amp;quot;/items&amp;quot;} &amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;.input field={f[:title]} type=&amp;quot;text&amp;quot; label=&amp;quot;Title&amp;quot; /&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
  &amp;lt;.button&amp;gt;Save Item&amp;lt;/.button&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;/.form&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With error handling looks like this:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;.form :let={f} for={@changeset}  action={~p&amp;quot;/items&amp;quot;} &amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;.error :if={@changeset.action}&amp;gt;&lt;br /&gt;
    Oops, something went wrong! Please check the errors below.&lt;br /&gt;
  &amp;lt;/.error&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;.input field={f[:title]} type=&amp;quot;text&amp;quot; label=&amp;quot;Title&amp;quot; /&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
  &amp;lt;.button&amp;gt;Save Item&amp;lt;/.button&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;/.form&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Create the routes for render and post to endpoint.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The controller for the page render needs to pass in the changeset via ```Items.change_item(%Item{})```&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  def new(conn, _params) do&lt;br /&gt;
    changeset = Items.change_item(%Item{})&lt;br /&gt;
    render(conn, :new, changeset: changeset)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Post route without error handling&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  def create(conn, %{&amp;quot;item&amp;quot; =&amp;gt; item_params}) do&lt;br /&gt;
    case Items.create_item(item_params) do&lt;br /&gt;
      {:ok, item} -&amp;gt;&lt;br /&gt;
        conn&lt;br /&gt;
        |&amp;gt; put_flash(:info, &amp;quot;Item created successfully.&amp;quot;)&lt;br /&gt;
        |&amp;gt; redirect(to: ~p&amp;quot;/items/#{item}&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With error handling&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  def create(conn, %{&amp;quot;item&amp;quot; =&amp;gt; item_params}) do&lt;br /&gt;
    case Items.create_item(item_params) do&lt;br /&gt;
      {:ok, item} -&amp;gt;&lt;br /&gt;
        conn&lt;br /&gt;
        |&amp;gt; put_flash(:info, &amp;quot;Item created successfully.&amp;quot;)&lt;br /&gt;
        |&amp;gt; redirect(to: ~p&amp;quot;/items/#{item}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
      {:error, %Ecto.Changeset{} = changeset} -&amp;gt;&lt;br /&gt;
        render(conn, :new, changeset: changeset)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_____________________________________________&lt;br /&gt;
https://medium.com/@vincentlin/phoenix-very-simple-form-c4b121697fcb&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''home.html.heex'''&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&amp;lt;form action=&amp;quot;/submit&amp;quot; method=&amp;quot;post&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;label for=&amp;quot;name&amp;quot;&amp;gt;Name:&amp;lt;/label&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;input type=&amp;quot;text&amp;quot; id=&amp;quot;name&amp;quot; name=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;_csrf_token&amp;quot; value={@csrf_token} /&amp;gt;&lt;br /&gt;
  &amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Submit&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
page_controller.ex&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.PageController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  def home(conn, _params) do&lt;br /&gt;
    # The home page is often custom made,&lt;br /&gt;
&lt;br /&gt;
    csrf_token = Plug.CSRFProtection.get_csrf_token()&lt;br /&gt;
    render(conn, :home, csrf_token: csrf_token)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def submit(conn, _params) do&lt;br /&gt;
    # The home page is often custom made,&lt;br /&gt;
     IO.inspect(_params)&lt;br /&gt;
     IO.inspect &amp;quot;___________________________&amp;quot;&lt;br /&gt;
    csrf_token = Plug.CSRFProtection.get_csrf_token()&lt;br /&gt;
    render(conn, :home, csrf_token: csrf_token)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
router.ex&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  scope &amp;quot;/&amp;quot;, AppWeb do&lt;br /&gt;
    pipe_through :browser&lt;br /&gt;
    post &amp;quot;/submit&amp;quot;, PageController, :submit&lt;br /&gt;
    get &amp;quot;/&amp;quot;, PageController, :home&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ecto.Adapters.SQL.query(Repo, &amp;quot;select * from artists where id=1&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ecto cheatsheet:  https://hexdocs.pm/ecto/crud.html&lt;br /&gt;
__________________________________________________________________&lt;br /&gt;
Most programming languages give you the ability to set global state by creating globally scoped variables. Elixir does not do this. Instead, Elixir provides a tool called a &amp;quot;processes&amp;quot; to persist  state. Elixir applications are composed of these &amp;quot;processes&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
Processes by themselves are complicated to use, thus Elixir provides abstractions to make working with processes easier. One of these abstractions is called a GenServer.&lt;br /&gt;
&lt;br /&gt;
GenServers are not only used to store state, they are also used to invoke work independent of the main application process. &lt;br /&gt;
&lt;br /&gt;
==Creating a GenServer to Store State==&lt;br /&gt;
&lt;br /&gt;
To Create a GenServer, start by creating a basic Module that ''uses'' the GenServer module (image below)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule App do  &lt;br /&gt;
  use GenServer&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We now need to describe the actions we want to perform. Being that this is used to store state, we will use basic CRUD actions: Create, Read, Update, Delete. To begins, empty functions describing each action is created.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule App do&lt;br /&gt;
   def create do &lt;br /&gt;
&lt;br /&gt;
   end&lt;br /&gt;
   def read do &lt;br /&gt;
&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
   def update do  &lt;br /&gt;
&lt;br /&gt;
   end &lt;br /&gt;
&lt;br /&gt;
   def delete do &lt;br /&gt;
&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==What now?==&lt;br /&gt;
&lt;br /&gt;
To fill in the functions with the appropriate code we must first have a basic understanding of how GenServers are structured.&lt;br /&gt;
&lt;br /&gt;
GenServers are composed of the GenServer module invoking callbacks. The callbacks have built in names that you, as a developer have to use.&lt;br /&gt;
&lt;br /&gt;
These callbacks are named:&lt;br /&gt;
&lt;br /&gt;
* init&lt;br /&gt;
* handle_cast&lt;br /&gt;
* handle_call&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To demonstrate, here is an example :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{:ok, pid} = GenServer.start(ModuleNameOfGenServer, %{})&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above function named &amp;quot;start&amp;quot; calls the function named init in the Module below.&lt;br /&gt;
In GenServer syntax the name of the GenServer functions always invoke callbacks that are determined by the language. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule ModuleNameOfGenServer do&lt;br /&gt;
  # 1&lt;br /&gt;
  def init(state \\ %{}) do&lt;br /&gt;
    {:ok, state}&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is a list of the GenServer functions and their corresponding callbacks.&lt;br /&gt;
&lt;br /&gt;
* GenServer.start/1  --&amp;gt;       init/1&lt;br /&gt;
* GenServer.call/3   --&amp;gt;       def handle_call/3&lt;br /&gt;
* GenServer.cast/2   --&amp;gt;       handle_cast/2&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Start and Call ==&lt;br /&gt;
&lt;br /&gt;
Call and Cast can be used to perform the same operations. The &lt;br /&gt;
&lt;br /&gt;
__________________________________________________________&lt;br /&gt;
Genserver timed events&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule Go do&lt;br /&gt;
  use GenServer&lt;br /&gt;
&lt;br /&gt;
  def go() do&lt;br /&gt;
    GenServer.start_link(__MODULE__, [])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def init(list) do&lt;br /&gt;
    :timer.apply_interval(1000, __MODULE__, :add, [self(), &amp;quot;weeeee&amp;quot;])&lt;br /&gt;
    {:ok, list}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def view(pid) do&lt;br /&gt;
    GenServer.call(pid, :view)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_call(:view, _from, list) do&lt;br /&gt;
    {:reply, list, list}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def add(pid, new_item) do&lt;br /&gt;
    GenServer.call(pid, {:item, new_item})&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_call({:item, new_item}, _from, state) do&lt;br /&gt;
    result = [new_item] ++ state&lt;br /&gt;
    {:reply, result, result}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule ShoppingList do&lt;br /&gt;
  use GenServer&lt;br /&gt;
&lt;br /&gt;
  def start_link() do&lt;br /&gt;
    GenServer.start_link(ShoppingList, [])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def init(list) do&lt;br /&gt;
    {:ok, list}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def view(pid) do&lt;br /&gt;
    GenServer.call(pid, :view)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_call(:view, _from, list) do&lt;br /&gt;
    {:reply, list, list}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def add(pid, new_item) do&lt;br /&gt;
    GenServer.call(pid, {:item, new_item})&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_call({:item, new_item}, _from, state) do&lt;br /&gt;
    result = [new_item] ++ state&lt;br /&gt;
    {:reply, result, result}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://blog.appsignal.com/2018/06/12/elixir-alchemy-deconstructing-genservers.html&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule KeyValue do&lt;br /&gt;
  # 1&lt;br /&gt;
  def init(state \\ %{}) do&lt;br /&gt;
    {:ok, state}&lt;br /&gt;
  end&lt;br /&gt;
 &lt;br /&gt;
  # 2&lt;br /&gt;
  def handle_cast({:put, key, value}, state) do&lt;br /&gt;
    {:noreply, Map.put(state, key, value)}&lt;br /&gt;
  end&lt;br /&gt;
 &lt;br /&gt;
  # 3&lt;br /&gt;
  def handle_call({:get, key}, _from, state) do&lt;br /&gt;
    {:reply, Map.fetch!(state, key), state}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
# {:ok, pid} = GenServer.start(KeyValue, %{})&lt;br /&gt;
# GenServer.cast(pid, {:put, :foo, &amp;quot;bar&amp;quot;})&lt;br /&gt;
# GenServer.call(pid, {:get, :foo})&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Send messages via these functions wrapped in module functions .You can look at these are functions used to fire &amp;quot;GenServer Events&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
* start_link&lt;br /&gt;
* GenServer.call&lt;br /&gt;
* GenServer.cast&lt;br /&gt;
&lt;br /&gt;
The corresponding server functions that reply are:&lt;br /&gt;
&lt;br /&gt;
* init&lt;br /&gt;
* handle__call&lt;br /&gt;
* handle_cast&lt;br /&gt;
* &lt;br /&gt;
&lt;br /&gt;
These can be looked at as &amp;quot;listeners&amp;quot; - in JavaScript parlance. &lt;br /&gt;
__________________________________________&lt;br /&gt;
&lt;br /&gt;
If you have experience with programming languages other than Elixir the idea of GenServers may be very foreign and require a strong context shift to learn. This document is intended to simplify the concept.&lt;br /&gt;
&lt;br /&gt;
* What: GenServers are simply a way to hold state and/or invoke actions based on incoming events. &lt;br /&gt;
* when &lt;br /&gt;
* where&lt;br /&gt;
* why&lt;br /&gt;
* how&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
___________________________________________&lt;br /&gt;
GenServer timer example&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule Timer do&lt;br /&gt;
  use GenServer&lt;br /&gt;
&lt;br /&gt;
  def init(_) do&lt;br /&gt;
    :timer.send_interval(1000, :xyz)&lt;br /&gt;
    {:ok, 0}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_info(:xyz, state) do&lt;br /&gt;
    IO.inspect(state)&lt;br /&gt;
    {:noreply, state + 1}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
[&lt;br /&gt;
   {&lt;br /&gt;
     data:{&lt;br /&gt;
        creationTime,&lt;br /&gt;
        publishDate,&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
     featured:{&lt;br /&gt;
        setAmount,&lt;br /&gt;
        items:[]&lt;br /&gt;
     },&lt;br /&gt;
&lt;br /&gt;
     children:{&lt;br /&gt;
        setAmount,&lt;br /&gt;
        items:[]&lt;br /&gt;
     },&lt;br /&gt;
     links:{&lt;br /&gt;
        setAmount,&lt;br /&gt;
        items:[]&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
jason.encode / jason.decode&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  def run(num) do&lt;br /&gt;
&lt;br /&gt;
    Enum.each(0..99999, fn(_x) -&amp;gt;&lt;br /&gt;
      task = Task.async(fn -&amp;gt; num + _x end)&lt;br /&gt;
    IO.inspect Task.await(task)&lt;br /&gt;
  end)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enum.map(feed.entries, fn x -&amp;gt; %{url: x.url, title: x.title} end)&lt;br /&gt;
&lt;br /&gt;
App is split:&lt;br /&gt;
&lt;br /&gt;
App that captures RSS in UI and lets admin select stories. THere are settings to determine the number of FEATURED,CHILD and LINK stories.&lt;br /&gt;
News categories are horizontal and scrollable.&lt;br /&gt;
This exports a json doc with all RSS data for each story.&lt;br /&gt;
The &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
App that reads the json data. This app creates tables and is the front end.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://stephenbussey.com/tags/elixir.html&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule AppWeb.GroupLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  alias App.TestBeds&lt;br /&gt;
  alias App.Groups&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    {:ok, assign(socket, testbeds: TestBeds.list_testbeds(), groups: Groups.list_groups())}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;select-group&amp;quot;, params, socket)  do  &lt;br /&gt;
     group = App.Groups.get_group!(params[&amp;quot;group-id&amp;quot;])&lt;br /&gt;
     testbed = App.TestBeds.get_test_bed!(params[&amp;quot;testbed_id&amp;quot;])&lt;br /&gt;
     App.TestBeds.update_test_bed(testbed, %{group_id: group.id})&lt;br /&gt;
     {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def updated_groups(testbed_id)  do  &lt;br /&gt;
     testbed = App.TestBeds.get_test_bed!(testbed_id)&lt;br /&gt;
     groups = App.Groups.list_groups&lt;br /&gt;
     tail = Enum.filter(groups, fn(item)-&amp;gt; item.id !== testbed.group_id end)&lt;br /&gt;
     head = Enum.filter(groups, fn(item)-&amp;gt; item.id == testbed.group_id end)&lt;br /&gt;
            |&amp;gt;Enum.at(0)&lt;br /&gt;
    [head | tail]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        &amp;lt;%= for testbed &amp;lt;- Enum.sort_by(@testbeds , &amp;amp;(&amp;quot;#{&amp;amp;1.name}&amp;quot;), :asc)do %&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;grid grid-cols-4 gap-4 p-8 rounded shadow bg-white&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;h2&amp;gt; Name&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;%= testbed.name %&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;h2&amp;gt; Group&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div&amp;gt;&lt;br /&gt;
            &amp;lt;form phx-change=&amp;quot;select-group&amp;quot; name=&amp;quot;testbed_id&amp;quot;  &amp;gt;&lt;br /&gt;
               &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;testbed_id&amp;quot; value={testbed.id}/&amp;gt;&lt;br /&gt;
               &amp;lt;select id=&amp;quot;group-selection&amp;quot;  name=&amp;quot;group-id&amp;quot; class=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;%= for group &amp;lt;- updated_groups(testbed.id) do %&amp;gt;&lt;br /&gt;
                  &amp;lt;%= if group !== nil do %&amp;gt;&lt;br /&gt;
                      &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}&amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
                      &amp;lt;%else%&amp;gt;&lt;br /&gt;
                      &amp;lt;option value= {&amp;quot;Unassigned&amp;quot;}&amp;gt;NONE&amp;lt;/option&amp;gt;&lt;br /&gt;
                  &amp;lt;% end %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
               &amp;lt;/select&amp;gt;&lt;br /&gt;
            &amp;lt;/form&amp;gt;&lt;br /&gt;
          &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
       &amp;lt;% end %&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Developer Notes ==&lt;br /&gt;
===Groups Feature ===&lt;br /&gt;
To complete this feature do these things.&lt;br /&gt;
* Run through the steps in [http://elixirblocks.com/index.php?title=Create_Foreign_Key_Relationship_Between_Ecto_Tables  | this document] to create Group table.&lt;br /&gt;
* Groups have these fields  '''name: string''', '''description: string''' and '''color: string'''  &lt;br /&gt;
* Add unique constraint in migration file: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def change do&lt;br /&gt;
     create unique_index(:groups, [:name])&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Port over Group LiveView code (temporarily placed at discussion page).&lt;br /&gt;
* On completion '''possibly''', create a Group named '''No Group''' and set all Testbeds to it.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
________&lt;br /&gt;
https://blog.appsignal.com/2022/10/11/phoenix-liveview-018-new-special-html-attributes.html&lt;br /&gt;
https://blixtdev.com/whats-new-phoenix-1-7/&lt;br /&gt;
https://github.com/devato/inertia_phoenix&lt;br /&gt;
https://phoenixonrails.com/blog/you-can-stop-using-form-for-in-phoenix&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://samuelmullen.com/articles/phoenix_templates_rendering_and_layouts&lt;br /&gt;
&lt;br /&gt;
WorkFlow of Todo App in Both LiveView and DeadView.&lt;br /&gt;
&lt;br /&gt;
Note:&lt;br /&gt;
&lt;br /&gt;
Create foreign key data.&lt;br /&gt;
Create live view. List all testbeds and form to assign each a group by group-name.&lt;br /&gt;
&lt;br /&gt;
Repeat in dead view&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Mental model and data flows&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
home.html.heex&lt;br /&gt;
&amp;lt;a href=&amp;quot;/data&amp;quot; name=&amp;quot;we are the world&amp;quot; &amp;gt;  click me&amp;lt;/a&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;%= @message %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
page controller&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  def home(conn, _params) do&lt;br /&gt;
    IO.inspect _params&lt;br /&gt;
    render(conn, :home, message: &amp;quot;Hello&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
get &amp;quot;/:yay&amp;quot;, PageController, :index&lt;br /&gt;
&lt;br /&gt;
get &amp;quot;/&amp;quot;, PageController, :index&lt;br /&gt;
&lt;br /&gt;
* Explain control flow of &amp;quot;Dead Views&amp;quot; and the Generator HTML Control flow.&lt;br /&gt;
* Proper Way to use Modal&lt;br /&gt;
* How to give Focus to Fields in Modal (or other forms fields)&lt;br /&gt;
* &lt;br /&gt;
* &lt;br /&gt;
* How to Create Database Seed Data.&lt;br /&gt;
* How to structure code so controller code is in one file and HTML Heex is in another&lt;br /&gt;
* How to Use Generators in a Real World Project&lt;br /&gt;
* How to Work with Database Data via Basic Commands and Custom Change sets.&lt;br /&gt;
* How to Render Database Data to LiveView (via Context Commands).&lt;br /&gt;
* How to Create a Chat using PubSub.&lt;br /&gt;
* How to Create Event Handlers in LiveView&lt;br /&gt;
* How to Create a Dynamic Route from Scratch.&lt;br /&gt;
* How to Use Elixirs Template language&lt;br /&gt;
* How to Work with Modal&lt;br /&gt;
* How to Use CSS From Scratch (Without bundler)&lt;br /&gt;
* How to use JS hooks&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
______________________&lt;br /&gt;
https://studioindie.co/blog/heex-guide/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
get &amp;quot;/&amp;quot;, PageController, :some-atom    #This is the route. some-atom is the controller name&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  def some-atom(conn, _params) do                 # controller name&lt;br /&gt;
    # The home page is often custom made,&lt;br /&gt;
    # so skip the default app layout.&lt;br /&gt;
    render(conn, :some-atom, layout: false)      # :some-atom is template name&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Controllers page_html.ex contains &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageHTML do&lt;br /&gt;
  use AppWeb, :html&lt;br /&gt;
&lt;br /&gt;
  embed_templates &amp;quot;page_html/*&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''page_html''' is the name of the folder in '''Controllers/page_html'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Controllers/page_html/some-atom.html.heex  (this is the template) &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__________________________________________&lt;br /&gt;
Set all association with preload:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  def list_groups do&lt;br /&gt;
    Repo.all(Group)&lt;br /&gt;
     |&amp;gt; Repo.preload([:testbeds])&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Insert Child into Parent ===&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
App.get_group!(2) # arg is id&lt;br /&gt;
|&amp;gt; Ecto.build_assoc(:testbeds)&lt;br /&gt;
|&amp;gt; Repo.insert()&lt;br /&gt;
&lt;br /&gt;
Or&lt;br /&gt;
&lt;br /&gt;
group = App.get_group!(2) # arg is id&lt;br /&gt;
&lt;br /&gt;
testbeds = Ecto.build_assoc(group, :testbeds)&lt;br /&gt;
&lt;br /&gt;
App.Group.create_group(testbeds)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
group = App.Groups.get_group!(1)&lt;br /&gt;
thing = Ecto.build_assoc(group, :testbeds, name: &amp;quot;DUMB&amp;quot;)&lt;br /&gt;
alias App.{Repo}&lt;br /&gt;
Repo.insert(thing)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
avatar = %Avatar{nick_name: &amp;quot;Elixir&amp;quot;, pic_url: &amp;quot;http://elixir-lang.org/images/logo.png&amp;quot;}&lt;br /&gt;
user = %User{name: &amp;quot;John Doe&amp;quot;, email: &amp;quot;john.doe@example.com&amp;quot;, avatar: avatar}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://www.reddit.com/r/elixir/comments/oh318k/is_there_a_way_to_avoid_ectoassociationnotloaded/h4mmcfi/?utm_source=share&amp;amp;utm_medium=web3x&amp;amp;utm_name=web3xcss&amp;amp;utm_term=1&amp;amp;utm_content=share_button&lt;br /&gt;
&lt;br /&gt;
# Create Group Table&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
mix phx.gen.html Groups Group groups name:string  &lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Set the resources / &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
mix ecto.migrate&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For testbeds create a migration file and add this field:   group_id:references:groups&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
def change do&lt;br /&gt;
    alter table(:testbeds) do    # customize to your code&lt;br /&gt;
      add :group_id, references(:groups)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Update Groups Schema (Don't forget alias / has_many)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule App.Groups.Group do&lt;br /&gt;
	use Ecto.Schema&lt;br /&gt;
	import Ecto.Changeset&lt;br /&gt;
	alias App.Testbeds.Testbed   # Alias!&lt;br /&gt;
&lt;br /&gt;
	schema &amp;quot;posts&amp;quot; do&lt;br /&gt;
		field :body, :string&lt;br /&gt;
		field :title, :string&lt;br /&gt;
		has_many :testbeds, Testbed    # Has many&lt;br /&gt;
&lt;br /&gt;
		timestamps()&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	@doc false&lt;br /&gt;
	def changeset(post, attrs) do&lt;br /&gt;
		post&lt;br /&gt;
		|&amp;gt; cast(attrs, [:title, :body])&lt;br /&gt;
		|&amp;gt; validate_required([:title, :body])&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
TESTBEDS Schema&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule App.Testbeds.Testbed do&lt;br /&gt;
  use Ecto.Schema&lt;br /&gt;
  import Ecto.Changeset&lt;br /&gt;
  alias App.Groups.Group      # Alias&lt;br /&gt;
  schema &amp;quot;testbeds&amp;quot; do&lt;br /&gt;
    field :name, :string&lt;br /&gt;
    belongs_to :group, Group    # Belongs to&lt;br /&gt;
    timestamps()&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  @doc false&lt;br /&gt;
  def changeset(testbed, attrs) do&lt;br /&gt;
    testbed&lt;br /&gt;
    |&amp;gt; cast(attrs, [:name])&lt;br /&gt;
    |&amp;gt; validate_required([:name])&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
_____________________________________&lt;br /&gt;
Side notes.&lt;br /&gt;
&lt;br /&gt;
defmodule App.Repo.Migrations.CreateTestbeds do&lt;br /&gt;
  use Ecto.Migration&lt;br /&gt;
&lt;br /&gt;
  def change do&lt;br /&gt;
    create table(:testbeds) do&lt;br /&gt;
      add :name, :string&lt;br /&gt;
      add :group_id, references(:groups, on_delete: :nothing)&lt;br /&gt;
&lt;br /&gt;
      timestamps()&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    create index(:testbeds, [:group_id])&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
________________________________&lt;br /&gt;
&lt;br /&gt;
mix phx.gen.context Comments Comment comments name:string content:text post_id:references:posts&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
mix phx.gen.html Testbeds Testbed testbeds name:string  group_id:references:groups&lt;br /&gt;
&lt;br /&gt;
https://graffino.com/web-development/first-steps-in-elixir-and-phoenix-create-a-blog-prototype&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://blog.logrocket.com/getting-started-ecto-phoenix/&lt;br /&gt;
&lt;br /&gt;
https://serokell.io/blog/ecto-guide-for-beginners&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
mix phx.gen.html Testbeds Testbed testbeds name:string&lt;br /&gt;
&lt;br /&gt;
mix phx.gen.html Groups Group groups name:string&lt;br /&gt;
&lt;br /&gt;
Create migration for &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
mix ecto.gen.migration add_testbed_group_reference&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Migration:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  def change do&lt;br /&gt;
    alter table(:testbeds) do    # customize to your code&lt;br /&gt;
      add :group_id, references(:groups)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Manually Change:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule App.Group do&lt;br /&gt;
  use Ecto.Schema&lt;br /&gt;
&lt;br /&gt;
  schema &amp;quot;groups&amp;quot; do&lt;br /&gt;
    field :title, :string&lt;br /&gt;
    field :tagline, :string&lt;br /&gt;
    has_many :testbeds, App.Testbed&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
testbeds&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule App.Repo.Migrations.AddTextbedGroups do&lt;br /&gt;
  use Ecto.Migration&lt;br /&gt;
&lt;br /&gt;
  def change do&lt;br /&gt;
    create table(:testbeds) do&lt;br /&gt;
      add :name, :string&lt;br /&gt;
      add :group_id, references(:groups)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
# lib/app/testbeds.ex&lt;br /&gt;
&lt;br /&gt;
defmodule App.Testbed do&lt;br /&gt;
  use Ecto.Schema&lt;br /&gt;
&lt;br /&gt;
  schema &amp;quot;testbedss&amp;quot; do&lt;br /&gt;
    field :name, :string&lt;br /&gt;
    belongs_to :group, App.Group&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_____________________&lt;br /&gt;
&lt;br /&gt;
%App.TestBeds.TestBed{&lt;br /&gt;
  __meta__: #Ecto.Schema.Metadata&amp;lt;:loaded, &amp;quot;testbeds&amp;quot;&amp;gt;,&lt;br /&gt;
  id: 1,&lt;br /&gt;
  developer: &amp;quot;None&amp;quot;,&lt;br /&gt;
  name: &amp;quot;sdfsd&amp;quot;,&lt;br /&gt;
  owner: &amp;quot;sdfsddf&amp;quot;,&lt;br /&gt;
  note: &amp;quot;sdsfsddf&amp;quot;,&lt;br /&gt;
  status: &amp;quot;Available&amp;quot;,&lt;br /&gt;
  url: &amp;quot;sdf&amp;quot;,&lt;br /&gt;
  version: &amp;quot;ddf&amp;quot;,&lt;br /&gt;
  manager: &amp;quot;sf&amp;quot;,&lt;br /&gt;
  inserted_at: ~N[2023-08-21 13:45:39],&lt;br /&gt;
  updated_at: ~N[2023-08-21 13:45:44]&lt;br /&gt;
}&lt;br /&gt;
________________________________________________________________---&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.SendLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  &lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    {:ok, socket}&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  def handle_event(&amp;quot;send&amp;quot;, %{&amp;quot;text&amp;quot; =&amp;gt; text}, socket) do&lt;br /&gt;
&lt;br /&gt;
    AppWeb.Endpoint.broadcast(topic, &amp;quot;message&amp;quot;, text)&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  defp topic do&lt;br /&gt;
    &amp;quot;chat&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def render(assigns)do   &lt;br /&gt;
   ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
  &amp;lt;h1&amp;gt;Send Message&amp;lt;/h1&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;form phx-submit=&amp;quot;send&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;text&amp;quot; /&amp;gt;&lt;br /&gt;
    &amp;lt;button type=&amp;quot;submit&amp;quot;&amp;gt;Send&amp;lt;/button&amp;gt;&lt;br /&gt;
  &amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
______________________________________________________________&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.ReceiveLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  &lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    if connected?(socket) do&lt;br /&gt;
      AppWeb.Endpoint.subscribe(topic)&lt;br /&gt;
    end&lt;br /&gt;
    {:ok, assign(socket, messages: &amp;quot;&amp;quot;)}&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def handle_info(%{event: &amp;quot;message&amp;quot;, payload: message}, socket) do&lt;br /&gt;
    IO.inspect message&lt;br /&gt;
    {:noreply, assign(socket, messages: message)}&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  defp topic do&lt;br /&gt;
    &amp;quot;chat&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns)do   &lt;br /&gt;
   ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
  &amp;lt;h1&amp;gt;ChatLive&amp;lt;/h1&amp;gt;&lt;br /&gt;
  &amp;lt;%= @messages %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
______________________________________________________________&lt;br /&gt;
When you hover over a list of items this hook finds items with the same name and sets the opacity of all others to 0. You see all the items similar to the one you are hovering over.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
TestbedVersionHover: {&lt;br /&gt;
			// https://jsfiddle.net/IrvinDominin/7K2Z3/&lt;br /&gt;
            mounted() {&lt;br /&gt;
&lt;br /&gt;
                let rows = document.getElementsByClassName(&amp;quot;testbed-version&amp;quot;)&lt;br /&gt;
                // this.ele = element&lt;br /&gt;
				// rows = this.ele;&lt;br /&gt;
                &lt;br /&gt;
				for (var i = 0; i &amp;lt; rows.length; i++) {&lt;br /&gt;
					rows[i].onmouseenter = function (event) {&lt;br /&gt;
						for (var j = 0; j &amp;lt; rows.length; j++) {&lt;br /&gt;
							let preversion = this.textContent;&lt;br /&gt;
							let version = preversion.slice(0,5)&lt;br /&gt;
							let compareVersion = rows[j].textContent.slice(0,5)&lt;br /&gt;
							if (compareVersion === version) continue&lt;br /&gt;
							rows[j].className += &amp;quot; other&amp;quot;;&lt;br /&gt;
						}&lt;br /&gt;
					};&lt;br /&gt;
				&lt;br /&gt;
					rows[i].onmouseleave = function (event) {&lt;br /&gt;
						var hovers = document.getElementsByClassName('other');&lt;br /&gt;
						var len = hovers.length;&lt;br /&gt;
						for (var j = 0; j &amp;lt; len; j++) {&lt;br /&gt;
							hovers[0].className = hovers[0].className.replace(/\sother(\s|$)/, '');&lt;br /&gt;
						}&lt;br /&gt;
					};&lt;br /&gt;
				}&lt;br /&gt;
&lt;br /&gt;
                // this.ele.addEventListener(&amp;quot;click&amp;quot;, (e) =&amp;gt; {&lt;br /&gt;
                //     console.log(e.target)&lt;br /&gt;
                    &lt;br /&gt;
                // });&lt;br /&gt;
&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* How to Create Database Seed Data.&lt;br /&gt;
* How to structure code so controller code is in one file and HTML Heex is in another&lt;br /&gt;
* How to Use Generators in a Real World Project&lt;br /&gt;
* How to Work with Database Data via Basic Commands and Custom Change sets.&lt;br /&gt;
* How to Render Database Data to LiveView (via Context Commands).&lt;br /&gt;
* How to Create a Chat using PubSub.&lt;br /&gt;
* How to Create Event Handlers in LiveView&lt;br /&gt;
* How to Create a Dynamic Route from Scratch.&lt;br /&gt;
* How to Use Elixirs Template language&lt;br /&gt;
* How to Work with Modal&lt;br /&gt;
* How to Use CSS From Scratch (Without bundler)&lt;br /&gt;
* How to use JS hooks&lt;br /&gt;
* Dissect Table Component and Update it to Order List in Reverse.&lt;br /&gt;
&lt;br /&gt;
Selenium&lt;br /&gt;
https://www.builder.io/blog/debug-nodejs&lt;br /&gt;
&lt;br /&gt;
https://marketplace.visualstudio.com/items?itemName=ms-vscode.live-server#running-the-extension&lt;br /&gt;
&lt;br /&gt;
This was added recently (see microsoft/vscode#109276).&lt;br /&gt;
    1. Open the palette (Ctrl + Shift + P)&lt;br /&gt;
    2. Select &amp;quot;Simple Browser: Preview&amp;quot;&lt;br /&gt;
    3. Enter web address&lt;br /&gt;
&lt;br /&gt;
_______________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
const {By, Key, Builder} = require(&amp;quot;selenium-webdriver&amp;quot;);&lt;br /&gt;
const assert = require(&amp;quot;assert&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
require(&amp;quot;chromedriver&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
async function test_case(){&lt;br /&gt;
  let driver = await new Builder().forBrowser(&amp;quot;chrome&amp;quot;).build();&lt;br /&gt;
  await driver.get(&amp;quot;sie&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  await driver.findElement(By.name('password')).clear();&lt;br /&gt;
  await driver.findElement(By.name('identification')).clear();&lt;br /&gt;
  await driver.findElement(By.name('identification')).sendKeys(&amp;quot;bill&amp;quot;);&lt;br /&gt;
  await driver.findElement(By.name('password')).sendKeys(&amp;quot;password&amp;quot;, Key.RETURN);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 setTimeout(()=&amp;gt;{&lt;br /&gt;
   driver.findElement(By.className(&amp;quot;req_lan_license&amp;quot;)).click();&lt;br /&gt;
 },5000)&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageLive do &lt;br /&gt;
&lt;br /&gt;
  use AppWeb, :live_view  &lt;br /&gt;
  alias App.Testbeds &lt;br /&gt;
  def mount(_params, _session, socket)do   &lt;br /&gt;
     {:ok, assign(socket, testbeds: Testbeds.list_testbeds())}   &lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
    def button_event(&amp;quot;invoke_editing&amp;quot;) do&lt;br /&gt;
    %JS{}&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;active&amp;quot;, to: &amp;quot;#editing_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#editing_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#preview_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;active&amp;quot;, to: &amp;quot;#preview_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;active&amp;quot;, to: &amp;quot;#preview&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#preview&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#editing&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;active&amp;quot;, to: &amp;quot;#editing&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def button_event(&amp;quot;invoke_preview&amp;quot;) do&lt;br /&gt;
    %JS{}&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;active&amp;quot;, to: &amp;quot;#preview_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#preview_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#editing_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;active&amp;quot;, to: &amp;quot;#editing_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;active&amp;quot;, to: &amp;quot;#editing&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#editing&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#preview&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;active&amp;quot;, to: &amp;quot;#preview&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;send&amp;quot;, params, socket) do&lt;br /&gt;
    hide_modal(&amp;quot;notes-modal-0&amp;quot;)&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do  &lt;br /&gt;
     ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
		&amp;lt;.modal id={&amp;quot;notes-modal-#{testbed.id}&amp;quot;}&amp;gt;&lt;br /&gt;
		    &amp;lt;.button phx-click={button_event(&amp;quot;invoke_editing&amp;quot;)} id=&amp;quot;editing_button&amp;quot; class=&amp;quot;hidden&amp;quot;&amp;gt;&lt;br /&gt;
		      Preview&lt;br /&gt;
		    &amp;lt;/.button&amp;gt;&lt;br /&gt;
		    &amp;lt;.button phx-click={button_event(&amp;quot;invoke_preview&amp;quot;)} id=&amp;quot;preview_button&amp;quot;&amp;gt;&lt;br /&gt;
		      Edit Me&lt;br /&gt;
		    &amp;lt;/.button&amp;gt;&lt;br /&gt;
		    &amp;lt;div id=&amp;quot;editing&amp;quot;&amp;gt; PREVIEWING THE WORK&amp;lt;/div&amp;gt;&lt;br /&gt;
		    &amp;lt;form phx-submit = &amp;quot;send&amp;quot;   id=&amp;quot;preview&amp;quot; class=&amp;quot;hidden&amp;quot;&amp;gt;&lt;br /&gt;
		      &amp;lt;textarea value = {testbed.note}&amp;gt;&amp;lt;/textarea&amp;gt;&lt;br /&gt;
		      &amp;lt;.button type=&amp;quot;submit&amp;quot; phx-click={hide_modal(&amp;quot;notes-modal-#{testbed.id}&amp;quot;)}&amp;gt;SAVE WORK&amp;lt;/.button&amp;gt;&lt;br /&gt;
		    &amp;lt;/form&amp;gt;&lt;br /&gt;
		&amp;lt;/.modal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;%= if testbed.note do %&amp;gt;&lt;br /&gt;
      &amp;lt;div phx-click={show_modal(&amp;quot;notes-modal-#{testbed.id}&amp;quot;)}&amp;gt;READ ME  ...&amp;lt;%= testbed.note %&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
	   &lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
       &lt;br /&gt;
      &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
import {HfInference} from &amp;quot;@huggingface/inference&amp;quot;;&lt;br /&gt;
import dotenv from &amp;quot;dotenv&amp;quot;;&lt;br /&gt;
dotenv.config()&lt;br /&gt;
&lt;br /&gt;
const HF_ACCESS_TOKEN = process.env.HF_ACCESS_TOKEN&lt;br /&gt;
&lt;br /&gt;
const hf = new HfInference(HF_ACCESS_TOKEN);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*______Uncomment for this example______________________&lt;br /&gt;
&lt;br /&gt;
const model = &amp;quot;nlpconnect/vit-gpt2-image-captioning&amp;quot;;&lt;br /&gt;
const imageURL = &amp;quot;https://i.imgur.com/lTvb7Et.png&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
const response = await fetch(imageURL);&lt;br /&gt;
const imageBlob = await response.blob();&lt;br /&gt;
&lt;br /&gt;
const result  = await hf.imageToText({&lt;br /&gt;
	data: imageBlob,&lt;br /&gt;
	model: model,&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
_______________________________________________________*/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*________Another example ___________________*/&lt;br /&gt;
&lt;br /&gt;
const result = await hf.summarization({&lt;br /&gt;
	model: 'facebook/bart-large-cnn',&lt;br /&gt;
	inputs: &amp;quot;The role of a dumb man is to get smarter oogy bookie boo&amp;quot;,&lt;br /&gt;
	parameters:{&lt;br /&gt;
		max_length: 100&lt;br /&gt;
	}&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
console.log(result);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
________________________________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://fly.io/phoenix-files/sdeb-toggling-element/&lt;br /&gt;
https://www.youtube.com/watch?v=vBgZvQapqhs&lt;br /&gt;
&lt;br /&gt;
https://blog.testdouble.com/posts/2022-11-28-how-to-use-javascript-with-phoenix-liveview/&lt;br /&gt;
&lt;br /&gt;
https://hexdocs.pm/phoenix_live_view/0.19.3/Phoenix.Component.html&lt;br /&gt;
_______________________________________&lt;br /&gt;
https://www.smashingmagazine.com/2011/10/quick-look-math-animations-javascript/&lt;br /&gt;
* Depth first traversal&lt;br /&gt;
* Breadth first traversal&lt;br /&gt;
&lt;br /&gt;
https://dev.to/codesphere/10-algorithms-every-developer-should-learn-3lnm&lt;br /&gt;
&lt;br /&gt;
https://www.youtube.com/watch?v=fPz40W9mfCg&lt;br /&gt;
&lt;br /&gt;
__________________________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.GroupLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  alias App.TestBeds&lt;br /&gt;
  alias App.Groups&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    {:ok, assign(socket, testbeds: TestBeds.list_testbeds(), groups: Groups.list_groups())}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;select-group&amp;quot;, params, socket)  do  &lt;br /&gt;
         &lt;br /&gt;
       IO.inspect params&lt;br /&gt;
       {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div class=&amp;quot;grid grid-columns-2 grid-flow-col gap-4&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;column-1&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;%= testbed.name %&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;column-2&amp;quot;&amp;gt;    &lt;br /&gt;
            &amp;lt;form phx-change=&amp;quot;select-group&amp;quot;  &amp;gt;&lt;br /&gt;
               &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;testbed_id&amp;quot; value={testbed.id}/&amp;gt;&lt;br /&gt;
               &amp;lt;select id=&amp;quot;group-selection&amp;quot;  name=&amp;quot;group-id&amp;quot; &amp;gt;&lt;br /&gt;
                &amp;lt;%= for group &amp;lt;- @groups do %&amp;gt;&lt;br /&gt;
                  &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}  &amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
               &amp;lt;/select&amp;gt;&lt;br /&gt;
            &amp;lt;/form&amp;gt;&lt;br /&gt;
         &amp;lt;/div&amp;gt;&lt;br /&gt;
       &amp;lt;% end %&amp;gt;&lt;br /&gt;
   &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
____________________________&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.GroupLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  alias App.TestBeds&lt;br /&gt;
  alias App.Groups&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
&lt;br /&gt;
    {:ok, assign(socket, testbeds: TestBeds.list_testbeds(), groups: Groups.list_groups(), messages: [])}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;select-group&amp;quot;, params, socket)  do  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
      group = App.Groups.get_group!(params[&amp;quot;group-id&amp;quot;])&lt;br /&gt;
       # IO.inspect group&lt;br /&gt;
       testbed = App.TestBeds.get_test_bed!(params[&amp;quot;testbed_id&amp;quot;])&lt;br /&gt;
     &lt;br /&gt;
       App.TestBeds.update_test_bed(testbed, %{group_id: group.id})&lt;br /&gt;
         &lt;br /&gt;
    &lt;br /&gt;
       {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def updated_groups(testbed_id)  do  &lt;br /&gt;
       groups = App.Groups.list_groups&lt;br /&gt;
       tail = Enum.filter(groups, fn(item)-&amp;gt; item.id !== testbed_id end)&lt;br /&gt;
       head = Enum.filter(groups, fn(item)-&amp;gt; item.id == testbed_id end)&lt;br /&gt;
              |&amp;gt;Enum.at(0)&lt;br /&gt;
     [head | tail]&lt;br /&gt;
         &lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
 # def handle_event(&amp;quot;groups&amp;quot;, params, socket)do  &lt;br /&gt;
 #       selected_testbed = %{name: &amp;quot;my testbed name&amp;quot;, id: 3}&lt;br /&gt;
 #       groups = App.Groups.list_groups&lt;br /&gt;
 #       tail = Enum.filter(groups, fn(item)-&amp;gt; item.id !== selected_testbed.id end)&lt;br /&gt;
 #       head = Enum.filter(groups, fn(item)-&amp;gt; item.id == selected_testbed.id end)&lt;br /&gt;
 #              |&amp;gt;Enum.at(0)&lt;br /&gt;
         &lt;br /&gt;
 &lt;br /&gt;
 #       # result = Enum.filter([1, 2, 3], fn x -&amp;gt; x.id !== 1 end)&lt;br /&gt;
 #      IO.inspect [head | tail]&lt;br /&gt;
         &lt;br /&gt;
 #      #&lt;br /&gt;
 #      {:noreply, socket, assigns.message:}&lt;br /&gt;
 #  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    &lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
       &amp;lt;%!-- &amp;lt;div phx-click = &amp;quot;groups&amp;quot;&amp;gt;CLICK ME&amp;lt;/div&amp;gt; --%&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;grid grid-cols-4 gap-4 p-8 rounded shadow bg-white&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;h2&amp;gt; Name&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;%= testbed.name %&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;h2&amp;gt; Group&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;form phx-change=&amp;quot;select-group&amp;quot; name=&amp;quot;testbed_id&amp;quot;  &amp;gt;&lt;br /&gt;
               &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;testbed_id&amp;quot; value={testbed.id}/&amp;gt;&lt;br /&gt;
               &amp;lt;select id=&amp;quot;group-selection&amp;quot;  name=&amp;quot;group-id&amp;quot; class=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
                &amp;lt;%= for group &amp;lt;- updated_groups(testbed.id) do %&amp;gt;&lt;br /&gt;
                  &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}  &amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
                  &amp;lt;!-- Write code to reorder with testbed.group_id matching group_id --&amp;gt;&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
               &amp;lt;/select&amp;gt;&lt;br /&gt;
            &amp;lt;/form&amp;gt;&lt;br /&gt;
          &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
       &amp;lt;% end %&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_____________________________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
   use AppWeb, :live_view  &lt;br /&gt;
     alias App.Testbeds&lt;br /&gt;
  alias App.Groups&lt;br /&gt;
   def mount(_params, _session, socket)  do&lt;br /&gt;
	     {:ok, assign(socket, testbeds: Testbeds.list_testbeds(), groups: Groups.list_groups())}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
   def handle_event(&amp;quot;select-group&amp;quot;, params, socket)  do  &lt;br /&gt;
       group = App.Groups.get_group!(params[&amp;quot;group-id&amp;quot;])&lt;br /&gt;
       testbed = App.Testbeds.get_testbed!(params[&amp;quot;testbed_id&amp;quot;])&lt;br /&gt;
       result = App.Testbeds.update_testbed(testbed, %{group_id: group.id})&lt;br /&gt;
       IO.inspect result&lt;br /&gt;
      &lt;br /&gt;
       {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
    def updated_groups(testbed_id)  do  &lt;br /&gt;
       testbed = App.Testbeds.get_testbed!(testbed_id)&lt;br /&gt;
       groups = App.Groups.list_groups&lt;br /&gt;
       tail = Enum.filter(groups, fn(item)-&amp;gt; item.id !== testbed.group_id end)&lt;br /&gt;
       head = Enum.filter(groups, fn(item)-&amp;gt; item.id == testbed.group_id end)&lt;br /&gt;
              |&amp;gt;Enum.at(0)&lt;br /&gt;
 &lt;br /&gt;
       [head | tail]&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    &lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;grid grid-cols-4 gap-4 p-8 rounded shadow bg-white&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;h2&amp;gt; Name&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;%= testbed.name %&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;h2&amp;gt; Group&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;form phx-change=&amp;quot;select-group&amp;quot; name=&amp;quot;testbed_id&amp;quot;  &amp;gt;&lt;br /&gt;
               &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;testbed_id&amp;quot; value={testbed.id}/&amp;gt;&lt;br /&gt;
               &amp;lt;select id=&amp;quot;group-selection&amp;quot;  name=&amp;quot;group-id&amp;quot; class=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
                &amp;lt;%= for group &amp;lt;- updated_groups(testbed.id) do %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
                  &amp;lt;%!-- &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}&amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt; --%&amp;gt;&lt;br /&gt;
                  &amp;lt;!-- Write code to reorder with testbed.group_id matching group_id --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
                  &amp;lt;%= if group !== nil do %&amp;gt;&lt;br /&gt;
                      &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}&amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
       &lt;br /&gt;
                  &amp;lt;% end %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
               &amp;lt;/select&amp;gt;&lt;br /&gt;
            &amp;lt;/form&amp;gt;&lt;br /&gt;
          &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
       &amp;lt;% end %&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  has_many :testbeds, TestBed, on_delete: :restrict   # Has many&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://elixirforum.com/t/ecto-has-many-on-delete-protect/49550&lt;br /&gt;
&lt;br /&gt;
https://hexdocs.pm/ecto/Ecto.Changeset.html#unique_constraint/3&lt;br /&gt;
&lt;br /&gt;
____________________________________________________________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== How to Create a Mix Project and Use It in Another Mix Project ==&lt;br /&gt;
&lt;br /&gt;
To create and use a **Mix project** inside another **Mix project** in Elixir, follow the steps below:&lt;br /&gt;
&lt;br /&gt;
=== 1. Create a New Mix Project ===&lt;br /&gt;
&lt;br /&gt;
First, you need to create a new Mix project. Let's call this project `library_project`. Run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mix new library_project --module LibraryProject&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will create a new Elixir Mix project named `library_project`. The `--module` flag specifies the name of the module that will be created (in this case `LibraryProject`).&lt;br /&gt;
&lt;br /&gt;
The directory structure of `library_project` will look like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
library_project/&lt;br /&gt;
  |_ lib/&lt;br /&gt;
      |_ library_project.ex&lt;br /&gt;
  |_ mix.exs&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can then add some basic functionality inside the `library_project/lib/library_project.ex` file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule LibraryProject do&lt;br /&gt;
  def hello do&lt;br /&gt;
    IO.puts &amp;quot;Hello from LibraryProject!&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now, `library_project` is ready to be used by another Mix project.&lt;br /&gt;
&lt;br /&gt;
=== 2. Create a Second Mix Project ===&lt;br /&gt;
&lt;br /&gt;
Next, create the second Mix project where you want to use `library_project`. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mix new app_project --module AppProject&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will create another Elixir project called `app_project`.&lt;br /&gt;
&lt;br /&gt;
The directory structure for this project will look like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
app_project/&lt;br /&gt;
  |_ lib/&lt;br /&gt;
      |_ app_project.ex&lt;br /&gt;
  |_ mix.exs&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 3. Add `library_project` as a Dependency in `app_project` ===&lt;br /&gt;
&lt;br /&gt;
Now, you want to make `library_project` available in `app_project`. There are two main ways to do this:&lt;br /&gt;
&lt;br /&gt;
==== Option 1: Local Dependency (via `path`) ====&lt;br /&gt;
&lt;br /&gt;
If `library_project` is a local project (i.e., it's stored in a different directory), you can add it to the `mix.exs` of `app_project` as a local dependency by specifying the path to `library_project`.&lt;br /&gt;
&lt;br /&gt;
Edit the `mix.exs` of `app_project`:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule AppProject.MixProject do&lt;br /&gt;
  use Mix.Project&lt;br /&gt;
&lt;br /&gt;
  def project do&lt;br /&gt;
    [&lt;br /&gt;
      app: :app_project,&lt;br /&gt;
      version: &amp;quot;0.1.0&amp;quot;,&lt;br /&gt;
      elixir: &amp;quot;~&amp;gt; 1.14&amp;quot;,&lt;br /&gt;
      start_permanent: Mix.env() == :prod,&lt;br /&gt;
      deps: deps()&lt;br /&gt;
    ]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  defp deps do&lt;br /&gt;
    [&lt;br /&gt;
      {:library_project, path: &amp;quot;../library_project&amp;quot;}  # Add the local dependency&lt;br /&gt;
    ]&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here, `{:library_project, path: &amp;quot;../library_project&amp;quot;}` tells Mix to use the local `library_project` located in the `../library_project` directory (relative to `app_project`).&lt;br /&gt;
&lt;br /&gt;
After updating the `mix.exs`, run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd app_project&lt;br /&gt;
mix deps.get&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will fetch the dependency and compile `library_project`.&lt;br /&gt;
&lt;br /&gt;
==== Option 2: Publish and Fetch as a Hex Package ====&lt;br /&gt;
&lt;br /&gt;
If you want to use `library_project` as a package in another project (for example, by publishing it to **Hex.pm**, Elixir’s package manager), you need to publish it to Hex and then add it as a dependency.&lt;br /&gt;
&lt;br /&gt;
1. Publish `library_project` to Hex (if it's public or for your private use).&lt;br /&gt;
2. Add `library_project` to your `app_project`’s `mix.exs` dependencies:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defp deps do&lt;br /&gt;
  [&lt;br /&gt;
    {:library_project, &amp;quot;~&amp;gt; 0.1.0&amp;quot;}  # Specify the published version from Hex&lt;br /&gt;
  ]&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Run `mix deps.get` to fetch the package from Hex.&lt;br /&gt;
&lt;br /&gt;
=== 4. Use `library_project` in `app_project` ===&lt;br /&gt;
&lt;br /&gt;
Now, you can use the functionality from `library_project` inside your `app_project`. For example, in `app_project/lib/app_project.ex`, you can call the function from `library_project`:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule AppProject do&lt;br /&gt;
  def start do&lt;br /&gt;
    IO.puts &amp;quot;Starting app_project!&amp;quot;&lt;br /&gt;
    LibraryProject.hello()  # Call the function from the library_project&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 5. Run the App ===&lt;br /&gt;
&lt;br /&gt;
Finally, you can run your `app_project`:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd app_project&lt;br /&gt;
mix run -e &amp;quot;AppProject.start()&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will print:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Starting app_project!&lt;br /&gt;
Hello from LibraryProject!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Recap of the Process ==&lt;br /&gt;
1. **Create the `library_project`**: Use `mix new` to generate a library project.&lt;br /&gt;
2. **Create the `app_project`**: Create the second project where you will use the library.&lt;br /&gt;
3. **Add the `library_project` as a dependency**:&lt;br /&gt;
   - Use the `path` option to point to the local project or publish it to Hex for public access.&lt;br /&gt;
4. **Use the `library_project` in the `app_project`**: Call functions or use modules from the library inside the second project.&lt;br /&gt;
5. **Run the app**: Use `mix run` to execute the project.&lt;br /&gt;
&lt;br /&gt;
This way, you can reuse code from one Mix project in another by adding it as a dependency.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==z==&lt;br /&gt;
Overloaded functions are extremely common in Elixir applications. They are&lt;br /&gt;
regularly used for recursive functions and for changing behavior based on&lt;br /&gt;
configuration.&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>http://elixirblocks.com/index.php?title=User:Admin&amp;diff=1881</id>
		<title>User:Admin</title>
		<link rel="alternate" type="text/html" href="http://elixirblocks.com/index.php?title=User:Admin&amp;diff=1881"/>
		<updated>2025-03-11T20:03:45Z</updated>

		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;https://thepugautomatic.com/2020/08/communicating-between-liveviews-on-the-same-page/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
from(a in Article,&lt;br /&gt;
  order_by: [desc: a.inserted_at],  # Assuming 'inserted_at' is the timestamp for when the article was created or updated&lt;br /&gt;
  limit: 8&lt;br /&gt;
)&lt;br /&gt;
|&amp;gt; Repo.all()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.Landing do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  alias App.Testbeds&lt;br /&gt;
  alias App.Testbeds.Testbed&lt;br /&gt;
  alias App.Repo  # Ensure to alias Repo&lt;br /&gt;
  import Ecto.Query  # Import Ecto.Query to work with queries&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    # Default to ordering by name&lt;br /&gt;
    testbeds = Repo.all(from(t in Testbed, order_by: t.name))&lt;br /&gt;
&lt;br /&gt;
    # Assign the testbeds to the socket for rendering&lt;br /&gt;
    {:ok, assign(socket, testbeds: testbeds, sort: :name)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    &amp;lt;h1&amp;gt;Hello World! YAY&amp;lt;/h1&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;div&amp;gt;&lt;br /&gt;
      &amp;lt;!-- Buttons to toggle sorting --&amp;gt;&lt;br /&gt;
      &amp;lt;button phx-click=&amp;quot;sort_by_name&amp;quot;&amp;gt;Sort by Name&amp;lt;/button&amp;gt;&lt;br /&gt;
      &amp;lt;button phx-click=&amp;quot;sort_by_updated_at&amp;quot;&amp;gt;Sort by Updated By&amp;lt;/button&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;ul&amp;gt;&lt;br /&gt;
      &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
        &amp;lt;li&amp;gt;&amp;lt;%= testbed.name %&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;% end %&amp;gt;&lt;br /&gt;
    &amp;lt;/ul&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;sort_by_name&amp;quot;, _params, socket) do&lt;br /&gt;
    testbeds = Repo.all(from(t in Testbed, order_by: t.name))&lt;br /&gt;
    {:noreply, assign(socket, testbeds: testbeds, sort: :name)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;sort_by_updated_at&amp;quot;, _params, socket) do&lt;br /&gt;
    testbeds = Repo.all(from(t in Testbed, order_by: t.inserted_at))&lt;br /&gt;
    {:noreply, assign(socket, testbeds: testbeds, sort: :inserted_at)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
_______________________________________________________&lt;br /&gt;
&lt;br /&gt;
* Create a form with a post request. &lt;br /&gt;
* Create the route needed for that request&lt;br /&gt;
* Create the controller needed for that route&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Form==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;.form action={~p&amp;quot;/todos&amp;quot;} method=&amp;quot;post&amp;quot; class=&amp;quot;mt-10 space-y-8&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    &amp;lt;label for=&amp;quot;contact_name&amp;quot; class=&amp;quot;block text-sm font-semibold leading-6 text-zinc-800&amp;quot;&amp;gt;&lt;br /&gt;
      Name&lt;br /&gt;
    &amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;input&lt;br /&gt;
      id=&amp;quot;todo&amp;quot;&lt;br /&gt;
      type=&amp;quot;text&amp;quot;&lt;br /&gt;
      name=&amp;quot;todo&amp;quot;&lt;br /&gt;
      class=&amp;quot;mt-2 block w-full rounded-lg text-zinc-900 focus:ring-0 sm:text-sm sm:leading-6 border-zinc-300 focus:border-zinc-400&amp;quot;&lt;br /&gt;
    /&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;button&lt;br /&gt;
    type=&amp;quot;submit&amp;quot;&lt;br /&gt;
    class=&amp;quot;rounded-lg bg-zinc-900 hover:bg-zinc-700 py-2 px-3 text-sm font-semibold leading-6 text-white active:text-white/80&amp;quot;&lt;br /&gt;
  &amp;gt;&lt;br /&gt;
    Save Contact&lt;br /&gt;
  &amp;lt;/button&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/.form&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Controller==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# In your TodoController&lt;br /&gt;
defmodule AppWeb.TodoController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  # Action to handle the form submission (POST request)&lt;br /&gt;
  def create(conn, %{&amp;quot;todo&amp;quot; =&amp;gt; todo_name}) do&lt;br /&gt;
    # Here you can handle the form data (e.g., save it to the database)&lt;br /&gt;
    IO.puts(&amp;quot;Received Todo: #{todo_name}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    # For now, let's just redirect to the home page&lt;br /&gt;
    conn&lt;br /&gt;
    |&amp;gt; put_flash(:info, &amp;quot;Todo saved!&amp;quot;)&lt;br /&gt;
    |&amp;gt; redirect(to: &amp;quot;/&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
________________________________________________________&lt;br /&gt;
&lt;br /&gt;
# CRUD Forms&lt;br /&gt;
&lt;br /&gt;
To understand CRUD forms you will need to understand the following concepts. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Ecto Schema&lt;br /&gt;
* Ecto Context&lt;br /&gt;
* Form Basics&lt;br /&gt;
* form/1&lt;br /&gt;
* simple_form/1&lt;br /&gt;
* changesets&lt;br /&gt;
&lt;br /&gt;
We are not going to go in order. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The Context provides CRUD functions for the chosen data schema. Phoenix contexts define the interface through which other parts of the codebase can interact with the app layer.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_______________________&lt;br /&gt;
* Create routes&lt;br /&gt;
* create page with form (submit get request)&lt;br /&gt;
&lt;br /&gt;
(ecto schema, context, changesets)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_______________________________________________________&lt;br /&gt;
In that case, you really should switch it to prod mode. Instead of doing all that above with the &amp;quot;config/secret.exs&amp;quot; file, create the &amp;quot;.env&amp;quot; in the project root, then add DotenvParser.load_file(&amp;quot;.env&amp;quot;) to &amp;quot;config/runtime.exs&amp;quot; as the first line inside the if config_env() == :prod do. In the .env file, set the DATABASE_URL and SECRET_KEY_BASE. Then run it as MIX_ENV=prod mix phx.server.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def get_titles do&lt;br /&gt;
    urls = [&lt;br /&gt;
      &amp;quot;https://cointelegraph.com/rss&amp;quot;,&lt;br /&gt;
      &amp;quot;https://chaski.huffpost.com/us/auto/vertical/us-news&amp;quot;&lt;br /&gt;
      # Add more RSS feed URLs here&lt;br /&gt;
    ]&lt;br /&gt;
&lt;br /&gt;
    urls&lt;br /&gt;
    |&amp;gt; Enum.map(fn url -&amp;gt;&lt;br /&gt;
      with {:ok, feed} &amp;lt;- ElixirRss.fetch_and_parse(url) do&lt;br /&gt;
        Enum.map(feed.entries, &amp;amp; &amp;amp;1.title)&lt;br /&gt;
      else&lt;br /&gt;
        {:error, reason} -&amp;gt; {:error, reason}&lt;br /&gt;
      end&lt;br /&gt;
    end)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule App do&lt;br /&gt;
&lt;br /&gt;
  def get_titles() do&lt;br /&gt;
    data = [&lt;br /&gt;
      &amp;quot;https://cointelegraph.com/rss&amp;quot;,&lt;br /&gt;
      &amp;quot;https://chaski.huffpost.com/us/auto/vertical/us-news&amp;quot;&lt;br /&gt;
      # Add more RSS feed URLs here&lt;br /&gt;
    ]&lt;br /&gt;
&lt;br /&gt;
    data&lt;br /&gt;
    |&amp;gt; Enum.map(fn url -&amp;gt;&lt;br /&gt;
      case ElixirRss.fetch_and_parse(url) do&lt;br /&gt;
        {:ok, feed} -&amp;gt; feed.entries |&amp;gt; Enum.map(fn entry -&amp;gt; entry end)&lt;br /&gt;
        {:error, reason} -&amp;gt; {:error, reason}&lt;br /&gt;
      end&lt;br /&gt;
    end)&lt;br /&gt;
    |&amp;gt; Enum.map(fn entry_list -&amp;gt;&lt;br /&gt;
      entry_list&lt;br /&gt;
      |&amp;gt; Enum.map(fn entry -&amp;gt; entry.title end)&lt;br /&gt;
    end)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def hello do&lt;br /&gt;
    rss_feeds = [&lt;br /&gt;
      &amp;quot;https://cointelegraph.com/rss&amp;quot;,&lt;br /&gt;
      &amp;quot;https://chaski.huffpost.com/us/auto/vertical/us-news&amp;quot;&lt;br /&gt;
      # Add more RSS feed URLs here&lt;br /&gt;
    ]&lt;br /&gt;
&lt;br /&gt;
    rss_feeds&lt;br /&gt;
    |&amp;gt; Enum.map(fn url -&amp;gt;&lt;br /&gt;
      case ElixirRss.fetch_and_parse(url) do&lt;br /&gt;
        {:ok, feed} -&amp;gt; feed.entries |&amp;gt; Enum.map(fn entry -&amp;gt; entry end)&lt;br /&gt;
        {:error, reason} -&amp;gt; {:error, reason}&lt;br /&gt;
      end&lt;br /&gt;
    end)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    if connected?(socket) do&lt;br /&gt;
      Phoenix.PubSub.subscribe(App.PubSub, &amp;quot;message&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
    {:ok, assign(socket, message_item: &amp;quot;different&amp;quot;)}&lt;br /&gt;
  end&lt;br /&gt;
  def handle_info({:pubsub_transmission, text}, socket) do&lt;br /&gt;
    IO.inspect &amp;quot;pub sub working&amp;quot;&lt;br /&gt;
    {:noreply, assign(socket, message_item: text)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def loop(data) do&lt;br /&gt;
     IO.inspect data&lt;br /&gt;
     if data &amp;gt; 0 do&lt;br /&gt;
      IO.inspect &amp;quot;notify&amp;quot;&lt;br /&gt;
      # run code to compare files, loop. If different run pubsub code below&lt;br /&gt;
      :timer.sleep(2000)&lt;br /&gt;
      loop(data-1)&lt;br /&gt;
&lt;br /&gt;
     end&lt;br /&gt;
     if data &amp;lt;= 0 do&lt;br /&gt;
&lt;br /&gt;
      Phoenix.PubSub.broadcast(App.PubSub, &amp;quot;message&amp;quot;, {:pubsub_transmission, &amp;quot;data&amp;quot;})&lt;br /&gt;
      &amp;quot;done&amp;quot;&lt;br /&gt;
     end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;change-text&amp;quot;, _params, socket) do&lt;br /&gt;
    spawn(fn -&amp;gt; loop(3) end)&lt;br /&gt;
    {:noreply, assign(socket, message_item: &amp;quot;START&amp;quot; )}&lt;br /&gt;
  end&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
&lt;br /&gt;
    # AppWeb.PageLive.loop(&amp;quot;xxx&amp;quot;)&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    SANDBOX&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;.button phx-click=&amp;quot;change-text&amp;quot; value={@message_item}&amp;gt;CLICK ME&amp;lt;/.button&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;%= @message_item %&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
elixir :   1.16.2&lt;br /&gt;
&lt;br /&gt;
Erl:   20&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# PostGres&lt;br /&gt;
Created Saturday 18 February 2023&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Launch [PostGres](#PostGres) from Terminal&lt;br /&gt;
------------------------------------------&lt;br /&gt;
sudo -u postgres psql&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Set User Permission&lt;br /&gt;
-------------------&lt;br /&gt;
&amp;lt;https://commandprompt.com/education/how-to-create-a-superuser-in-postgresql/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ALTER USER user_name WITH PASSWORD 'new_password';&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Run Post Gres Commands&lt;br /&gt;
----------------------&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
sudo -i -u postgres&lt;br /&gt;
psql&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Create and Delete Database&lt;br /&gt;
&lt;br /&gt;
CREATE DATABASE name;&lt;br /&gt;
DROP DATABASE name;&lt;br /&gt;
## View user list&lt;br /&gt;
&lt;br /&gt;
\du&lt;br /&gt;
&lt;br /&gt;
 View all databases&lt;br /&gt;
&lt;br /&gt;
postgres=# \l&lt;br /&gt;
&lt;br /&gt;
 Change databases&lt;br /&gt;
&lt;br /&gt;
postgres=# \c    name-of-database&lt;br /&gt;
&lt;br /&gt;
View Tables&lt;br /&gt;
&lt;br /&gt;
After you change databases and are selected on one of them do this:&lt;br /&gt;
&lt;br /&gt;
\dt&lt;br /&gt;
&lt;br /&gt;
SELECT * FROM mytablename;&lt;br /&gt;
&lt;br /&gt;
EMPTY TABLE&lt;br /&gt;
DELETE FROM name-of-table&lt;br /&gt;
&lt;br /&gt;
CREATE TABLE&lt;br /&gt;
&lt;br /&gt;
CREATE TABLE table_name(&lt;br /&gt;
   column1 datatype,&lt;br /&gt;
   column2 datatype,&lt;br /&gt;
   column3 datatype,&lt;br /&gt;
   .....&lt;br /&gt;
   columnN datatype,&lt;br /&gt;
   PRIMARY KEY( one or more columns )&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
INSERT&lt;br /&gt;
&lt;br /&gt;
INSERT INTO ITEMS(id, name) VALUES(1,'htvjbjbgni');     Strings are single quote&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Roadmap==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.ItemsLive do&lt;br /&gt;
    use AppWeb, :live_view  &lt;br /&gt;
    def mount(_params, _session, socket)  do&lt;br /&gt;
      {:ok, assign(socket, switches: [&amp;quot;grindy&amp;quot;,&amp;quot;sonic&amp;quot;,&amp;quot;ogre&amp;quot;])}  &lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    def handle_event(&amp;quot;run&amp;quot;,_params,socket) do  &lt;br /&gt;
        &lt;br /&gt;
        IO.inspect &amp;quot;DOWNLOAD VIA SSH&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        {:noreply, redirect(socket, to: &amp;quot;/download&amp;quot;)}&lt;br /&gt;
&lt;br /&gt;
    end&lt;br /&gt;
   &lt;br /&gt;
&lt;br /&gt;
    def render(assigns) do&lt;br /&gt;
        &lt;br /&gt;
        ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        &amp;lt;ul&amp;gt;&lt;br /&gt;
        &amp;lt;%= for switch &amp;lt;- @switches do %&amp;gt;&lt;br /&gt;
         &amp;lt;a phx-submit=&amp;quot;click&amp;quot; href=&amp;quot;/download&amp;quot;&amp;gt;  &amp;lt;li&amp;gt; &amp;lt;%= switch %&amp;gt;  &amp;lt;/li&amp;gt; &amp;lt;/a&amp;gt;&lt;br /&gt;
&lt;br /&gt;
        &amp;lt;%end%&amp;gt;&lt;br /&gt;
        &amp;lt;/ul&amp;gt;&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot; &lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Notes==&lt;br /&gt;
List of Switches and the option to select the one needed.&lt;br /&gt;
Button to download JSON file.&lt;br /&gt;
Drag and Drop Palette to upload JSON file.&lt;br /&gt;
&lt;br /&gt;
After JSON file is uploaded a button titled &amp;quot;Make Active&amp;quot; is available.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://medium.com/@fraiha26/pushing-events-to-livecomponents-from-js-hooks-w-phoenix-elixir-d5544d4c3dfa&lt;br /&gt;
&lt;br /&gt;
Changeset notes and forms&lt;br /&gt;
&lt;br /&gt;
NOTE: Use case statements for pattern matching&lt;br /&gt;
____________________________________________&lt;br /&gt;
&lt;br /&gt;
Create a basic &amp;lt;.form&amp;gt;&amp;lt;/form&amp;gt; without error handling&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&amp;lt;.form :let={f} for={@changeset}  action={~p&amp;quot;/items&amp;quot;} &amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;.input field={f[:title]} type=&amp;quot;text&amp;quot; label=&amp;quot;Title&amp;quot; /&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
  &amp;lt;.button&amp;gt;Save Item&amp;lt;/.button&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;/.form&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With error handling looks like this:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;.form :let={f} for={@changeset}  action={~p&amp;quot;/items&amp;quot;} &amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;.error :if={@changeset.action}&amp;gt;&lt;br /&gt;
    Oops, something went wrong! Please check the errors below.&lt;br /&gt;
  &amp;lt;/.error&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;.input field={f[:title]} type=&amp;quot;text&amp;quot; label=&amp;quot;Title&amp;quot; /&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
  &amp;lt;.button&amp;gt;Save Item&amp;lt;/.button&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;/.form&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Create the routes for render and post to endpoint.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The controller for the page render needs to pass in the changeset via ```Items.change_item(%Item{})```&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  def new(conn, _params) do&lt;br /&gt;
    changeset = Items.change_item(%Item{})&lt;br /&gt;
    render(conn, :new, changeset: changeset)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Post route without error handling&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  def create(conn, %{&amp;quot;item&amp;quot; =&amp;gt; item_params}) do&lt;br /&gt;
    case Items.create_item(item_params) do&lt;br /&gt;
      {:ok, item} -&amp;gt;&lt;br /&gt;
        conn&lt;br /&gt;
        |&amp;gt; put_flash(:info, &amp;quot;Item created successfully.&amp;quot;)&lt;br /&gt;
        |&amp;gt; redirect(to: ~p&amp;quot;/items/#{item}&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With error handling&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  def create(conn, %{&amp;quot;item&amp;quot; =&amp;gt; item_params}) do&lt;br /&gt;
    case Items.create_item(item_params) do&lt;br /&gt;
      {:ok, item} -&amp;gt;&lt;br /&gt;
        conn&lt;br /&gt;
        |&amp;gt; put_flash(:info, &amp;quot;Item created successfully.&amp;quot;)&lt;br /&gt;
        |&amp;gt; redirect(to: ~p&amp;quot;/items/#{item}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
      {:error, %Ecto.Changeset{} = changeset} -&amp;gt;&lt;br /&gt;
        render(conn, :new, changeset: changeset)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_____________________________________________&lt;br /&gt;
https://medium.com/@vincentlin/phoenix-very-simple-form-c4b121697fcb&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''home.html.heex'''&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&amp;lt;form action=&amp;quot;/submit&amp;quot; method=&amp;quot;post&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;label for=&amp;quot;name&amp;quot;&amp;gt;Name:&amp;lt;/label&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;input type=&amp;quot;text&amp;quot; id=&amp;quot;name&amp;quot; name=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;_csrf_token&amp;quot; value={@csrf_token} /&amp;gt;&lt;br /&gt;
  &amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Submit&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
page_controller.ex&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.PageController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  def home(conn, _params) do&lt;br /&gt;
    # The home page is often custom made,&lt;br /&gt;
&lt;br /&gt;
    csrf_token = Plug.CSRFProtection.get_csrf_token()&lt;br /&gt;
    render(conn, :home, csrf_token: csrf_token)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def submit(conn, _params) do&lt;br /&gt;
    # The home page is often custom made,&lt;br /&gt;
     IO.inspect(_params)&lt;br /&gt;
     IO.inspect &amp;quot;___________________________&amp;quot;&lt;br /&gt;
    csrf_token = Plug.CSRFProtection.get_csrf_token()&lt;br /&gt;
    render(conn, :home, csrf_token: csrf_token)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
router.ex&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  scope &amp;quot;/&amp;quot;, AppWeb do&lt;br /&gt;
    pipe_through :browser&lt;br /&gt;
    post &amp;quot;/submit&amp;quot;, PageController, :submit&lt;br /&gt;
    get &amp;quot;/&amp;quot;, PageController, :home&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ecto.Adapters.SQL.query(Repo, &amp;quot;select * from artists where id=1&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ecto cheatsheet:  https://hexdocs.pm/ecto/crud.html&lt;br /&gt;
__________________________________________________________________&lt;br /&gt;
Most programming languages give you the ability to set global state by creating globally scoped variables. Elixir does not do this. Instead, Elixir provides a tool called a &amp;quot;processes&amp;quot; to persist  state. Elixir applications are composed of these &amp;quot;processes&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
Processes by themselves are complicated to use, thus Elixir provides abstractions to make working with processes easier. One of these abstractions is called a GenServer.&lt;br /&gt;
&lt;br /&gt;
GenServers are not only used to store state, they are also used to invoke work independent of the main application process. &lt;br /&gt;
&lt;br /&gt;
==Creating a GenServer to Store State==&lt;br /&gt;
&lt;br /&gt;
To Create a GenServer, start by creating a basic Module that ''uses'' the GenServer module (image below)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule App do  &lt;br /&gt;
  use GenServer&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We now need to describe the actions we want to perform. Being that this is used to store state, we will use basic CRUD actions: Create, Read, Update, Delete. To begins, empty functions describing each action is created.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule App do&lt;br /&gt;
   def create do &lt;br /&gt;
&lt;br /&gt;
   end&lt;br /&gt;
   def read do &lt;br /&gt;
&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
   def update do  &lt;br /&gt;
&lt;br /&gt;
   end &lt;br /&gt;
&lt;br /&gt;
   def delete do &lt;br /&gt;
&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==What now?==&lt;br /&gt;
&lt;br /&gt;
To fill in the functions with the appropriate code we must first have a basic understanding of how GenServers are structured.&lt;br /&gt;
&lt;br /&gt;
GenServers are composed of the GenServer module invoking callbacks. The callbacks have built in names that you, as a developer have to use.&lt;br /&gt;
&lt;br /&gt;
These callbacks are named:&lt;br /&gt;
&lt;br /&gt;
* init&lt;br /&gt;
* handle_cast&lt;br /&gt;
* handle_call&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To demonstrate, here is an example :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{:ok, pid} = GenServer.start(ModuleNameOfGenServer, %{})&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above function named &amp;quot;start&amp;quot; calls the function named init in the Module below.&lt;br /&gt;
In GenServer syntax the name of the GenServer functions always invoke callbacks that are determined by the language. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule ModuleNameOfGenServer do&lt;br /&gt;
  # 1&lt;br /&gt;
  def init(state \\ %{}) do&lt;br /&gt;
    {:ok, state}&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is a list of the GenServer functions and their corresponding callbacks.&lt;br /&gt;
&lt;br /&gt;
* GenServer.start/1  --&amp;gt;       init/1&lt;br /&gt;
* GenServer.call/3   --&amp;gt;       def handle_call/3&lt;br /&gt;
* GenServer.cast/2   --&amp;gt;       handle_cast/2&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Start and Call ==&lt;br /&gt;
&lt;br /&gt;
Call and Cast can be used to perform the same operations. The &lt;br /&gt;
&lt;br /&gt;
__________________________________________________________&lt;br /&gt;
Genserver timed events&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule Go do&lt;br /&gt;
  use GenServer&lt;br /&gt;
&lt;br /&gt;
  def go() do&lt;br /&gt;
    GenServer.start_link(__MODULE__, [])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def init(list) do&lt;br /&gt;
    :timer.apply_interval(1000, __MODULE__, :add, [self(), &amp;quot;weeeee&amp;quot;])&lt;br /&gt;
    {:ok, list}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def view(pid) do&lt;br /&gt;
    GenServer.call(pid, :view)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_call(:view, _from, list) do&lt;br /&gt;
    {:reply, list, list}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def add(pid, new_item) do&lt;br /&gt;
    GenServer.call(pid, {:item, new_item})&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_call({:item, new_item}, _from, state) do&lt;br /&gt;
    result = [new_item] ++ state&lt;br /&gt;
    {:reply, result, result}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule ShoppingList do&lt;br /&gt;
  use GenServer&lt;br /&gt;
&lt;br /&gt;
  def start_link() do&lt;br /&gt;
    GenServer.start_link(ShoppingList, [])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def init(list) do&lt;br /&gt;
    {:ok, list}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def view(pid) do&lt;br /&gt;
    GenServer.call(pid, :view)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_call(:view, _from, list) do&lt;br /&gt;
    {:reply, list, list}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def add(pid, new_item) do&lt;br /&gt;
    GenServer.call(pid, {:item, new_item})&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_call({:item, new_item}, _from, state) do&lt;br /&gt;
    result = [new_item] ++ state&lt;br /&gt;
    {:reply, result, result}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://blog.appsignal.com/2018/06/12/elixir-alchemy-deconstructing-genservers.html&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule KeyValue do&lt;br /&gt;
  # 1&lt;br /&gt;
  def init(state \\ %{}) do&lt;br /&gt;
    {:ok, state}&lt;br /&gt;
  end&lt;br /&gt;
 &lt;br /&gt;
  # 2&lt;br /&gt;
  def handle_cast({:put, key, value}, state) do&lt;br /&gt;
    {:noreply, Map.put(state, key, value)}&lt;br /&gt;
  end&lt;br /&gt;
 &lt;br /&gt;
  # 3&lt;br /&gt;
  def handle_call({:get, key}, _from, state) do&lt;br /&gt;
    {:reply, Map.fetch!(state, key), state}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
# {:ok, pid} = GenServer.start(KeyValue, %{})&lt;br /&gt;
# GenServer.cast(pid, {:put, :foo, &amp;quot;bar&amp;quot;})&lt;br /&gt;
# GenServer.call(pid, {:get, :foo})&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Send messages via these functions wrapped in module functions .You can look at these are functions used to fire &amp;quot;GenServer Events&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
* start_link&lt;br /&gt;
* GenServer.call&lt;br /&gt;
* GenServer.cast&lt;br /&gt;
&lt;br /&gt;
The corresponding server functions that reply are:&lt;br /&gt;
&lt;br /&gt;
* init&lt;br /&gt;
* handle__call&lt;br /&gt;
* handle_cast&lt;br /&gt;
* &lt;br /&gt;
&lt;br /&gt;
These can be looked at as &amp;quot;listeners&amp;quot; - in JavaScript parlance. &lt;br /&gt;
__________________________________________&lt;br /&gt;
&lt;br /&gt;
If you have experience with programming languages other than Elixir the idea of GenServers may be very foreign and require a strong context shift to learn. This document is intended to simplify the concept.&lt;br /&gt;
&lt;br /&gt;
* What: GenServers are simply a way to hold state and/or invoke actions based on incoming events. &lt;br /&gt;
* when &lt;br /&gt;
* where&lt;br /&gt;
* why&lt;br /&gt;
* how&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
___________________________________________&lt;br /&gt;
GenServer timer example&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule Timer do&lt;br /&gt;
  use GenServer&lt;br /&gt;
&lt;br /&gt;
  def init(_) do&lt;br /&gt;
    :timer.send_interval(1000, :xyz)&lt;br /&gt;
    {:ok, 0}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_info(:xyz, state) do&lt;br /&gt;
    IO.inspect(state)&lt;br /&gt;
    {:noreply, state + 1}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
[&lt;br /&gt;
   {&lt;br /&gt;
     data:{&lt;br /&gt;
        creationTime,&lt;br /&gt;
        publishDate,&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
     featured:{&lt;br /&gt;
        setAmount,&lt;br /&gt;
        items:[]&lt;br /&gt;
     },&lt;br /&gt;
&lt;br /&gt;
     children:{&lt;br /&gt;
        setAmount,&lt;br /&gt;
        items:[]&lt;br /&gt;
     },&lt;br /&gt;
     links:{&lt;br /&gt;
        setAmount,&lt;br /&gt;
        items:[]&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
jason.encode / jason.decode&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  def run(num) do&lt;br /&gt;
&lt;br /&gt;
    Enum.each(0..99999, fn(_x) -&amp;gt;&lt;br /&gt;
      task = Task.async(fn -&amp;gt; num + _x end)&lt;br /&gt;
    IO.inspect Task.await(task)&lt;br /&gt;
  end)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enum.map(feed.entries, fn x -&amp;gt; %{url: x.url, title: x.title} end)&lt;br /&gt;
&lt;br /&gt;
App is split:&lt;br /&gt;
&lt;br /&gt;
App that captures RSS in UI and lets admin select stories. THere are settings to determine the number of FEATURED,CHILD and LINK stories.&lt;br /&gt;
News categories are horizontal and scrollable.&lt;br /&gt;
This exports a json doc with all RSS data for each story.&lt;br /&gt;
The &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
App that reads the json data. This app creates tables and is the front end.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://stephenbussey.com/tags/elixir.html&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule AppWeb.GroupLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  alias App.TestBeds&lt;br /&gt;
  alias App.Groups&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    {:ok, assign(socket, testbeds: TestBeds.list_testbeds(), groups: Groups.list_groups())}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;select-group&amp;quot;, params, socket)  do  &lt;br /&gt;
     group = App.Groups.get_group!(params[&amp;quot;group-id&amp;quot;])&lt;br /&gt;
     testbed = App.TestBeds.get_test_bed!(params[&amp;quot;testbed_id&amp;quot;])&lt;br /&gt;
     App.TestBeds.update_test_bed(testbed, %{group_id: group.id})&lt;br /&gt;
     {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def updated_groups(testbed_id)  do  &lt;br /&gt;
     testbed = App.TestBeds.get_test_bed!(testbed_id)&lt;br /&gt;
     groups = App.Groups.list_groups&lt;br /&gt;
     tail = Enum.filter(groups, fn(item)-&amp;gt; item.id !== testbed.group_id end)&lt;br /&gt;
     head = Enum.filter(groups, fn(item)-&amp;gt; item.id == testbed.group_id end)&lt;br /&gt;
            |&amp;gt;Enum.at(0)&lt;br /&gt;
    [head | tail]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        &amp;lt;%= for testbed &amp;lt;- Enum.sort_by(@testbeds , &amp;amp;(&amp;quot;#{&amp;amp;1.name}&amp;quot;), :asc)do %&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;grid grid-cols-4 gap-4 p-8 rounded shadow bg-white&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;h2&amp;gt; Name&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;%= testbed.name %&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;h2&amp;gt; Group&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div&amp;gt;&lt;br /&gt;
            &amp;lt;form phx-change=&amp;quot;select-group&amp;quot; name=&amp;quot;testbed_id&amp;quot;  &amp;gt;&lt;br /&gt;
               &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;testbed_id&amp;quot; value={testbed.id}/&amp;gt;&lt;br /&gt;
               &amp;lt;select id=&amp;quot;group-selection&amp;quot;  name=&amp;quot;group-id&amp;quot; class=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;%= for group &amp;lt;- updated_groups(testbed.id) do %&amp;gt;&lt;br /&gt;
                  &amp;lt;%= if group !== nil do %&amp;gt;&lt;br /&gt;
                      &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}&amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
                      &amp;lt;%else%&amp;gt;&lt;br /&gt;
                      &amp;lt;option value= {&amp;quot;Unassigned&amp;quot;}&amp;gt;NONE&amp;lt;/option&amp;gt;&lt;br /&gt;
                  &amp;lt;% end %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
               &amp;lt;/select&amp;gt;&lt;br /&gt;
            &amp;lt;/form&amp;gt;&lt;br /&gt;
          &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
       &amp;lt;% end %&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Developer Notes ==&lt;br /&gt;
===Groups Feature ===&lt;br /&gt;
To complete this feature do these things.&lt;br /&gt;
* Run through the steps in [http://elixirblocks.com/index.php?title=Create_Foreign_Key_Relationship_Between_Ecto_Tables  | this document] to create Group table.&lt;br /&gt;
* Groups have these fields  '''name: string''', '''description: string''' and '''color: string'''  &lt;br /&gt;
* Add unique constraint in migration file: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def change do&lt;br /&gt;
     create unique_index(:groups, [:name])&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Port over Group LiveView code (temporarily placed at discussion page).&lt;br /&gt;
* On completion '''possibly''', create a Group named '''No Group''' and set all Testbeds to it.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
________&lt;br /&gt;
https://blog.appsignal.com/2022/10/11/phoenix-liveview-018-new-special-html-attributes.html&lt;br /&gt;
https://blixtdev.com/whats-new-phoenix-1-7/&lt;br /&gt;
https://github.com/devato/inertia_phoenix&lt;br /&gt;
https://phoenixonrails.com/blog/you-can-stop-using-form-for-in-phoenix&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://samuelmullen.com/articles/phoenix_templates_rendering_and_layouts&lt;br /&gt;
&lt;br /&gt;
WorkFlow of Todo App in Both LiveView and DeadView.&lt;br /&gt;
&lt;br /&gt;
Note:&lt;br /&gt;
&lt;br /&gt;
Create foreign key data.&lt;br /&gt;
Create live view. List all testbeds and form to assign each a group by group-name.&lt;br /&gt;
&lt;br /&gt;
Repeat in dead view&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Mental model and data flows&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
home.html.heex&lt;br /&gt;
&amp;lt;a href=&amp;quot;/data&amp;quot; name=&amp;quot;we are the world&amp;quot; &amp;gt;  click me&amp;lt;/a&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;%= @message %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
page controller&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  def home(conn, _params) do&lt;br /&gt;
    IO.inspect _params&lt;br /&gt;
    render(conn, :home, message: &amp;quot;Hello&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
get &amp;quot;/:yay&amp;quot;, PageController, :index&lt;br /&gt;
&lt;br /&gt;
get &amp;quot;/&amp;quot;, PageController, :index&lt;br /&gt;
&lt;br /&gt;
* Explain control flow of &amp;quot;Dead Views&amp;quot; and the Generator HTML Control flow.&lt;br /&gt;
* Proper Way to use Modal&lt;br /&gt;
* How to give Focus to Fields in Modal (or other forms fields)&lt;br /&gt;
* &lt;br /&gt;
* &lt;br /&gt;
* How to Create Database Seed Data.&lt;br /&gt;
* How to structure code so controller code is in one file and HTML Heex is in another&lt;br /&gt;
* How to Use Generators in a Real World Project&lt;br /&gt;
* How to Work with Database Data via Basic Commands and Custom Change sets.&lt;br /&gt;
* How to Render Database Data to LiveView (via Context Commands).&lt;br /&gt;
* How to Create a Chat using PubSub.&lt;br /&gt;
* How to Create Event Handlers in LiveView&lt;br /&gt;
* How to Create a Dynamic Route from Scratch.&lt;br /&gt;
* How to Use Elixirs Template language&lt;br /&gt;
* How to Work with Modal&lt;br /&gt;
* How to Use CSS From Scratch (Without bundler)&lt;br /&gt;
* How to use JS hooks&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
______________________&lt;br /&gt;
https://studioindie.co/blog/heex-guide/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
get &amp;quot;/&amp;quot;, PageController, :some-atom    #This is the route. some-atom is the controller name&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  def some-atom(conn, _params) do                 # controller name&lt;br /&gt;
    # The home page is often custom made,&lt;br /&gt;
    # so skip the default app layout.&lt;br /&gt;
    render(conn, :some-atom, layout: false)      # :some-atom is template name&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Controllers page_html.ex contains &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageHTML do&lt;br /&gt;
  use AppWeb, :html&lt;br /&gt;
&lt;br /&gt;
  embed_templates &amp;quot;page_html/*&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''page_html''' is the name of the folder in '''Controllers/page_html'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Controllers/page_html/some-atom.html.heex  (this is the template) &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__________________________________________&lt;br /&gt;
Set all association with preload:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  def list_groups do&lt;br /&gt;
    Repo.all(Group)&lt;br /&gt;
     |&amp;gt; Repo.preload([:testbeds])&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Insert Child into Parent ===&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
App.get_group!(2) # arg is id&lt;br /&gt;
|&amp;gt; Ecto.build_assoc(:testbeds)&lt;br /&gt;
|&amp;gt; Repo.insert()&lt;br /&gt;
&lt;br /&gt;
Or&lt;br /&gt;
&lt;br /&gt;
group = App.get_group!(2) # arg is id&lt;br /&gt;
&lt;br /&gt;
testbeds = Ecto.build_assoc(group, :testbeds)&lt;br /&gt;
&lt;br /&gt;
App.Group.create_group(testbeds)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
group = App.Groups.get_group!(1)&lt;br /&gt;
thing = Ecto.build_assoc(group, :testbeds, name: &amp;quot;DUMB&amp;quot;)&lt;br /&gt;
alias App.{Repo}&lt;br /&gt;
Repo.insert(thing)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
avatar = %Avatar{nick_name: &amp;quot;Elixir&amp;quot;, pic_url: &amp;quot;http://elixir-lang.org/images/logo.png&amp;quot;}&lt;br /&gt;
user = %User{name: &amp;quot;John Doe&amp;quot;, email: &amp;quot;john.doe@example.com&amp;quot;, avatar: avatar}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://www.reddit.com/r/elixir/comments/oh318k/is_there_a_way_to_avoid_ectoassociationnotloaded/h4mmcfi/?utm_source=share&amp;amp;utm_medium=web3x&amp;amp;utm_name=web3xcss&amp;amp;utm_term=1&amp;amp;utm_content=share_button&lt;br /&gt;
&lt;br /&gt;
# Create Group Table&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
mix phx.gen.html Groups Group groups name:string  &lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Set the resources / &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
mix ecto.migrate&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For testbeds create a migration file and add this field:   group_id:references:groups&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
def change do&lt;br /&gt;
    alter table(:testbeds) do    # customize to your code&lt;br /&gt;
      add :group_id, references(:groups)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Update Groups Schema (Don't forget alias / has_many)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule App.Groups.Group do&lt;br /&gt;
	use Ecto.Schema&lt;br /&gt;
	import Ecto.Changeset&lt;br /&gt;
	alias App.Testbeds.Testbed   # Alias!&lt;br /&gt;
&lt;br /&gt;
	schema &amp;quot;posts&amp;quot; do&lt;br /&gt;
		field :body, :string&lt;br /&gt;
		field :title, :string&lt;br /&gt;
		has_many :testbeds, Testbed    # Has many&lt;br /&gt;
&lt;br /&gt;
		timestamps()&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	@doc false&lt;br /&gt;
	def changeset(post, attrs) do&lt;br /&gt;
		post&lt;br /&gt;
		|&amp;gt; cast(attrs, [:title, :body])&lt;br /&gt;
		|&amp;gt; validate_required([:title, :body])&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
TESTBEDS Schema&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule App.Testbeds.Testbed do&lt;br /&gt;
  use Ecto.Schema&lt;br /&gt;
  import Ecto.Changeset&lt;br /&gt;
  alias App.Groups.Group      # Alias&lt;br /&gt;
  schema &amp;quot;testbeds&amp;quot; do&lt;br /&gt;
    field :name, :string&lt;br /&gt;
    belongs_to :group, Group    # Belongs to&lt;br /&gt;
    timestamps()&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  @doc false&lt;br /&gt;
  def changeset(testbed, attrs) do&lt;br /&gt;
    testbed&lt;br /&gt;
    |&amp;gt; cast(attrs, [:name])&lt;br /&gt;
    |&amp;gt; validate_required([:name])&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
_____________________________________&lt;br /&gt;
Side notes.&lt;br /&gt;
&lt;br /&gt;
defmodule App.Repo.Migrations.CreateTestbeds do&lt;br /&gt;
  use Ecto.Migration&lt;br /&gt;
&lt;br /&gt;
  def change do&lt;br /&gt;
    create table(:testbeds) do&lt;br /&gt;
      add :name, :string&lt;br /&gt;
      add :group_id, references(:groups, on_delete: :nothing)&lt;br /&gt;
&lt;br /&gt;
      timestamps()&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    create index(:testbeds, [:group_id])&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
________________________________&lt;br /&gt;
&lt;br /&gt;
mix phx.gen.context Comments Comment comments name:string content:text post_id:references:posts&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
mix phx.gen.html Testbeds Testbed testbeds name:string  group_id:references:groups&lt;br /&gt;
&lt;br /&gt;
https://graffino.com/web-development/first-steps-in-elixir-and-phoenix-create-a-blog-prototype&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://blog.logrocket.com/getting-started-ecto-phoenix/&lt;br /&gt;
&lt;br /&gt;
https://serokell.io/blog/ecto-guide-for-beginners&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
mix phx.gen.html Testbeds Testbed testbeds name:string&lt;br /&gt;
&lt;br /&gt;
mix phx.gen.html Groups Group groups name:string&lt;br /&gt;
&lt;br /&gt;
Create migration for &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
mix ecto.gen.migration add_testbed_group_reference&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Migration:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  def change do&lt;br /&gt;
    alter table(:testbeds) do    # customize to your code&lt;br /&gt;
      add :group_id, references(:groups)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Manually Change:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule App.Group do&lt;br /&gt;
  use Ecto.Schema&lt;br /&gt;
&lt;br /&gt;
  schema &amp;quot;groups&amp;quot; do&lt;br /&gt;
    field :title, :string&lt;br /&gt;
    field :tagline, :string&lt;br /&gt;
    has_many :testbeds, App.Testbed&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
testbeds&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule App.Repo.Migrations.AddTextbedGroups do&lt;br /&gt;
  use Ecto.Migration&lt;br /&gt;
&lt;br /&gt;
  def change do&lt;br /&gt;
    create table(:testbeds) do&lt;br /&gt;
      add :name, :string&lt;br /&gt;
      add :group_id, references(:groups)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
# lib/app/testbeds.ex&lt;br /&gt;
&lt;br /&gt;
defmodule App.Testbed do&lt;br /&gt;
  use Ecto.Schema&lt;br /&gt;
&lt;br /&gt;
  schema &amp;quot;testbedss&amp;quot; do&lt;br /&gt;
    field :name, :string&lt;br /&gt;
    belongs_to :group, App.Group&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_____________________&lt;br /&gt;
&lt;br /&gt;
%App.TestBeds.TestBed{&lt;br /&gt;
  __meta__: #Ecto.Schema.Metadata&amp;lt;:loaded, &amp;quot;testbeds&amp;quot;&amp;gt;,&lt;br /&gt;
  id: 1,&lt;br /&gt;
  developer: &amp;quot;None&amp;quot;,&lt;br /&gt;
  name: &amp;quot;sdfsd&amp;quot;,&lt;br /&gt;
  owner: &amp;quot;sdfsddf&amp;quot;,&lt;br /&gt;
  note: &amp;quot;sdsfsddf&amp;quot;,&lt;br /&gt;
  status: &amp;quot;Available&amp;quot;,&lt;br /&gt;
  url: &amp;quot;sdf&amp;quot;,&lt;br /&gt;
  version: &amp;quot;ddf&amp;quot;,&lt;br /&gt;
  manager: &amp;quot;sf&amp;quot;,&lt;br /&gt;
  inserted_at: ~N[2023-08-21 13:45:39],&lt;br /&gt;
  updated_at: ~N[2023-08-21 13:45:44]&lt;br /&gt;
}&lt;br /&gt;
________________________________________________________________---&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.SendLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  &lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    {:ok, socket}&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  def handle_event(&amp;quot;send&amp;quot;, %{&amp;quot;text&amp;quot; =&amp;gt; text}, socket) do&lt;br /&gt;
&lt;br /&gt;
    AppWeb.Endpoint.broadcast(topic, &amp;quot;message&amp;quot;, text)&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  defp topic do&lt;br /&gt;
    &amp;quot;chat&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def render(assigns)do   &lt;br /&gt;
   ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
  &amp;lt;h1&amp;gt;Send Message&amp;lt;/h1&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;form phx-submit=&amp;quot;send&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;text&amp;quot; /&amp;gt;&lt;br /&gt;
    &amp;lt;button type=&amp;quot;submit&amp;quot;&amp;gt;Send&amp;lt;/button&amp;gt;&lt;br /&gt;
  &amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
______________________________________________________________&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.ReceiveLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  &lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    if connected?(socket) do&lt;br /&gt;
      AppWeb.Endpoint.subscribe(topic)&lt;br /&gt;
    end&lt;br /&gt;
    {:ok, assign(socket, messages: &amp;quot;&amp;quot;)}&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def handle_info(%{event: &amp;quot;message&amp;quot;, payload: message}, socket) do&lt;br /&gt;
    IO.inspect message&lt;br /&gt;
    {:noreply, assign(socket, messages: message)}&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  defp topic do&lt;br /&gt;
    &amp;quot;chat&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns)do   &lt;br /&gt;
   ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
  &amp;lt;h1&amp;gt;ChatLive&amp;lt;/h1&amp;gt;&lt;br /&gt;
  &amp;lt;%= @messages %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
______________________________________________________________&lt;br /&gt;
When you hover over a list of items this hook finds items with the same name and sets the opacity of all others to 0. You see all the items similar to the one you are hovering over.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
TestbedVersionHover: {&lt;br /&gt;
			// https://jsfiddle.net/IrvinDominin/7K2Z3/&lt;br /&gt;
            mounted() {&lt;br /&gt;
&lt;br /&gt;
                let rows = document.getElementsByClassName(&amp;quot;testbed-version&amp;quot;)&lt;br /&gt;
                // this.ele = element&lt;br /&gt;
				// rows = this.ele;&lt;br /&gt;
                &lt;br /&gt;
				for (var i = 0; i &amp;lt; rows.length; i++) {&lt;br /&gt;
					rows[i].onmouseenter = function (event) {&lt;br /&gt;
						for (var j = 0; j &amp;lt; rows.length; j++) {&lt;br /&gt;
							let preversion = this.textContent;&lt;br /&gt;
							let version = preversion.slice(0,5)&lt;br /&gt;
							let compareVersion = rows[j].textContent.slice(0,5)&lt;br /&gt;
							if (compareVersion === version) continue&lt;br /&gt;
							rows[j].className += &amp;quot; other&amp;quot;;&lt;br /&gt;
						}&lt;br /&gt;
					};&lt;br /&gt;
				&lt;br /&gt;
					rows[i].onmouseleave = function (event) {&lt;br /&gt;
						var hovers = document.getElementsByClassName('other');&lt;br /&gt;
						var len = hovers.length;&lt;br /&gt;
						for (var j = 0; j &amp;lt; len; j++) {&lt;br /&gt;
							hovers[0].className = hovers[0].className.replace(/\sother(\s|$)/, '');&lt;br /&gt;
						}&lt;br /&gt;
					};&lt;br /&gt;
				}&lt;br /&gt;
&lt;br /&gt;
                // this.ele.addEventListener(&amp;quot;click&amp;quot;, (e) =&amp;gt; {&lt;br /&gt;
                //     console.log(e.target)&lt;br /&gt;
                    &lt;br /&gt;
                // });&lt;br /&gt;
&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* How to Create Database Seed Data.&lt;br /&gt;
* How to structure code so controller code is in one file and HTML Heex is in another&lt;br /&gt;
* How to Use Generators in a Real World Project&lt;br /&gt;
* How to Work with Database Data via Basic Commands and Custom Change sets.&lt;br /&gt;
* How to Render Database Data to LiveView (via Context Commands).&lt;br /&gt;
* How to Create a Chat using PubSub.&lt;br /&gt;
* How to Create Event Handlers in LiveView&lt;br /&gt;
* How to Create a Dynamic Route from Scratch.&lt;br /&gt;
* How to Use Elixirs Template language&lt;br /&gt;
* How to Work with Modal&lt;br /&gt;
* How to Use CSS From Scratch (Without bundler)&lt;br /&gt;
* How to use JS hooks&lt;br /&gt;
* Dissect Table Component and Update it to Order List in Reverse.&lt;br /&gt;
&lt;br /&gt;
Selenium&lt;br /&gt;
https://www.builder.io/blog/debug-nodejs&lt;br /&gt;
&lt;br /&gt;
https://marketplace.visualstudio.com/items?itemName=ms-vscode.live-server#running-the-extension&lt;br /&gt;
&lt;br /&gt;
This was added recently (see microsoft/vscode#109276).&lt;br /&gt;
    1. Open the palette (Ctrl + Shift + P)&lt;br /&gt;
    2. Select &amp;quot;Simple Browser: Preview&amp;quot;&lt;br /&gt;
    3. Enter web address&lt;br /&gt;
&lt;br /&gt;
_______________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
const {By, Key, Builder} = require(&amp;quot;selenium-webdriver&amp;quot;);&lt;br /&gt;
const assert = require(&amp;quot;assert&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
require(&amp;quot;chromedriver&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
async function test_case(){&lt;br /&gt;
  let driver = await new Builder().forBrowser(&amp;quot;chrome&amp;quot;).build();&lt;br /&gt;
  await driver.get(&amp;quot;sie&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  await driver.findElement(By.name('password')).clear();&lt;br /&gt;
  await driver.findElement(By.name('identification')).clear();&lt;br /&gt;
  await driver.findElement(By.name('identification')).sendKeys(&amp;quot;bill&amp;quot;);&lt;br /&gt;
  await driver.findElement(By.name('password')).sendKeys(&amp;quot;password&amp;quot;, Key.RETURN);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 setTimeout(()=&amp;gt;{&lt;br /&gt;
   driver.findElement(By.className(&amp;quot;req_lan_license&amp;quot;)).click();&lt;br /&gt;
 },5000)&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageLive do &lt;br /&gt;
&lt;br /&gt;
  use AppWeb, :live_view  &lt;br /&gt;
  alias App.Testbeds &lt;br /&gt;
  def mount(_params, _session, socket)do   &lt;br /&gt;
     {:ok, assign(socket, testbeds: Testbeds.list_testbeds())}   &lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
    def button_event(&amp;quot;invoke_editing&amp;quot;) do&lt;br /&gt;
    %JS{}&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;active&amp;quot;, to: &amp;quot;#editing_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#editing_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#preview_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;active&amp;quot;, to: &amp;quot;#preview_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;active&amp;quot;, to: &amp;quot;#preview&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#preview&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#editing&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;active&amp;quot;, to: &amp;quot;#editing&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def button_event(&amp;quot;invoke_preview&amp;quot;) do&lt;br /&gt;
    %JS{}&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;active&amp;quot;, to: &amp;quot;#preview_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#preview_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#editing_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;active&amp;quot;, to: &amp;quot;#editing_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;active&amp;quot;, to: &amp;quot;#editing&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#editing&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#preview&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;active&amp;quot;, to: &amp;quot;#preview&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;send&amp;quot;, params, socket) do&lt;br /&gt;
    hide_modal(&amp;quot;notes-modal-0&amp;quot;)&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do  &lt;br /&gt;
     ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
		&amp;lt;.modal id={&amp;quot;notes-modal-#{testbed.id}&amp;quot;}&amp;gt;&lt;br /&gt;
		    &amp;lt;.button phx-click={button_event(&amp;quot;invoke_editing&amp;quot;)} id=&amp;quot;editing_button&amp;quot; class=&amp;quot;hidden&amp;quot;&amp;gt;&lt;br /&gt;
		      Preview&lt;br /&gt;
		    &amp;lt;/.button&amp;gt;&lt;br /&gt;
		    &amp;lt;.button phx-click={button_event(&amp;quot;invoke_preview&amp;quot;)} id=&amp;quot;preview_button&amp;quot;&amp;gt;&lt;br /&gt;
		      Edit Me&lt;br /&gt;
		    &amp;lt;/.button&amp;gt;&lt;br /&gt;
		    &amp;lt;div id=&amp;quot;editing&amp;quot;&amp;gt; PREVIEWING THE WORK&amp;lt;/div&amp;gt;&lt;br /&gt;
		    &amp;lt;form phx-submit = &amp;quot;send&amp;quot;   id=&amp;quot;preview&amp;quot; class=&amp;quot;hidden&amp;quot;&amp;gt;&lt;br /&gt;
		      &amp;lt;textarea value = {testbed.note}&amp;gt;&amp;lt;/textarea&amp;gt;&lt;br /&gt;
		      &amp;lt;.button type=&amp;quot;submit&amp;quot; phx-click={hide_modal(&amp;quot;notes-modal-#{testbed.id}&amp;quot;)}&amp;gt;SAVE WORK&amp;lt;/.button&amp;gt;&lt;br /&gt;
		    &amp;lt;/form&amp;gt;&lt;br /&gt;
		&amp;lt;/.modal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;%= if testbed.note do %&amp;gt;&lt;br /&gt;
      &amp;lt;div phx-click={show_modal(&amp;quot;notes-modal-#{testbed.id}&amp;quot;)}&amp;gt;READ ME  ...&amp;lt;%= testbed.note %&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
	   &lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
       &lt;br /&gt;
      &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
import {HfInference} from &amp;quot;@huggingface/inference&amp;quot;;&lt;br /&gt;
import dotenv from &amp;quot;dotenv&amp;quot;;&lt;br /&gt;
dotenv.config()&lt;br /&gt;
&lt;br /&gt;
const HF_ACCESS_TOKEN = process.env.HF_ACCESS_TOKEN&lt;br /&gt;
&lt;br /&gt;
const hf = new HfInference(HF_ACCESS_TOKEN);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*______Uncomment for this example______________________&lt;br /&gt;
&lt;br /&gt;
const model = &amp;quot;nlpconnect/vit-gpt2-image-captioning&amp;quot;;&lt;br /&gt;
const imageURL = &amp;quot;https://i.imgur.com/lTvb7Et.png&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
const response = await fetch(imageURL);&lt;br /&gt;
const imageBlob = await response.blob();&lt;br /&gt;
&lt;br /&gt;
const result  = await hf.imageToText({&lt;br /&gt;
	data: imageBlob,&lt;br /&gt;
	model: model,&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
_______________________________________________________*/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*________Another example ___________________*/&lt;br /&gt;
&lt;br /&gt;
const result = await hf.summarization({&lt;br /&gt;
	model: 'facebook/bart-large-cnn',&lt;br /&gt;
	inputs: &amp;quot;The role of a dumb man is to get smarter oogy bookie boo&amp;quot;,&lt;br /&gt;
	parameters:{&lt;br /&gt;
		max_length: 100&lt;br /&gt;
	}&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
console.log(result);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
________________________________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://fly.io/phoenix-files/sdeb-toggling-element/&lt;br /&gt;
https://www.youtube.com/watch?v=vBgZvQapqhs&lt;br /&gt;
&lt;br /&gt;
https://blog.testdouble.com/posts/2022-11-28-how-to-use-javascript-with-phoenix-liveview/&lt;br /&gt;
&lt;br /&gt;
https://hexdocs.pm/phoenix_live_view/0.19.3/Phoenix.Component.html&lt;br /&gt;
_______________________________________&lt;br /&gt;
https://www.smashingmagazine.com/2011/10/quick-look-math-animations-javascript/&lt;br /&gt;
* Depth first traversal&lt;br /&gt;
* Breadth first traversal&lt;br /&gt;
&lt;br /&gt;
https://dev.to/codesphere/10-algorithms-every-developer-should-learn-3lnm&lt;br /&gt;
&lt;br /&gt;
https://www.youtube.com/watch?v=fPz40W9mfCg&lt;br /&gt;
&lt;br /&gt;
__________________________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.GroupLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  alias App.TestBeds&lt;br /&gt;
  alias App.Groups&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    {:ok, assign(socket, testbeds: TestBeds.list_testbeds(), groups: Groups.list_groups())}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;select-group&amp;quot;, params, socket)  do  &lt;br /&gt;
         &lt;br /&gt;
       IO.inspect params&lt;br /&gt;
       {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div class=&amp;quot;grid grid-columns-2 grid-flow-col gap-4&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;column-1&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;%= testbed.name %&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;column-2&amp;quot;&amp;gt;    &lt;br /&gt;
            &amp;lt;form phx-change=&amp;quot;select-group&amp;quot;  &amp;gt;&lt;br /&gt;
               &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;testbed_id&amp;quot; value={testbed.id}/&amp;gt;&lt;br /&gt;
               &amp;lt;select id=&amp;quot;group-selection&amp;quot;  name=&amp;quot;group-id&amp;quot; &amp;gt;&lt;br /&gt;
                &amp;lt;%= for group &amp;lt;- @groups do %&amp;gt;&lt;br /&gt;
                  &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}  &amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
               &amp;lt;/select&amp;gt;&lt;br /&gt;
            &amp;lt;/form&amp;gt;&lt;br /&gt;
         &amp;lt;/div&amp;gt;&lt;br /&gt;
       &amp;lt;% end %&amp;gt;&lt;br /&gt;
   &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
____________________________&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.GroupLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  alias App.TestBeds&lt;br /&gt;
  alias App.Groups&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
&lt;br /&gt;
    {:ok, assign(socket, testbeds: TestBeds.list_testbeds(), groups: Groups.list_groups(), messages: [])}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;select-group&amp;quot;, params, socket)  do  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
      group = App.Groups.get_group!(params[&amp;quot;group-id&amp;quot;])&lt;br /&gt;
       # IO.inspect group&lt;br /&gt;
       testbed = App.TestBeds.get_test_bed!(params[&amp;quot;testbed_id&amp;quot;])&lt;br /&gt;
     &lt;br /&gt;
       App.TestBeds.update_test_bed(testbed, %{group_id: group.id})&lt;br /&gt;
         &lt;br /&gt;
    &lt;br /&gt;
       {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def updated_groups(testbed_id)  do  &lt;br /&gt;
       groups = App.Groups.list_groups&lt;br /&gt;
       tail = Enum.filter(groups, fn(item)-&amp;gt; item.id !== testbed_id end)&lt;br /&gt;
       head = Enum.filter(groups, fn(item)-&amp;gt; item.id == testbed_id end)&lt;br /&gt;
              |&amp;gt;Enum.at(0)&lt;br /&gt;
     [head | tail]&lt;br /&gt;
         &lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
 # def handle_event(&amp;quot;groups&amp;quot;, params, socket)do  &lt;br /&gt;
 #       selected_testbed = %{name: &amp;quot;my testbed name&amp;quot;, id: 3}&lt;br /&gt;
 #       groups = App.Groups.list_groups&lt;br /&gt;
 #       tail = Enum.filter(groups, fn(item)-&amp;gt; item.id !== selected_testbed.id end)&lt;br /&gt;
 #       head = Enum.filter(groups, fn(item)-&amp;gt; item.id == selected_testbed.id end)&lt;br /&gt;
 #              |&amp;gt;Enum.at(0)&lt;br /&gt;
         &lt;br /&gt;
 &lt;br /&gt;
 #       # result = Enum.filter([1, 2, 3], fn x -&amp;gt; x.id !== 1 end)&lt;br /&gt;
 #      IO.inspect [head | tail]&lt;br /&gt;
         &lt;br /&gt;
 #      #&lt;br /&gt;
 #      {:noreply, socket, assigns.message:}&lt;br /&gt;
 #  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    &lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
       &amp;lt;%!-- &amp;lt;div phx-click = &amp;quot;groups&amp;quot;&amp;gt;CLICK ME&amp;lt;/div&amp;gt; --%&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;grid grid-cols-4 gap-4 p-8 rounded shadow bg-white&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;h2&amp;gt; Name&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;%= testbed.name %&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;h2&amp;gt; Group&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;form phx-change=&amp;quot;select-group&amp;quot; name=&amp;quot;testbed_id&amp;quot;  &amp;gt;&lt;br /&gt;
               &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;testbed_id&amp;quot; value={testbed.id}/&amp;gt;&lt;br /&gt;
               &amp;lt;select id=&amp;quot;group-selection&amp;quot;  name=&amp;quot;group-id&amp;quot; class=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
                &amp;lt;%= for group &amp;lt;- updated_groups(testbed.id) do %&amp;gt;&lt;br /&gt;
                  &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}  &amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
                  &amp;lt;!-- Write code to reorder with testbed.group_id matching group_id --&amp;gt;&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
               &amp;lt;/select&amp;gt;&lt;br /&gt;
            &amp;lt;/form&amp;gt;&lt;br /&gt;
          &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
       &amp;lt;% end %&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_____________________________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
   use AppWeb, :live_view  &lt;br /&gt;
     alias App.Testbeds&lt;br /&gt;
  alias App.Groups&lt;br /&gt;
   def mount(_params, _session, socket)  do&lt;br /&gt;
	     {:ok, assign(socket, testbeds: Testbeds.list_testbeds(), groups: Groups.list_groups())}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
   def handle_event(&amp;quot;select-group&amp;quot;, params, socket)  do  &lt;br /&gt;
       group = App.Groups.get_group!(params[&amp;quot;group-id&amp;quot;])&lt;br /&gt;
       testbed = App.Testbeds.get_testbed!(params[&amp;quot;testbed_id&amp;quot;])&lt;br /&gt;
       result = App.Testbeds.update_testbed(testbed, %{group_id: group.id})&lt;br /&gt;
       IO.inspect result&lt;br /&gt;
      &lt;br /&gt;
       {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
    def updated_groups(testbed_id)  do  &lt;br /&gt;
       testbed = App.Testbeds.get_testbed!(testbed_id)&lt;br /&gt;
       groups = App.Groups.list_groups&lt;br /&gt;
       tail = Enum.filter(groups, fn(item)-&amp;gt; item.id !== testbed.group_id end)&lt;br /&gt;
       head = Enum.filter(groups, fn(item)-&amp;gt; item.id == testbed.group_id end)&lt;br /&gt;
              |&amp;gt;Enum.at(0)&lt;br /&gt;
 &lt;br /&gt;
       [head | tail]&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    &lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;grid grid-cols-4 gap-4 p-8 rounded shadow bg-white&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;h2&amp;gt; Name&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;%= testbed.name %&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;h2&amp;gt; Group&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;form phx-change=&amp;quot;select-group&amp;quot; name=&amp;quot;testbed_id&amp;quot;  &amp;gt;&lt;br /&gt;
               &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;testbed_id&amp;quot; value={testbed.id}/&amp;gt;&lt;br /&gt;
               &amp;lt;select id=&amp;quot;group-selection&amp;quot;  name=&amp;quot;group-id&amp;quot; class=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
                &amp;lt;%= for group &amp;lt;- updated_groups(testbed.id) do %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
                  &amp;lt;%!-- &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}&amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt; --%&amp;gt;&lt;br /&gt;
                  &amp;lt;!-- Write code to reorder with testbed.group_id matching group_id --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
                  &amp;lt;%= if group !== nil do %&amp;gt;&lt;br /&gt;
                      &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}&amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
       &lt;br /&gt;
                  &amp;lt;% end %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
               &amp;lt;/select&amp;gt;&lt;br /&gt;
            &amp;lt;/form&amp;gt;&lt;br /&gt;
          &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
       &amp;lt;% end %&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  has_many :testbeds, TestBed, on_delete: :restrict   # Has many&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://elixirforum.com/t/ecto-has-many-on-delete-protect/49550&lt;br /&gt;
&lt;br /&gt;
https://hexdocs.pm/ecto/Ecto.Changeset.html#unique_constraint/3&lt;br /&gt;
&lt;br /&gt;
____________________________________________________________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== How to Create a Mix Project and Use It in Another Mix Project ==&lt;br /&gt;
&lt;br /&gt;
To create and use a **Mix project** inside another **Mix project** in Elixir, follow the steps below:&lt;br /&gt;
&lt;br /&gt;
=== 1. Create a New Mix Project ===&lt;br /&gt;
&lt;br /&gt;
First, you need to create a new Mix project. Let's call this project `library_project`. Run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mix new library_project --module LibraryProject&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will create a new Elixir Mix project named `library_project`. The `--module` flag specifies the name of the module that will be created (in this case `LibraryProject`).&lt;br /&gt;
&lt;br /&gt;
The directory structure of `library_project` will look like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
library_project/&lt;br /&gt;
  |_ lib/&lt;br /&gt;
      |_ library_project.ex&lt;br /&gt;
  |_ mix.exs&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can then add some basic functionality inside the `library_project/lib/library_project.ex` file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule LibraryProject do&lt;br /&gt;
  def hello do&lt;br /&gt;
    IO.puts &amp;quot;Hello from LibraryProject!&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now, `library_project` is ready to be used by another Mix project.&lt;br /&gt;
&lt;br /&gt;
=== 2. Create a Second Mix Project ===&lt;br /&gt;
&lt;br /&gt;
Next, create the second Mix project where you want to use `library_project`. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mix new app_project --module AppProject&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will create another Elixir project called `app_project`.&lt;br /&gt;
&lt;br /&gt;
The directory structure for this project will look like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
app_project/&lt;br /&gt;
  |_ lib/&lt;br /&gt;
      |_ app_project.ex&lt;br /&gt;
  |_ mix.exs&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 3. Add `library_project` as a Dependency in `app_project` ===&lt;br /&gt;
&lt;br /&gt;
Now, you want to make `library_project` available in `app_project`. There are two main ways to do this:&lt;br /&gt;
&lt;br /&gt;
==== Option 1: Local Dependency (via `path`) ====&lt;br /&gt;
&lt;br /&gt;
If `library_project` is a local project (i.e., it's stored in a different directory), you can add it to the `mix.exs` of `app_project` as a local dependency by specifying the path to `library_project`.&lt;br /&gt;
&lt;br /&gt;
Edit the `mix.exs` of `app_project`:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule AppProject.MixProject do&lt;br /&gt;
  use Mix.Project&lt;br /&gt;
&lt;br /&gt;
  def project do&lt;br /&gt;
    [&lt;br /&gt;
      app: :app_project,&lt;br /&gt;
      version: &amp;quot;0.1.0&amp;quot;,&lt;br /&gt;
      elixir: &amp;quot;~&amp;gt; 1.14&amp;quot;,&lt;br /&gt;
      start_permanent: Mix.env() == :prod,&lt;br /&gt;
      deps: deps()&lt;br /&gt;
    ]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  defp deps do&lt;br /&gt;
    [&lt;br /&gt;
      {:library_project, path: &amp;quot;../library_project&amp;quot;}  # Add the local dependency&lt;br /&gt;
    ]&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here, `{:library_project, path: &amp;quot;../library_project&amp;quot;}` tells Mix to use the local `library_project` located in the `../library_project` directory (relative to `app_project`).&lt;br /&gt;
&lt;br /&gt;
After updating the `mix.exs`, run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd app_project&lt;br /&gt;
mix deps.get&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will fetch the dependency and compile `library_project`.&lt;br /&gt;
&lt;br /&gt;
==== Option 2: Publish and Fetch as a Hex Package ====&lt;br /&gt;
&lt;br /&gt;
If you want to use `library_project` as a package in another project (for example, by publishing it to **Hex.pm**, Elixir’s package manager), you need to publish it to Hex and then add it as a dependency.&lt;br /&gt;
&lt;br /&gt;
1. Publish `library_project` to Hex (if it's public or for your private use).&lt;br /&gt;
2. Add `library_project` to your `app_project`’s `mix.exs` dependencies:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defp deps do&lt;br /&gt;
  [&lt;br /&gt;
    {:library_project, &amp;quot;~&amp;gt; 0.1.0&amp;quot;}  # Specify the published version from Hex&lt;br /&gt;
  ]&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Run `mix deps.get` to fetch the package from Hex.&lt;br /&gt;
&lt;br /&gt;
=== 4. Use `library_project` in `app_project` ===&lt;br /&gt;
&lt;br /&gt;
Now, you can use the functionality from `library_project` inside your `app_project`. For example, in `app_project/lib/app_project.ex`, you can call the function from `library_project`:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule AppProject do&lt;br /&gt;
  def start do&lt;br /&gt;
    IO.puts &amp;quot;Starting app_project!&amp;quot;&lt;br /&gt;
    LibraryProject.hello()  # Call the function from the library_project&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 5. Run the App ===&lt;br /&gt;
&lt;br /&gt;
Finally, you can run your `app_project`:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd app_project&lt;br /&gt;
mix run -e &amp;quot;AppProject.start()&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will print:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Starting app_project!&lt;br /&gt;
Hello from LibraryProject!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Recap of the Process ==&lt;br /&gt;
1. **Create the `library_project`**: Use `mix new` to generate a library project.&lt;br /&gt;
2. **Create the `app_project`**: Create the second project where you will use the library.&lt;br /&gt;
3. **Add the `library_project` as a dependency**:&lt;br /&gt;
   - Use the `path` option to point to the local project or publish it to Hex for public access.&lt;br /&gt;
4. **Use the `library_project` in the `app_project`**: Call functions or use modules from the library inside the second project.&lt;br /&gt;
5. **Run the app**: Use `mix run` to execute the project.&lt;br /&gt;
&lt;br /&gt;
This way, you can reuse code from one Mix project in another by adding it as a dependency.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==z==&lt;br /&gt;
Overloaded functions are extremely common in Elixir applications. They are&lt;br /&gt;
regularly used for recursive functions and for changing behavior based on&lt;br /&gt;
configuration.&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>http://elixirblocks.com/index.php?title=User:Admin&amp;diff=1880</id>
		<title>User:Admin</title>
		<link rel="alternate" type="text/html" href="http://elixirblocks.com/index.php?title=User:Admin&amp;diff=1880"/>
		<updated>2025-02-20T23:21:54Z</updated>

		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source&amp;gt;&lt;br /&gt;
from(a in Article,&lt;br /&gt;
  order_by: [desc: a.inserted_at],  # Assuming 'inserted_at' is the timestamp for when the article was created or updated&lt;br /&gt;
  limit: 8&lt;br /&gt;
)&lt;br /&gt;
|&amp;gt; Repo.all()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.Landing do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  alias App.Testbeds&lt;br /&gt;
  alias App.Testbeds.Testbed&lt;br /&gt;
  alias App.Repo  # Ensure to alias Repo&lt;br /&gt;
  import Ecto.Query  # Import Ecto.Query to work with queries&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    # Default to ordering by name&lt;br /&gt;
    testbeds = Repo.all(from(t in Testbed, order_by: t.name))&lt;br /&gt;
&lt;br /&gt;
    # Assign the testbeds to the socket for rendering&lt;br /&gt;
    {:ok, assign(socket, testbeds: testbeds, sort: :name)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    &amp;lt;h1&amp;gt;Hello World! YAY&amp;lt;/h1&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;div&amp;gt;&lt;br /&gt;
      &amp;lt;!-- Buttons to toggle sorting --&amp;gt;&lt;br /&gt;
      &amp;lt;button phx-click=&amp;quot;sort_by_name&amp;quot;&amp;gt;Sort by Name&amp;lt;/button&amp;gt;&lt;br /&gt;
      &amp;lt;button phx-click=&amp;quot;sort_by_updated_at&amp;quot;&amp;gt;Sort by Updated By&amp;lt;/button&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;ul&amp;gt;&lt;br /&gt;
      &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
        &amp;lt;li&amp;gt;&amp;lt;%= testbed.name %&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;% end %&amp;gt;&lt;br /&gt;
    &amp;lt;/ul&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;sort_by_name&amp;quot;, _params, socket) do&lt;br /&gt;
    testbeds = Repo.all(from(t in Testbed, order_by: t.name))&lt;br /&gt;
    {:noreply, assign(socket, testbeds: testbeds, sort: :name)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;sort_by_updated_at&amp;quot;, _params, socket) do&lt;br /&gt;
    testbeds = Repo.all(from(t in Testbed, order_by: t.inserted_at))&lt;br /&gt;
    {:noreply, assign(socket, testbeds: testbeds, sort: :inserted_at)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
_______________________________________________________&lt;br /&gt;
&lt;br /&gt;
* Create a form with a post request. &lt;br /&gt;
* Create the route needed for that request&lt;br /&gt;
* Create the controller needed for that route&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Form==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;.form action={~p&amp;quot;/todos&amp;quot;} method=&amp;quot;post&amp;quot; class=&amp;quot;mt-10 space-y-8&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    &amp;lt;label for=&amp;quot;contact_name&amp;quot; class=&amp;quot;block text-sm font-semibold leading-6 text-zinc-800&amp;quot;&amp;gt;&lt;br /&gt;
      Name&lt;br /&gt;
    &amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;input&lt;br /&gt;
      id=&amp;quot;todo&amp;quot;&lt;br /&gt;
      type=&amp;quot;text&amp;quot;&lt;br /&gt;
      name=&amp;quot;todo&amp;quot;&lt;br /&gt;
      class=&amp;quot;mt-2 block w-full rounded-lg text-zinc-900 focus:ring-0 sm:text-sm sm:leading-6 border-zinc-300 focus:border-zinc-400&amp;quot;&lt;br /&gt;
    /&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;button&lt;br /&gt;
    type=&amp;quot;submit&amp;quot;&lt;br /&gt;
    class=&amp;quot;rounded-lg bg-zinc-900 hover:bg-zinc-700 py-2 px-3 text-sm font-semibold leading-6 text-white active:text-white/80&amp;quot;&lt;br /&gt;
  &amp;gt;&lt;br /&gt;
    Save Contact&lt;br /&gt;
  &amp;lt;/button&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/.form&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Controller==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# In your TodoController&lt;br /&gt;
defmodule AppWeb.TodoController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  # Action to handle the form submission (POST request)&lt;br /&gt;
  def create(conn, %{&amp;quot;todo&amp;quot; =&amp;gt; todo_name}) do&lt;br /&gt;
    # Here you can handle the form data (e.g., save it to the database)&lt;br /&gt;
    IO.puts(&amp;quot;Received Todo: #{todo_name}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    # For now, let's just redirect to the home page&lt;br /&gt;
    conn&lt;br /&gt;
    |&amp;gt; put_flash(:info, &amp;quot;Todo saved!&amp;quot;)&lt;br /&gt;
    |&amp;gt; redirect(to: &amp;quot;/&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
________________________________________________________&lt;br /&gt;
&lt;br /&gt;
# CRUD Forms&lt;br /&gt;
&lt;br /&gt;
To understand CRUD forms you will need to understand the following concepts. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Ecto Schema&lt;br /&gt;
* Ecto Context&lt;br /&gt;
* Form Basics&lt;br /&gt;
* form/1&lt;br /&gt;
* simple_form/1&lt;br /&gt;
* changesets&lt;br /&gt;
&lt;br /&gt;
We are not going to go in order. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The Context provides CRUD functions for the chosen data schema. Phoenix contexts define the interface through which other parts of the codebase can interact with the app layer.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_______________________&lt;br /&gt;
* Create routes&lt;br /&gt;
* create page with form (submit get request)&lt;br /&gt;
&lt;br /&gt;
(ecto schema, context, changesets)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_______________________________________________________&lt;br /&gt;
In that case, you really should switch it to prod mode. Instead of doing all that above with the &amp;quot;config/secret.exs&amp;quot; file, create the &amp;quot;.env&amp;quot; in the project root, then add DotenvParser.load_file(&amp;quot;.env&amp;quot;) to &amp;quot;config/runtime.exs&amp;quot; as the first line inside the if config_env() == :prod do. In the .env file, set the DATABASE_URL and SECRET_KEY_BASE. Then run it as MIX_ENV=prod mix phx.server.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def get_titles do&lt;br /&gt;
    urls = [&lt;br /&gt;
      &amp;quot;https://cointelegraph.com/rss&amp;quot;,&lt;br /&gt;
      &amp;quot;https://chaski.huffpost.com/us/auto/vertical/us-news&amp;quot;&lt;br /&gt;
      # Add more RSS feed URLs here&lt;br /&gt;
    ]&lt;br /&gt;
&lt;br /&gt;
    urls&lt;br /&gt;
    |&amp;gt; Enum.map(fn url -&amp;gt;&lt;br /&gt;
      with {:ok, feed} &amp;lt;- ElixirRss.fetch_and_parse(url) do&lt;br /&gt;
        Enum.map(feed.entries, &amp;amp; &amp;amp;1.title)&lt;br /&gt;
      else&lt;br /&gt;
        {:error, reason} -&amp;gt; {:error, reason}&lt;br /&gt;
      end&lt;br /&gt;
    end)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule App do&lt;br /&gt;
&lt;br /&gt;
  def get_titles() do&lt;br /&gt;
    data = [&lt;br /&gt;
      &amp;quot;https://cointelegraph.com/rss&amp;quot;,&lt;br /&gt;
      &amp;quot;https://chaski.huffpost.com/us/auto/vertical/us-news&amp;quot;&lt;br /&gt;
      # Add more RSS feed URLs here&lt;br /&gt;
    ]&lt;br /&gt;
&lt;br /&gt;
    data&lt;br /&gt;
    |&amp;gt; Enum.map(fn url -&amp;gt;&lt;br /&gt;
      case ElixirRss.fetch_and_parse(url) do&lt;br /&gt;
        {:ok, feed} -&amp;gt; feed.entries |&amp;gt; Enum.map(fn entry -&amp;gt; entry end)&lt;br /&gt;
        {:error, reason} -&amp;gt; {:error, reason}&lt;br /&gt;
      end&lt;br /&gt;
    end)&lt;br /&gt;
    |&amp;gt; Enum.map(fn entry_list -&amp;gt;&lt;br /&gt;
      entry_list&lt;br /&gt;
      |&amp;gt; Enum.map(fn entry -&amp;gt; entry.title end)&lt;br /&gt;
    end)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def hello do&lt;br /&gt;
    rss_feeds = [&lt;br /&gt;
      &amp;quot;https://cointelegraph.com/rss&amp;quot;,&lt;br /&gt;
      &amp;quot;https://chaski.huffpost.com/us/auto/vertical/us-news&amp;quot;&lt;br /&gt;
      # Add more RSS feed URLs here&lt;br /&gt;
    ]&lt;br /&gt;
&lt;br /&gt;
    rss_feeds&lt;br /&gt;
    |&amp;gt; Enum.map(fn url -&amp;gt;&lt;br /&gt;
      case ElixirRss.fetch_and_parse(url) do&lt;br /&gt;
        {:ok, feed} -&amp;gt; feed.entries |&amp;gt; Enum.map(fn entry -&amp;gt; entry end)&lt;br /&gt;
        {:error, reason} -&amp;gt; {:error, reason}&lt;br /&gt;
      end&lt;br /&gt;
    end)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    if connected?(socket) do&lt;br /&gt;
      Phoenix.PubSub.subscribe(App.PubSub, &amp;quot;message&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
    {:ok, assign(socket, message_item: &amp;quot;different&amp;quot;)}&lt;br /&gt;
  end&lt;br /&gt;
  def handle_info({:pubsub_transmission, text}, socket) do&lt;br /&gt;
    IO.inspect &amp;quot;pub sub working&amp;quot;&lt;br /&gt;
    {:noreply, assign(socket, message_item: text)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def loop(data) do&lt;br /&gt;
     IO.inspect data&lt;br /&gt;
     if data &amp;gt; 0 do&lt;br /&gt;
      IO.inspect &amp;quot;notify&amp;quot;&lt;br /&gt;
      # run code to compare files, loop. If different run pubsub code below&lt;br /&gt;
      :timer.sleep(2000)&lt;br /&gt;
      loop(data-1)&lt;br /&gt;
&lt;br /&gt;
     end&lt;br /&gt;
     if data &amp;lt;= 0 do&lt;br /&gt;
&lt;br /&gt;
      Phoenix.PubSub.broadcast(App.PubSub, &amp;quot;message&amp;quot;, {:pubsub_transmission, &amp;quot;data&amp;quot;})&lt;br /&gt;
      &amp;quot;done&amp;quot;&lt;br /&gt;
     end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;change-text&amp;quot;, _params, socket) do&lt;br /&gt;
    spawn(fn -&amp;gt; loop(3) end)&lt;br /&gt;
    {:noreply, assign(socket, message_item: &amp;quot;START&amp;quot; )}&lt;br /&gt;
  end&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
&lt;br /&gt;
    # AppWeb.PageLive.loop(&amp;quot;xxx&amp;quot;)&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    SANDBOX&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;.button phx-click=&amp;quot;change-text&amp;quot; value={@message_item}&amp;gt;CLICK ME&amp;lt;/.button&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;%= @message_item %&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
elixir :   1.16.2&lt;br /&gt;
&lt;br /&gt;
Erl:   20&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# PostGres&lt;br /&gt;
Created Saturday 18 February 2023&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Launch [PostGres](#PostGres) from Terminal&lt;br /&gt;
------------------------------------------&lt;br /&gt;
sudo -u postgres psql&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Set User Permission&lt;br /&gt;
-------------------&lt;br /&gt;
&amp;lt;https://commandprompt.com/education/how-to-create-a-superuser-in-postgresql/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ALTER USER user_name WITH PASSWORD 'new_password';&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Run Post Gres Commands&lt;br /&gt;
----------------------&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
sudo -i -u postgres&lt;br /&gt;
psql&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Create and Delete Database&lt;br /&gt;
&lt;br /&gt;
CREATE DATABASE name;&lt;br /&gt;
DROP DATABASE name;&lt;br /&gt;
## View user list&lt;br /&gt;
&lt;br /&gt;
\du&lt;br /&gt;
&lt;br /&gt;
 View all databases&lt;br /&gt;
&lt;br /&gt;
postgres=# \l&lt;br /&gt;
&lt;br /&gt;
 Change databases&lt;br /&gt;
&lt;br /&gt;
postgres=# \c    name-of-database&lt;br /&gt;
&lt;br /&gt;
View Tables&lt;br /&gt;
&lt;br /&gt;
After you change databases and are selected on one of them do this:&lt;br /&gt;
&lt;br /&gt;
\dt&lt;br /&gt;
&lt;br /&gt;
SELECT * FROM mytablename;&lt;br /&gt;
&lt;br /&gt;
EMPTY TABLE&lt;br /&gt;
DELETE FROM name-of-table&lt;br /&gt;
&lt;br /&gt;
CREATE TABLE&lt;br /&gt;
&lt;br /&gt;
CREATE TABLE table_name(&lt;br /&gt;
   column1 datatype,&lt;br /&gt;
   column2 datatype,&lt;br /&gt;
   column3 datatype,&lt;br /&gt;
   .....&lt;br /&gt;
   columnN datatype,&lt;br /&gt;
   PRIMARY KEY( one or more columns )&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
INSERT&lt;br /&gt;
&lt;br /&gt;
INSERT INTO ITEMS(id, name) VALUES(1,'htvjbjbgni');     Strings are single quote&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Roadmap==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.ItemsLive do&lt;br /&gt;
    use AppWeb, :live_view  &lt;br /&gt;
    def mount(_params, _session, socket)  do&lt;br /&gt;
      {:ok, assign(socket, switches: [&amp;quot;grindy&amp;quot;,&amp;quot;sonic&amp;quot;,&amp;quot;ogre&amp;quot;])}  &lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    def handle_event(&amp;quot;run&amp;quot;,_params,socket) do  &lt;br /&gt;
        &lt;br /&gt;
        IO.inspect &amp;quot;DOWNLOAD VIA SSH&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        {:noreply, redirect(socket, to: &amp;quot;/download&amp;quot;)}&lt;br /&gt;
&lt;br /&gt;
    end&lt;br /&gt;
   &lt;br /&gt;
&lt;br /&gt;
    def render(assigns) do&lt;br /&gt;
        &lt;br /&gt;
        ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        &amp;lt;ul&amp;gt;&lt;br /&gt;
        &amp;lt;%= for switch &amp;lt;- @switches do %&amp;gt;&lt;br /&gt;
         &amp;lt;a phx-submit=&amp;quot;click&amp;quot; href=&amp;quot;/download&amp;quot;&amp;gt;  &amp;lt;li&amp;gt; &amp;lt;%= switch %&amp;gt;  &amp;lt;/li&amp;gt; &amp;lt;/a&amp;gt;&lt;br /&gt;
&lt;br /&gt;
        &amp;lt;%end%&amp;gt;&lt;br /&gt;
        &amp;lt;/ul&amp;gt;&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot; &lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Notes==&lt;br /&gt;
List of Switches and the option to select the one needed.&lt;br /&gt;
Button to download JSON file.&lt;br /&gt;
Drag and Drop Palette to upload JSON file.&lt;br /&gt;
&lt;br /&gt;
After JSON file is uploaded a button titled &amp;quot;Make Active&amp;quot; is available.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://medium.com/@fraiha26/pushing-events-to-livecomponents-from-js-hooks-w-phoenix-elixir-d5544d4c3dfa&lt;br /&gt;
&lt;br /&gt;
Changeset notes and forms&lt;br /&gt;
&lt;br /&gt;
NOTE: Use case statements for pattern matching&lt;br /&gt;
____________________________________________&lt;br /&gt;
&lt;br /&gt;
Create a basic &amp;lt;.form&amp;gt;&amp;lt;/form&amp;gt; without error handling&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&amp;lt;.form :let={f} for={@changeset}  action={~p&amp;quot;/items&amp;quot;} &amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;.input field={f[:title]} type=&amp;quot;text&amp;quot; label=&amp;quot;Title&amp;quot; /&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
  &amp;lt;.button&amp;gt;Save Item&amp;lt;/.button&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;/.form&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With error handling looks like this:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;.form :let={f} for={@changeset}  action={~p&amp;quot;/items&amp;quot;} &amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;.error :if={@changeset.action}&amp;gt;&lt;br /&gt;
    Oops, something went wrong! Please check the errors below.&lt;br /&gt;
  &amp;lt;/.error&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;.input field={f[:title]} type=&amp;quot;text&amp;quot; label=&amp;quot;Title&amp;quot; /&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
  &amp;lt;.button&amp;gt;Save Item&amp;lt;/.button&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;/.form&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Create the routes for render and post to endpoint.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The controller for the page render needs to pass in the changeset via ```Items.change_item(%Item{})```&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  def new(conn, _params) do&lt;br /&gt;
    changeset = Items.change_item(%Item{})&lt;br /&gt;
    render(conn, :new, changeset: changeset)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Post route without error handling&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  def create(conn, %{&amp;quot;item&amp;quot; =&amp;gt; item_params}) do&lt;br /&gt;
    case Items.create_item(item_params) do&lt;br /&gt;
      {:ok, item} -&amp;gt;&lt;br /&gt;
        conn&lt;br /&gt;
        |&amp;gt; put_flash(:info, &amp;quot;Item created successfully.&amp;quot;)&lt;br /&gt;
        |&amp;gt; redirect(to: ~p&amp;quot;/items/#{item}&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With error handling&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  def create(conn, %{&amp;quot;item&amp;quot; =&amp;gt; item_params}) do&lt;br /&gt;
    case Items.create_item(item_params) do&lt;br /&gt;
      {:ok, item} -&amp;gt;&lt;br /&gt;
        conn&lt;br /&gt;
        |&amp;gt; put_flash(:info, &amp;quot;Item created successfully.&amp;quot;)&lt;br /&gt;
        |&amp;gt; redirect(to: ~p&amp;quot;/items/#{item}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
      {:error, %Ecto.Changeset{} = changeset} -&amp;gt;&lt;br /&gt;
        render(conn, :new, changeset: changeset)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_____________________________________________&lt;br /&gt;
https://medium.com/@vincentlin/phoenix-very-simple-form-c4b121697fcb&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''home.html.heex'''&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&amp;lt;form action=&amp;quot;/submit&amp;quot; method=&amp;quot;post&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;label for=&amp;quot;name&amp;quot;&amp;gt;Name:&amp;lt;/label&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;input type=&amp;quot;text&amp;quot; id=&amp;quot;name&amp;quot; name=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;_csrf_token&amp;quot; value={@csrf_token} /&amp;gt;&lt;br /&gt;
  &amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Submit&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
page_controller.ex&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.PageController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  def home(conn, _params) do&lt;br /&gt;
    # The home page is often custom made,&lt;br /&gt;
&lt;br /&gt;
    csrf_token = Plug.CSRFProtection.get_csrf_token()&lt;br /&gt;
    render(conn, :home, csrf_token: csrf_token)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def submit(conn, _params) do&lt;br /&gt;
    # The home page is often custom made,&lt;br /&gt;
     IO.inspect(_params)&lt;br /&gt;
     IO.inspect &amp;quot;___________________________&amp;quot;&lt;br /&gt;
    csrf_token = Plug.CSRFProtection.get_csrf_token()&lt;br /&gt;
    render(conn, :home, csrf_token: csrf_token)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
router.ex&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  scope &amp;quot;/&amp;quot;, AppWeb do&lt;br /&gt;
    pipe_through :browser&lt;br /&gt;
    post &amp;quot;/submit&amp;quot;, PageController, :submit&lt;br /&gt;
    get &amp;quot;/&amp;quot;, PageController, :home&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ecto.Adapters.SQL.query(Repo, &amp;quot;select * from artists where id=1&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ecto cheatsheet:  https://hexdocs.pm/ecto/crud.html&lt;br /&gt;
__________________________________________________________________&lt;br /&gt;
Most programming languages give you the ability to set global state by creating globally scoped variables. Elixir does not do this. Instead, Elixir provides a tool called a &amp;quot;processes&amp;quot; to persist  state. Elixir applications are composed of these &amp;quot;processes&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
Processes by themselves are complicated to use, thus Elixir provides abstractions to make working with processes easier. One of these abstractions is called a GenServer.&lt;br /&gt;
&lt;br /&gt;
GenServers are not only used to store state, they are also used to invoke work independent of the main application process. &lt;br /&gt;
&lt;br /&gt;
==Creating a GenServer to Store State==&lt;br /&gt;
&lt;br /&gt;
To Create a GenServer, start by creating a basic Module that ''uses'' the GenServer module (image below)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule App do  &lt;br /&gt;
  use GenServer&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We now need to describe the actions we want to perform. Being that this is used to store state, we will use basic CRUD actions: Create, Read, Update, Delete. To begins, empty functions describing each action is created.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule App do&lt;br /&gt;
   def create do &lt;br /&gt;
&lt;br /&gt;
   end&lt;br /&gt;
   def read do &lt;br /&gt;
&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
   def update do  &lt;br /&gt;
&lt;br /&gt;
   end &lt;br /&gt;
&lt;br /&gt;
   def delete do &lt;br /&gt;
&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==What now?==&lt;br /&gt;
&lt;br /&gt;
To fill in the functions with the appropriate code we must first have a basic understanding of how GenServers are structured.&lt;br /&gt;
&lt;br /&gt;
GenServers are composed of the GenServer module invoking callbacks. The callbacks have built in names that you, as a developer have to use.&lt;br /&gt;
&lt;br /&gt;
These callbacks are named:&lt;br /&gt;
&lt;br /&gt;
* init&lt;br /&gt;
* handle_cast&lt;br /&gt;
* handle_call&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To demonstrate, here is an example :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{:ok, pid} = GenServer.start(ModuleNameOfGenServer, %{})&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above function named &amp;quot;start&amp;quot; calls the function named init in the Module below.&lt;br /&gt;
In GenServer syntax the name of the GenServer functions always invoke callbacks that are determined by the language. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule ModuleNameOfGenServer do&lt;br /&gt;
  # 1&lt;br /&gt;
  def init(state \\ %{}) do&lt;br /&gt;
    {:ok, state}&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is a list of the GenServer functions and their corresponding callbacks.&lt;br /&gt;
&lt;br /&gt;
* GenServer.start/1  --&amp;gt;       init/1&lt;br /&gt;
* GenServer.call/3   --&amp;gt;       def handle_call/3&lt;br /&gt;
* GenServer.cast/2   --&amp;gt;       handle_cast/2&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Start and Call ==&lt;br /&gt;
&lt;br /&gt;
Call and Cast can be used to perform the same operations. The &lt;br /&gt;
&lt;br /&gt;
__________________________________________________________&lt;br /&gt;
Genserver timed events&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule Go do&lt;br /&gt;
  use GenServer&lt;br /&gt;
&lt;br /&gt;
  def go() do&lt;br /&gt;
    GenServer.start_link(__MODULE__, [])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def init(list) do&lt;br /&gt;
    :timer.apply_interval(1000, __MODULE__, :add, [self(), &amp;quot;weeeee&amp;quot;])&lt;br /&gt;
    {:ok, list}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def view(pid) do&lt;br /&gt;
    GenServer.call(pid, :view)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_call(:view, _from, list) do&lt;br /&gt;
    {:reply, list, list}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def add(pid, new_item) do&lt;br /&gt;
    GenServer.call(pid, {:item, new_item})&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_call({:item, new_item}, _from, state) do&lt;br /&gt;
    result = [new_item] ++ state&lt;br /&gt;
    {:reply, result, result}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule ShoppingList do&lt;br /&gt;
  use GenServer&lt;br /&gt;
&lt;br /&gt;
  def start_link() do&lt;br /&gt;
    GenServer.start_link(ShoppingList, [])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def init(list) do&lt;br /&gt;
    {:ok, list}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def view(pid) do&lt;br /&gt;
    GenServer.call(pid, :view)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_call(:view, _from, list) do&lt;br /&gt;
    {:reply, list, list}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def add(pid, new_item) do&lt;br /&gt;
    GenServer.call(pid, {:item, new_item})&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_call({:item, new_item}, _from, state) do&lt;br /&gt;
    result = [new_item] ++ state&lt;br /&gt;
    {:reply, result, result}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://blog.appsignal.com/2018/06/12/elixir-alchemy-deconstructing-genservers.html&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule KeyValue do&lt;br /&gt;
  # 1&lt;br /&gt;
  def init(state \\ %{}) do&lt;br /&gt;
    {:ok, state}&lt;br /&gt;
  end&lt;br /&gt;
 &lt;br /&gt;
  # 2&lt;br /&gt;
  def handle_cast({:put, key, value}, state) do&lt;br /&gt;
    {:noreply, Map.put(state, key, value)}&lt;br /&gt;
  end&lt;br /&gt;
 &lt;br /&gt;
  # 3&lt;br /&gt;
  def handle_call({:get, key}, _from, state) do&lt;br /&gt;
    {:reply, Map.fetch!(state, key), state}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
# {:ok, pid} = GenServer.start(KeyValue, %{})&lt;br /&gt;
# GenServer.cast(pid, {:put, :foo, &amp;quot;bar&amp;quot;})&lt;br /&gt;
# GenServer.call(pid, {:get, :foo})&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Send messages via these functions wrapped in module functions .You can look at these are functions used to fire &amp;quot;GenServer Events&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
* start_link&lt;br /&gt;
* GenServer.call&lt;br /&gt;
* GenServer.cast&lt;br /&gt;
&lt;br /&gt;
The corresponding server functions that reply are:&lt;br /&gt;
&lt;br /&gt;
* init&lt;br /&gt;
* handle__call&lt;br /&gt;
* handle_cast&lt;br /&gt;
* &lt;br /&gt;
&lt;br /&gt;
These can be looked at as &amp;quot;listeners&amp;quot; - in JavaScript parlance. &lt;br /&gt;
__________________________________________&lt;br /&gt;
&lt;br /&gt;
If you have experience with programming languages other than Elixir the idea of GenServers may be very foreign and require a strong context shift to learn. This document is intended to simplify the concept.&lt;br /&gt;
&lt;br /&gt;
* What: GenServers are simply a way to hold state and/or invoke actions based on incoming events. &lt;br /&gt;
* when &lt;br /&gt;
* where&lt;br /&gt;
* why&lt;br /&gt;
* how&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
___________________________________________&lt;br /&gt;
GenServer timer example&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule Timer do&lt;br /&gt;
  use GenServer&lt;br /&gt;
&lt;br /&gt;
  def init(_) do&lt;br /&gt;
    :timer.send_interval(1000, :xyz)&lt;br /&gt;
    {:ok, 0}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_info(:xyz, state) do&lt;br /&gt;
    IO.inspect(state)&lt;br /&gt;
    {:noreply, state + 1}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
[&lt;br /&gt;
   {&lt;br /&gt;
     data:{&lt;br /&gt;
        creationTime,&lt;br /&gt;
        publishDate,&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
     featured:{&lt;br /&gt;
        setAmount,&lt;br /&gt;
        items:[]&lt;br /&gt;
     },&lt;br /&gt;
&lt;br /&gt;
     children:{&lt;br /&gt;
        setAmount,&lt;br /&gt;
        items:[]&lt;br /&gt;
     },&lt;br /&gt;
     links:{&lt;br /&gt;
        setAmount,&lt;br /&gt;
        items:[]&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
jason.encode / jason.decode&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  def run(num) do&lt;br /&gt;
&lt;br /&gt;
    Enum.each(0..99999, fn(_x) -&amp;gt;&lt;br /&gt;
      task = Task.async(fn -&amp;gt; num + _x end)&lt;br /&gt;
    IO.inspect Task.await(task)&lt;br /&gt;
  end)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enum.map(feed.entries, fn x -&amp;gt; %{url: x.url, title: x.title} end)&lt;br /&gt;
&lt;br /&gt;
App is split:&lt;br /&gt;
&lt;br /&gt;
App that captures RSS in UI and lets admin select stories. THere are settings to determine the number of FEATURED,CHILD and LINK stories.&lt;br /&gt;
News categories are horizontal and scrollable.&lt;br /&gt;
This exports a json doc with all RSS data for each story.&lt;br /&gt;
The &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
App that reads the json data. This app creates tables and is the front end.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://stephenbussey.com/tags/elixir.html&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule AppWeb.GroupLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  alias App.TestBeds&lt;br /&gt;
  alias App.Groups&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    {:ok, assign(socket, testbeds: TestBeds.list_testbeds(), groups: Groups.list_groups())}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;select-group&amp;quot;, params, socket)  do  &lt;br /&gt;
     group = App.Groups.get_group!(params[&amp;quot;group-id&amp;quot;])&lt;br /&gt;
     testbed = App.TestBeds.get_test_bed!(params[&amp;quot;testbed_id&amp;quot;])&lt;br /&gt;
     App.TestBeds.update_test_bed(testbed, %{group_id: group.id})&lt;br /&gt;
     {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def updated_groups(testbed_id)  do  &lt;br /&gt;
     testbed = App.TestBeds.get_test_bed!(testbed_id)&lt;br /&gt;
     groups = App.Groups.list_groups&lt;br /&gt;
     tail = Enum.filter(groups, fn(item)-&amp;gt; item.id !== testbed.group_id end)&lt;br /&gt;
     head = Enum.filter(groups, fn(item)-&amp;gt; item.id == testbed.group_id end)&lt;br /&gt;
            |&amp;gt;Enum.at(0)&lt;br /&gt;
    [head | tail]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        &amp;lt;%= for testbed &amp;lt;- Enum.sort_by(@testbeds , &amp;amp;(&amp;quot;#{&amp;amp;1.name}&amp;quot;), :asc)do %&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;grid grid-cols-4 gap-4 p-8 rounded shadow bg-white&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;h2&amp;gt; Name&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;%= testbed.name %&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;h2&amp;gt; Group&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div&amp;gt;&lt;br /&gt;
            &amp;lt;form phx-change=&amp;quot;select-group&amp;quot; name=&amp;quot;testbed_id&amp;quot;  &amp;gt;&lt;br /&gt;
               &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;testbed_id&amp;quot; value={testbed.id}/&amp;gt;&lt;br /&gt;
               &amp;lt;select id=&amp;quot;group-selection&amp;quot;  name=&amp;quot;group-id&amp;quot; class=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;%= for group &amp;lt;- updated_groups(testbed.id) do %&amp;gt;&lt;br /&gt;
                  &amp;lt;%= if group !== nil do %&amp;gt;&lt;br /&gt;
                      &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}&amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
                      &amp;lt;%else%&amp;gt;&lt;br /&gt;
                      &amp;lt;option value= {&amp;quot;Unassigned&amp;quot;}&amp;gt;NONE&amp;lt;/option&amp;gt;&lt;br /&gt;
                  &amp;lt;% end %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
               &amp;lt;/select&amp;gt;&lt;br /&gt;
            &amp;lt;/form&amp;gt;&lt;br /&gt;
          &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
       &amp;lt;% end %&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Developer Notes ==&lt;br /&gt;
===Groups Feature ===&lt;br /&gt;
To complete this feature do these things.&lt;br /&gt;
* Run through the steps in [http://elixirblocks.com/index.php?title=Create_Foreign_Key_Relationship_Between_Ecto_Tables  | this document] to create Group table.&lt;br /&gt;
* Groups have these fields  '''name: string''', '''description: string''' and '''color: string'''  &lt;br /&gt;
* Add unique constraint in migration file: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def change do&lt;br /&gt;
     create unique_index(:groups, [:name])&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Port over Group LiveView code (temporarily placed at discussion page).&lt;br /&gt;
* On completion '''possibly''', create a Group named '''No Group''' and set all Testbeds to it.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
________&lt;br /&gt;
https://blog.appsignal.com/2022/10/11/phoenix-liveview-018-new-special-html-attributes.html&lt;br /&gt;
https://blixtdev.com/whats-new-phoenix-1-7/&lt;br /&gt;
https://github.com/devato/inertia_phoenix&lt;br /&gt;
https://phoenixonrails.com/blog/you-can-stop-using-form-for-in-phoenix&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://samuelmullen.com/articles/phoenix_templates_rendering_and_layouts&lt;br /&gt;
&lt;br /&gt;
WorkFlow of Todo App in Both LiveView and DeadView.&lt;br /&gt;
&lt;br /&gt;
Note:&lt;br /&gt;
&lt;br /&gt;
Create foreign key data.&lt;br /&gt;
Create live view. List all testbeds and form to assign each a group by group-name.&lt;br /&gt;
&lt;br /&gt;
Repeat in dead view&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Mental model and data flows&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
home.html.heex&lt;br /&gt;
&amp;lt;a href=&amp;quot;/data&amp;quot; name=&amp;quot;we are the world&amp;quot; &amp;gt;  click me&amp;lt;/a&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;%= @message %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
page controller&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  def home(conn, _params) do&lt;br /&gt;
    IO.inspect _params&lt;br /&gt;
    render(conn, :home, message: &amp;quot;Hello&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
get &amp;quot;/:yay&amp;quot;, PageController, :index&lt;br /&gt;
&lt;br /&gt;
get &amp;quot;/&amp;quot;, PageController, :index&lt;br /&gt;
&lt;br /&gt;
* Explain control flow of &amp;quot;Dead Views&amp;quot; and the Generator HTML Control flow.&lt;br /&gt;
* Proper Way to use Modal&lt;br /&gt;
* How to give Focus to Fields in Modal (or other forms fields)&lt;br /&gt;
* &lt;br /&gt;
* &lt;br /&gt;
* How to Create Database Seed Data.&lt;br /&gt;
* How to structure code so controller code is in one file and HTML Heex is in another&lt;br /&gt;
* How to Use Generators in a Real World Project&lt;br /&gt;
* How to Work with Database Data via Basic Commands and Custom Change sets.&lt;br /&gt;
* How to Render Database Data to LiveView (via Context Commands).&lt;br /&gt;
* How to Create a Chat using PubSub.&lt;br /&gt;
* How to Create Event Handlers in LiveView&lt;br /&gt;
* How to Create a Dynamic Route from Scratch.&lt;br /&gt;
* How to Use Elixirs Template language&lt;br /&gt;
* How to Work with Modal&lt;br /&gt;
* How to Use CSS From Scratch (Without bundler)&lt;br /&gt;
* How to use JS hooks&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
______________________&lt;br /&gt;
https://studioindie.co/blog/heex-guide/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
get &amp;quot;/&amp;quot;, PageController, :some-atom    #This is the route. some-atom is the controller name&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  def some-atom(conn, _params) do                 # controller name&lt;br /&gt;
    # The home page is often custom made,&lt;br /&gt;
    # so skip the default app layout.&lt;br /&gt;
    render(conn, :some-atom, layout: false)      # :some-atom is template name&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Controllers page_html.ex contains &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageHTML do&lt;br /&gt;
  use AppWeb, :html&lt;br /&gt;
&lt;br /&gt;
  embed_templates &amp;quot;page_html/*&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''page_html''' is the name of the folder in '''Controllers/page_html'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Controllers/page_html/some-atom.html.heex  (this is the template) &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__________________________________________&lt;br /&gt;
Set all association with preload:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  def list_groups do&lt;br /&gt;
    Repo.all(Group)&lt;br /&gt;
     |&amp;gt; Repo.preload([:testbeds])&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Insert Child into Parent ===&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
App.get_group!(2) # arg is id&lt;br /&gt;
|&amp;gt; Ecto.build_assoc(:testbeds)&lt;br /&gt;
|&amp;gt; Repo.insert()&lt;br /&gt;
&lt;br /&gt;
Or&lt;br /&gt;
&lt;br /&gt;
group = App.get_group!(2) # arg is id&lt;br /&gt;
&lt;br /&gt;
testbeds = Ecto.build_assoc(group, :testbeds)&lt;br /&gt;
&lt;br /&gt;
App.Group.create_group(testbeds)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
group = App.Groups.get_group!(1)&lt;br /&gt;
thing = Ecto.build_assoc(group, :testbeds, name: &amp;quot;DUMB&amp;quot;)&lt;br /&gt;
alias App.{Repo}&lt;br /&gt;
Repo.insert(thing)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
avatar = %Avatar{nick_name: &amp;quot;Elixir&amp;quot;, pic_url: &amp;quot;http://elixir-lang.org/images/logo.png&amp;quot;}&lt;br /&gt;
user = %User{name: &amp;quot;John Doe&amp;quot;, email: &amp;quot;john.doe@example.com&amp;quot;, avatar: avatar}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://www.reddit.com/r/elixir/comments/oh318k/is_there_a_way_to_avoid_ectoassociationnotloaded/h4mmcfi/?utm_source=share&amp;amp;utm_medium=web3x&amp;amp;utm_name=web3xcss&amp;amp;utm_term=1&amp;amp;utm_content=share_button&lt;br /&gt;
&lt;br /&gt;
# Create Group Table&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
mix phx.gen.html Groups Group groups name:string  &lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Set the resources / &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
mix ecto.migrate&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For testbeds create a migration file and add this field:   group_id:references:groups&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
def change do&lt;br /&gt;
    alter table(:testbeds) do    # customize to your code&lt;br /&gt;
      add :group_id, references(:groups)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Update Groups Schema (Don't forget alias / has_many)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule App.Groups.Group do&lt;br /&gt;
	use Ecto.Schema&lt;br /&gt;
	import Ecto.Changeset&lt;br /&gt;
	alias App.Testbeds.Testbed   # Alias!&lt;br /&gt;
&lt;br /&gt;
	schema &amp;quot;posts&amp;quot; do&lt;br /&gt;
		field :body, :string&lt;br /&gt;
		field :title, :string&lt;br /&gt;
		has_many :testbeds, Testbed    # Has many&lt;br /&gt;
&lt;br /&gt;
		timestamps()&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	@doc false&lt;br /&gt;
	def changeset(post, attrs) do&lt;br /&gt;
		post&lt;br /&gt;
		|&amp;gt; cast(attrs, [:title, :body])&lt;br /&gt;
		|&amp;gt; validate_required([:title, :body])&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
TESTBEDS Schema&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule App.Testbeds.Testbed do&lt;br /&gt;
  use Ecto.Schema&lt;br /&gt;
  import Ecto.Changeset&lt;br /&gt;
  alias App.Groups.Group      # Alias&lt;br /&gt;
  schema &amp;quot;testbeds&amp;quot; do&lt;br /&gt;
    field :name, :string&lt;br /&gt;
    belongs_to :group, Group    # Belongs to&lt;br /&gt;
    timestamps()&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  @doc false&lt;br /&gt;
  def changeset(testbed, attrs) do&lt;br /&gt;
    testbed&lt;br /&gt;
    |&amp;gt; cast(attrs, [:name])&lt;br /&gt;
    |&amp;gt; validate_required([:name])&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
_____________________________________&lt;br /&gt;
Side notes.&lt;br /&gt;
&lt;br /&gt;
defmodule App.Repo.Migrations.CreateTestbeds do&lt;br /&gt;
  use Ecto.Migration&lt;br /&gt;
&lt;br /&gt;
  def change do&lt;br /&gt;
    create table(:testbeds) do&lt;br /&gt;
      add :name, :string&lt;br /&gt;
      add :group_id, references(:groups, on_delete: :nothing)&lt;br /&gt;
&lt;br /&gt;
      timestamps()&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    create index(:testbeds, [:group_id])&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
________________________________&lt;br /&gt;
&lt;br /&gt;
mix phx.gen.context Comments Comment comments name:string content:text post_id:references:posts&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
mix phx.gen.html Testbeds Testbed testbeds name:string  group_id:references:groups&lt;br /&gt;
&lt;br /&gt;
https://graffino.com/web-development/first-steps-in-elixir-and-phoenix-create-a-blog-prototype&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://blog.logrocket.com/getting-started-ecto-phoenix/&lt;br /&gt;
&lt;br /&gt;
https://serokell.io/blog/ecto-guide-for-beginners&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
mix phx.gen.html Testbeds Testbed testbeds name:string&lt;br /&gt;
&lt;br /&gt;
mix phx.gen.html Groups Group groups name:string&lt;br /&gt;
&lt;br /&gt;
Create migration for &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
mix ecto.gen.migration add_testbed_group_reference&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Migration:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  def change do&lt;br /&gt;
    alter table(:testbeds) do    # customize to your code&lt;br /&gt;
      add :group_id, references(:groups)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Manually Change:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule App.Group do&lt;br /&gt;
  use Ecto.Schema&lt;br /&gt;
&lt;br /&gt;
  schema &amp;quot;groups&amp;quot; do&lt;br /&gt;
    field :title, :string&lt;br /&gt;
    field :tagline, :string&lt;br /&gt;
    has_many :testbeds, App.Testbed&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
testbeds&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule App.Repo.Migrations.AddTextbedGroups do&lt;br /&gt;
  use Ecto.Migration&lt;br /&gt;
&lt;br /&gt;
  def change do&lt;br /&gt;
    create table(:testbeds) do&lt;br /&gt;
      add :name, :string&lt;br /&gt;
      add :group_id, references(:groups)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
# lib/app/testbeds.ex&lt;br /&gt;
&lt;br /&gt;
defmodule App.Testbed do&lt;br /&gt;
  use Ecto.Schema&lt;br /&gt;
&lt;br /&gt;
  schema &amp;quot;testbedss&amp;quot; do&lt;br /&gt;
    field :name, :string&lt;br /&gt;
    belongs_to :group, App.Group&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_____________________&lt;br /&gt;
&lt;br /&gt;
%App.TestBeds.TestBed{&lt;br /&gt;
  __meta__: #Ecto.Schema.Metadata&amp;lt;:loaded, &amp;quot;testbeds&amp;quot;&amp;gt;,&lt;br /&gt;
  id: 1,&lt;br /&gt;
  developer: &amp;quot;None&amp;quot;,&lt;br /&gt;
  name: &amp;quot;sdfsd&amp;quot;,&lt;br /&gt;
  owner: &amp;quot;sdfsddf&amp;quot;,&lt;br /&gt;
  note: &amp;quot;sdsfsddf&amp;quot;,&lt;br /&gt;
  status: &amp;quot;Available&amp;quot;,&lt;br /&gt;
  url: &amp;quot;sdf&amp;quot;,&lt;br /&gt;
  version: &amp;quot;ddf&amp;quot;,&lt;br /&gt;
  manager: &amp;quot;sf&amp;quot;,&lt;br /&gt;
  inserted_at: ~N[2023-08-21 13:45:39],&lt;br /&gt;
  updated_at: ~N[2023-08-21 13:45:44]&lt;br /&gt;
}&lt;br /&gt;
________________________________________________________________---&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.SendLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  &lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    {:ok, socket}&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  def handle_event(&amp;quot;send&amp;quot;, %{&amp;quot;text&amp;quot; =&amp;gt; text}, socket) do&lt;br /&gt;
&lt;br /&gt;
    AppWeb.Endpoint.broadcast(topic, &amp;quot;message&amp;quot;, text)&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  defp topic do&lt;br /&gt;
    &amp;quot;chat&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def render(assigns)do   &lt;br /&gt;
   ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
  &amp;lt;h1&amp;gt;Send Message&amp;lt;/h1&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;form phx-submit=&amp;quot;send&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;text&amp;quot; /&amp;gt;&lt;br /&gt;
    &amp;lt;button type=&amp;quot;submit&amp;quot;&amp;gt;Send&amp;lt;/button&amp;gt;&lt;br /&gt;
  &amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
______________________________________________________________&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.ReceiveLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  &lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    if connected?(socket) do&lt;br /&gt;
      AppWeb.Endpoint.subscribe(topic)&lt;br /&gt;
    end&lt;br /&gt;
    {:ok, assign(socket, messages: &amp;quot;&amp;quot;)}&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def handle_info(%{event: &amp;quot;message&amp;quot;, payload: message}, socket) do&lt;br /&gt;
    IO.inspect message&lt;br /&gt;
    {:noreply, assign(socket, messages: message)}&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  defp topic do&lt;br /&gt;
    &amp;quot;chat&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns)do   &lt;br /&gt;
   ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
  &amp;lt;h1&amp;gt;ChatLive&amp;lt;/h1&amp;gt;&lt;br /&gt;
  &amp;lt;%= @messages %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
______________________________________________________________&lt;br /&gt;
When you hover over a list of items this hook finds items with the same name and sets the opacity of all others to 0. You see all the items similar to the one you are hovering over.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
TestbedVersionHover: {&lt;br /&gt;
			// https://jsfiddle.net/IrvinDominin/7K2Z3/&lt;br /&gt;
            mounted() {&lt;br /&gt;
&lt;br /&gt;
                let rows = document.getElementsByClassName(&amp;quot;testbed-version&amp;quot;)&lt;br /&gt;
                // this.ele = element&lt;br /&gt;
				// rows = this.ele;&lt;br /&gt;
                &lt;br /&gt;
				for (var i = 0; i &amp;lt; rows.length; i++) {&lt;br /&gt;
					rows[i].onmouseenter = function (event) {&lt;br /&gt;
						for (var j = 0; j &amp;lt; rows.length; j++) {&lt;br /&gt;
							let preversion = this.textContent;&lt;br /&gt;
							let version = preversion.slice(0,5)&lt;br /&gt;
							let compareVersion = rows[j].textContent.slice(0,5)&lt;br /&gt;
							if (compareVersion === version) continue&lt;br /&gt;
							rows[j].className += &amp;quot; other&amp;quot;;&lt;br /&gt;
						}&lt;br /&gt;
					};&lt;br /&gt;
				&lt;br /&gt;
					rows[i].onmouseleave = function (event) {&lt;br /&gt;
						var hovers = document.getElementsByClassName('other');&lt;br /&gt;
						var len = hovers.length;&lt;br /&gt;
						for (var j = 0; j &amp;lt; len; j++) {&lt;br /&gt;
							hovers[0].className = hovers[0].className.replace(/\sother(\s|$)/, '');&lt;br /&gt;
						}&lt;br /&gt;
					};&lt;br /&gt;
				}&lt;br /&gt;
&lt;br /&gt;
                // this.ele.addEventListener(&amp;quot;click&amp;quot;, (e) =&amp;gt; {&lt;br /&gt;
                //     console.log(e.target)&lt;br /&gt;
                    &lt;br /&gt;
                // });&lt;br /&gt;
&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* How to Create Database Seed Data.&lt;br /&gt;
* How to structure code so controller code is in one file and HTML Heex is in another&lt;br /&gt;
* How to Use Generators in a Real World Project&lt;br /&gt;
* How to Work with Database Data via Basic Commands and Custom Change sets.&lt;br /&gt;
* How to Render Database Data to LiveView (via Context Commands).&lt;br /&gt;
* How to Create a Chat using PubSub.&lt;br /&gt;
* How to Create Event Handlers in LiveView&lt;br /&gt;
* How to Create a Dynamic Route from Scratch.&lt;br /&gt;
* How to Use Elixirs Template language&lt;br /&gt;
* How to Work with Modal&lt;br /&gt;
* How to Use CSS From Scratch (Without bundler)&lt;br /&gt;
* How to use JS hooks&lt;br /&gt;
* Dissect Table Component and Update it to Order List in Reverse.&lt;br /&gt;
&lt;br /&gt;
Selenium&lt;br /&gt;
https://www.builder.io/blog/debug-nodejs&lt;br /&gt;
&lt;br /&gt;
https://marketplace.visualstudio.com/items?itemName=ms-vscode.live-server#running-the-extension&lt;br /&gt;
&lt;br /&gt;
This was added recently (see microsoft/vscode#109276).&lt;br /&gt;
    1. Open the palette (Ctrl + Shift + P)&lt;br /&gt;
    2. Select &amp;quot;Simple Browser: Preview&amp;quot;&lt;br /&gt;
    3. Enter web address&lt;br /&gt;
&lt;br /&gt;
_______________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
const {By, Key, Builder} = require(&amp;quot;selenium-webdriver&amp;quot;);&lt;br /&gt;
const assert = require(&amp;quot;assert&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
require(&amp;quot;chromedriver&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
async function test_case(){&lt;br /&gt;
  let driver = await new Builder().forBrowser(&amp;quot;chrome&amp;quot;).build();&lt;br /&gt;
  await driver.get(&amp;quot;sie&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  await driver.findElement(By.name('password')).clear();&lt;br /&gt;
  await driver.findElement(By.name('identification')).clear();&lt;br /&gt;
  await driver.findElement(By.name('identification')).sendKeys(&amp;quot;bill&amp;quot;);&lt;br /&gt;
  await driver.findElement(By.name('password')).sendKeys(&amp;quot;password&amp;quot;, Key.RETURN);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 setTimeout(()=&amp;gt;{&lt;br /&gt;
   driver.findElement(By.className(&amp;quot;req_lan_license&amp;quot;)).click();&lt;br /&gt;
 },5000)&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageLive do &lt;br /&gt;
&lt;br /&gt;
  use AppWeb, :live_view  &lt;br /&gt;
  alias App.Testbeds &lt;br /&gt;
  def mount(_params, _session, socket)do   &lt;br /&gt;
     {:ok, assign(socket, testbeds: Testbeds.list_testbeds())}   &lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
    def button_event(&amp;quot;invoke_editing&amp;quot;) do&lt;br /&gt;
    %JS{}&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;active&amp;quot;, to: &amp;quot;#editing_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#editing_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#preview_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;active&amp;quot;, to: &amp;quot;#preview_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;active&amp;quot;, to: &amp;quot;#preview&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#preview&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#editing&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;active&amp;quot;, to: &amp;quot;#editing&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def button_event(&amp;quot;invoke_preview&amp;quot;) do&lt;br /&gt;
    %JS{}&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;active&amp;quot;, to: &amp;quot;#preview_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#preview_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#editing_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;active&amp;quot;, to: &amp;quot;#editing_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;active&amp;quot;, to: &amp;quot;#editing&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#editing&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#preview&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;active&amp;quot;, to: &amp;quot;#preview&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;send&amp;quot;, params, socket) do&lt;br /&gt;
    hide_modal(&amp;quot;notes-modal-0&amp;quot;)&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do  &lt;br /&gt;
     ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
		&amp;lt;.modal id={&amp;quot;notes-modal-#{testbed.id}&amp;quot;}&amp;gt;&lt;br /&gt;
		    &amp;lt;.button phx-click={button_event(&amp;quot;invoke_editing&amp;quot;)} id=&amp;quot;editing_button&amp;quot; class=&amp;quot;hidden&amp;quot;&amp;gt;&lt;br /&gt;
		      Preview&lt;br /&gt;
		    &amp;lt;/.button&amp;gt;&lt;br /&gt;
		    &amp;lt;.button phx-click={button_event(&amp;quot;invoke_preview&amp;quot;)} id=&amp;quot;preview_button&amp;quot;&amp;gt;&lt;br /&gt;
		      Edit Me&lt;br /&gt;
		    &amp;lt;/.button&amp;gt;&lt;br /&gt;
		    &amp;lt;div id=&amp;quot;editing&amp;quot;&amp;gt; PREVIEWING THE WORK&amp;lt;/div&amp;gt;&lt;br /&gt;
		    &amp;lt;form phx-submit = &amp;quot;send&amp;quot;   id=&amp;quot;preview&amp;quot; class=&amp;quot;hidden&amp;quot;&amp;gt;&lt;br /&gt;
		      &amp;lt;textarea value = {testbed.note}&amp;gt;&amp;lt;/textarea&amp;gt;&lt;br /&gt;
		      &amp;lt;.button type=&amp;quot;submit&amp;quot; phx-click={hide_modal(&amp;quot;notes-modal-#{testbed.id}&amp;quot;)}&amp;gt;SAVE WORK&amp;lt;/.button&amp;gt;&lt;br /&gt;
		    &amp;lt;/form&amp;gt;&lt;br /&gt;
		&amp;lt;/.modal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;%= if testbed.note do %&amp;gt;&lt;br /&gt;
      &amp;lt;div phx-click={show_modal(&amp;quot;notes-modal-#{testbed.id}&amp;quot;)}&amp;gt;READ ME  ...&amp;lt;%= testbed.note %&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
	   &lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
       &lt;br /&gt;
      &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
import {HfInference} from &amp;quot;@huggingface/inference&amp;quot;;&lt;br /&gt;
import dotenv from &amp;quot;dotenv&amp;quot;;&lt;br /&gt;
dotenv.config()&lt;br /&gt;
&lt;br /&gt;
const HF_ACCESS_TOKEN = process.env.HF_ACCESS_TOKEN&lt;br /&gt;
&lt;br /&gt;
const hf = new HfInference(HF_ACCESS_TOKEN);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*______Uncomment for this example______________________&lt;br /&gt;
&lt;br /&gt;
const model = &amp;quot;nlpconnect/vit-gpt2-image-captioning&amp;quot;;&lt;br /&gt;
const imageURL = &amp;quot;https://i.imgur.com/lTvb7Et.png&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
const response = await fetch(imageURL);&lt;br /&gt;
const imageBlob = await response.blob();&lt;br /&gt;
&lt;br /&gt;
const result  = await hf.imageToText({&lt;br /&gt;
	data: imageBlob,&lt;br /&gt;
	model: model,&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
_______________________________________________________*/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*________Another example ___________________*/&lt;br /&gt;
&lt;br /&gt;
const result = await hf.summarization({&lt;br /&gt;
	model: 'facebook/bart-large-cnn',&lt;br /&gt;
	inputs: &amp;quot;The role of a dumb man is to get smarter oogy bookie boo&amp;quot;,&lt;br /&gt;
	parameters:{&lt;br /&gt;
		max_length: 100&lt;br /&gt;
	}&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
console.log(result);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
________________________________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://fly.io/phoenix-files/sdeb-toggling-element/&lt;br /&gt;
https://www.youtube.com/watch?v=vBgZvQapqhs&lt;br /&gt;
&lt;br /&gt;
https://blog.testdouble.com/posts/2022-11-28-how-to-use-javascript-with-phoenix-liveview/&lt;br /&gt;
&lt;br /&gt;
https://hexdocs.pm/phoenix_live_view/0.19.3/Phoenix.Component.html&lt;br /&gt;
_______________________________________&lt;br /&gt;
https://www.smashingmagazine.com/2011/10/quick-look-math-animations-javascript/&lt;br /&gt;
* Depth first traversal&lt;br /&gt;
* Breadth first traversal&lt;br /&gt;
&lt;br /&gt;
https://dev.to/codesphere/10-algorithms-every-developer-should-learn-3lnm&lt;br /&gt;
&lt;br /&gt;
https://www.youtube.com/watch?v=fPz40W9mfCg&lt;br /&gt;
&lt;br /&gt;
__________________________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.GroupLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  alias App.TestBeds&lt;br /&gt;
  alias App.Groups&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    {:ok, assign(socket, testbeds: TestBeds.list_testbeds(), groups: Groups.list_groups())}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;select-group&amp;quot;, params, socket)  do  &lt;br /&gt;
         &lt;br /&gt;
       IO.inspect params&lt;br /&gt;
       {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div class=&amp;quot;grid grid-columns-2 grid-flow-col gap-4&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;column-1&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;%= testbed.name %&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;column-2&amp;quot;&amp;gt;    &lt;br /&gt;
            &amp;lt;form phx-change=&amp;quot;select-group&amp;quot;  &amp;gt;&lt;br /&gt;
               &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;testbed_id&amp;quot; value={testbed.id}/&amp;gt;&lt;br /&gt;
               &amp;lt;select id=&amp;quot;group-selection&amp;quot;  name=&amp;quot;group-id&amp;quot; &amp;gt;&lt;br /&gt;
                &amp;lt;%= for group &amp;lt;- @groups do %&amp;gt;&lt;br /&gt;
                  &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}  &amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
               &amp;lt;/select&amp;gt;&lt;br /&gt;
            &amp;lt;/form&amp;gt;&lt;br /&gt;
         &amp;lt;/div&amp;gt;&lt;br /&gt;
       &amp;lt;% end %&amp;gt;&lt;br /&gt;
   &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
____________________________&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.GroupLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  alias App.TestBeds&lt;br /&gt;
  alias App.Groups&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
&lt;br /&gt;
    {:ok, assign(socket, testbeds: TestBeds.list_testbeds(), groups: Groups.list_groups(), messages: [])}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;select-group&amp;quot;, params, socket)  do  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
      group = App.Groups.get_group!(params[&amp;quot;group-id&amp;quot;])&lt;br /&gt;
       # IO.inspect group&lt;br /&gt;
       testbed = App.TestBeds.get_test_bed!(params[&amp;quot;testbed_id&amp;quot;])&lt;br /&gt;
     &lt;br /&gt;
       App.TestBeds.update_test_bed(testbed, %{group_id: group.id})&lt;br /&gt;
         &lt;br /&gt;
    &lt;br /&gt;
       {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def updated_groups(testbed_id)  do  &lt;br /&gt;
       groups = App.Groups.list_groups&lt;br /&gt;
       tail = Enum.filter(groups, fn(item)-&amp;gt; item.id !== testbed_id end)&lt;br /&gt;
       head = Enum.filter(groups, fn(item)-&amp;gt; item.id == testbed_id end)&lt;br /&gt;
              |&amp;gt;Enum.at(0)&lt;br /&gt;
     [head | tail]&lt;br /&gt;
         &lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
 # def handle_event(&amp;quot;groups&amp;quot;, params, socket)do  &lt;br /&gt;
 #       selected_testbed = %{name: &amp;quot;my testbed name&amp;quot;, id: 3}&lt;br /&gt;
 #       groups = App.Groups.list_groups&lt;br /&gt;
 #       tail = Enum.filter(groups, fn(item)-&amp;gt; item.id !== selected_testbed.id end)&lt;br /&gt;
 #       head = Enum.filter(groups, fn(item)-&amp;gt; item.id == selected_testbed.id end)&lt;br /&gt;
 #              |&amp;gt;Enum.at(0)&lt;br /&gt;
         &lt;br /&gt;
 &lt;br /&gt;
 #       # result = Enum.filter([1, 2, 3], fn x -&amp;gt; x.id !== 1 end)&lt;br /&gt;
 #      IO.inspect [head | tail]&lt;br /&gt;
         &lt;br /&gt;
 #      #&lt;br /&gt;
 #      {:noreply, socket, assigns.message:}&lt;br /&gt;
 #  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    &lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
       &amp;lt;%!-- &amp;lt;div phx-click = &amp;quot;groups&amp;quot;&amp;gt;CLICK ME&amp;lt;/div&amp;gt; --%&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;grid grid-cols-4 gap-4 p-8 rounded shadow bg-white&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;h2&amp;gt; Name&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;%= testbed.name %&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;h2&amp;gt; Group&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;form phx-change=&amp;quot;select-group&amp;quot; name=&amp;quot;testbed_id&amp;quot;  &amp;gt;&lt;br /&gt;
               &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;testbed_id&amp;quot; value={testbed.id}/&amp;gt;&lt;br /&gt;
               &amp;lt;select id=&amp;quot;group-selection&amp;quot;  name=&amp;quot;group-id&amp;quot; class=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
                &amp;lt;%= for group &amp;lt;- updated_groups(testbed.id) do %&amp;gt;&lt;br /&gt;
                  &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}  &amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
                  &amp;lt;!-- Write code to reorder with testbed.group_id matching group_id --&amp;gt;&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
               &amp;lt;/select&amp;gt;&lt;br /&gt;
            &amp;lt;/form&amp;gt;&lt;br /&gt;
          &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
       &amp;lt;% end %&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_____________________________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
   use AppWeb, :live_view  &lt;br /&gt;
     alias App.Testbeds&lt;br /&gt;
  alias App.Groups&lt;br /&gt;
   def mount(_params, _session, socket)  do&lt;br /&gt;
	     {:ok, assign(socket, testbeds: Testbeds.list_testbeds(), groups: Groups.list_groups())}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
   def handle_event(&amp;quot;select-group&amp;quot;, params, socket)  do  &lt;br /&gt;
       group = App.Groups.get_group!(params[&amp;quot;group-id&amp;quot;])&lt;br /&gt;
       testbed = App.Testbeds.get_testbed!(params[&amp;quot;testbed_id&amp;quot;])&lt;br /&gt;
       result = App.Testbeds.update_testbed(testbed, %{group_id: group.id})&lt;br /&gt;
       IO.inspect result&lt;br /&gt;
      &lt;br /&gt;
       {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
    def updated_groups(testbed_id)  do  &lt;br /&gt;
       testbed = App.Testbeds.get_testbed!(testbed_id)&lt;br /&gt;
       groups = App.Groups.list_groups&lt;br /&gt;
       tail = Enum.filter(groups, fn(item)-&amp;gt; item.id !== testbed.group_id end)&lt;br /&gt;
       head = Enum.filter(groups, fn(item)-&amp;gt; item.id == testbed.group_id end)&lt;br /&gt;
              |&amp;gt;Enum.at(0)&lt;br /&gt;
 &lt;br /&gt;
       [head | tail]&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    &lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;grid grid-cols-4 gap-4 p-8 rounded shadow bg-white&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;h2&amp;gt; Name&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;%= testbed.name %&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;h2&amp;gt; Group&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;form phx-change=&amp;quot;select-group&amp;quot; name=&amp;quot;testbed_id&amp;quot;  &amp;gt;&lt;br /&gt;
               &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;testbed_id&amp;quot; value={testbed.id}/&amp;gt;&lt;br /&gt;
               &amp;lt;select id=&amp;quot;group-selection&amp;quot;  name=&amp;quot;group-id&amp;quot; class=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
                &amp;lt;%= for group &amp;lt;- updated_groups(testbed.id) do %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
                  &amp;lt;%!-- &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}&amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt; --%&amp;gt;&lt;br /&gt;
                  &amp;lt;!-- Write code to reorder with testbed.group_id matching group_id --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
                  &amp;lt;%= if group !== nil do %&amp;gt;&lt;br /&gt;
                      &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}&amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
       &lt;br /&gt;
                  &amp;lt;% end %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
               &amp;lt;/select&amp;gt;&lt;br /&gt;
            &amp;lt;/form&amp;gt;&lt;br /&gt;
          &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
       &amp;lt;% end %&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  has_many :testbeds, TestBed, on_delete: :restrict   # Has many&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://elixirforum.com/t/ecto-has-many-on-delete-protect/49550&lt;br /&gt;
&lt;br /&gt;
https://hexdocs.pm/ecto/Ecto.Changeset.html#unique_constraint/3&lt;br /&gt;
&lt;br /&gt;
____________________________________________________________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== How to Create a Mix Project and Use It in Another Mix Project ==&lt;br /&gt;
&lt;br /&gt;
To create and use a **Mix project** inside another **Mix project** in Elixir, follow the steps below:&lt;br /&gt;
&lt;br /&gt;
=== 1. Create a New Mix Project ===&lt;br /&gt;
&lt;br /&gt;
First, you need to create a new Mix project. Let's call this project `library_project`. Run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mix new library_project --module LibraryProject&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will create a new Elixir Mix project named `library_project`. The `--module` flag specifies the name of the module that will be created (in this case `LibraryProject`).&lt;br /&gt;
&lt;br /&gt;
The directory structure of `library_project` will look like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
library_project/&lt;br /&gt;
  |_ lib/&lt;br /&gt;
      |_ library_project.ex&lt;br /&gt;
  |_ mix.exs&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can then add some basic functionality inside the `library_project/lib/library_project.ex` file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule LibraryProject do&lt;br /&gt;
  def hello do&lt;br /&gt;
    IO.puts &amp;quot;Hello from LibraryProject!&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now, `library_project` is ready to be used by another Mix project.&lt;br /&gt;
&lt;br /&gt;
=== 2. Create a Second Mix Project ===&lt;br /&gt;
&lt;br /&gt;
Next, create the second Mix project where you want to use `library_project`. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mix new app_project --module AppProject&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will create another Elixir project called `app_project`.&lt;br /&gt;
&lt;br /&gt;
The directory structure for this project will look like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
app_project/&lt;br /&gt;
  |_ lib/&lt;br /&gt;
      |_ app_project.ex&lt;br /&gt;
  |_ mix.exs&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 3. Add `library_project` as a Dependency in `app_project` ===&lt;br /&gt;
&lt;br /&gt;
Now, you want to make `library_project` available in `app_project`. There are two main ways to do this:&lt;br /&gt;
&lt;br /&gt;
==== Option 1: Local Dependency (via `path`) ====&lt;br /&gt;
&lt;br /&gt;
If `library_project` is a local project (i.e., it's stored in a different directory), you can add it to the `mix.exs` of `app_project` as a local dependency by specifying the path to `library_project`.&lt;br /&gt;
&lt;br /&gt;
Edit the `mix.exs` of `app_project`:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule AppProject.MixProject do&lt;br /&gt;
  use Mix.Project&lt;br /&gt;
&lt;br /&gt;
  def project do&lt;br /&gt;
    [&lt;br /&gt;
      app: :app_project,&lt;br /&gt;
      version: &amp;quot;0.1.0&amp;quot;,&lt;br /&gt;
      elixir: &amp;quot;~&amp;gt; 1.14&amp;quot;,&lt;br /&gt;
      start_permanent: Mix.env() == :prod,&lt;br /&gt;
      deps: deps()&lt;br /&gt;
    ]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  defp deps do&lt;br /&gt;
    [&lt;br /&gt;
      {:library_project, path: &amp;quot;../library_project&amp;quot;}  # Add the local dependency&lt;br /&gt;
    ]&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here, `{:library_project, path: &amp;quot;../library_project&amp;quot;}` tells Mix to use the local `library_project` located in the `../library_project` directory (relative to `app_project`).&lt;br /&gt;
&lt;br /&gt;
After updating the `mix.exs`, run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd app_project&lt;br /&gt;
mix deps.get&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will fetch the dependency and compile `library_project`.&lt;br /&gt;
&lt;br /&gt;
==== Option 2: Publish and Fetch as a Hex Package ====&lt;br /&gt;
&lt;br /&gt;
If you want to use `library_project` as a package in another project (for example, by publishing it to **Hex.pm**, Elixir’s package manager), you need to publish it to Hex and then add it as a dependency.&lt;br /&gt;
&lt;br /&gt;
1. Publish `library_project` to Hex (if it's public or for your private use).&lt;br /&gt;
2. Add `library_project` to your `app_project`’s `mix.exs` dependencies:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defp deps do&lt;br /&gt;
  [&lt;br /&gt;
    {:library_project, &amp;quot;~&amp;gt; 0.1.0&amp;quot;}  # Specify the published version from Hex&lt;br /&gt;
  ]&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Run `mix deps.get` to fetch the package from Hex.&lt;br /&gt;
&lt;br /&gt;
=== 4. Use `library_project` in `app_project` ===&lt;br /&gt;
&lt;br /&gt;
Now, you can use the functionality from `library_project` inside your `app_project`. For example, in `app_project/lib/app_project.ex`, you can call the function from `library_project`:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule AppProject do&lt;br /&gt;
  def start do&lt;br /&gt;
    IO.puts &amp;quot;Starting app_project!&amp;quot;&lt;br /&gt;
    LibraryProject.hello()  # Call the function from the library_project&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 5. Run the App ===&lt;br /&gt;
&lt;br /&gt;
Finally, you can run your `app_project`:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd app_project&lt;br /&gt;
mix run -e &amp;quot;AppProject.start()&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will print:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Starting app_project!&lt;br /&gt;
Hello from LibraryProject!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Recap of the Process ==&lt;br /&gt;
1. **Create the `library_project`**: Use `mix new` to generate a library project.&lt;br /&gt;
2. **Create the `app_project`**: Create the second project where you will use the library.&lt;br /&gt;
3. **Add the `library_project` as a dependency**:&lt;br /&gt;
   - Use the `path` option to point to the local project or publish it to Hex for public access.&lt;br /&gt;
4. **Use the `library_project` in the `app_project`**: Call functions or use modules from the library inside the second project.&lt;br /&gt;
5. **Run the app**: Use `mix run` to execute the project.&lt;br /&gt;
&lt;br /&gt;
This way, you can reuse code from one Mix project in another by adding it as a dependency.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==z==&lt;br /&gt;
Overloaded functions are extremely common in Elixir applications. They are&lt;br /&gt;
regularly used for recursive functions and for changing behavior based on&lt;br /&gt;
configuration.&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>http://elixirblocks.com/index.php?title=User:Admin&amp;diff=1879</id>
		<title>User:Admin</title>
		<link rel="alternate" type="text/html" href="http://elixirblocks.com/index.php?title=User:Admin&amp;diff=1879"/>
		<updated>2025-02-20T21:32:20Z</updated>

		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;defmodule AppWeb.Landing do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  alias App.Testbeds&lt;br /&gt;
  alias App.Testbeds.Testbed&lt;br /&gt;
  alias App.Repo  # Ensure to alias Repo&lt;br /&gt;
  import Ecto.Query  # Import Ecto.Query to work with queries&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    # Default to ordering by name&lt;br /&gt;
    testbeds = Repo.all(from(t in Testbed, order_by: t.name))&lt;br /&gt;
&lt;br /&gt;
    # Assign the testbeds to the socket for rendering&lt;br /&gt;
    {:ok, assign(socket, testbeds: testbeds, sort: :name)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    &amp;lt;h1&amp;gt;Hello World! YAY&amp;lt;/h1&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;div&amp;gt;&lt;br /&gt;
      &amp;lt;!-- Buttons to toggle sorting --&amp;gt;&lt;br /&gt;
      &amp;lt;button phx-click=&amp;quot;sort_by_name&amp;quot;&amp;gt;Sort by Name&amp;lt;/button&amp;gt;&lt;br /&gt;
      &amp;lt;button phx-click=&amp;quot;sort_by_updated_at&amp;quot;&amp;gt;Sort by Updated By&amp;lt;/button&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;ul&amp;gt;&lt;br /&gt;
      &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
        &amp;lt;li&amp;gt;&amp;lt;%= testbed.name %&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;% end %&amp;gt;&lt;br /&gt;
    &amp;lt;/ul&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;sort_by_name&amp;quot;, _params, socket) do&lt;br /&gt;
    testbeds = Repo.all(from(t in Testbed, order_by: t.name))&lt;br /&gt;
    {:noreply, assign(socket, testbeds: testbeds, sort: :name)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;sort_by_updated_at&amp;quot;, _params, socket) do&lt;br /&gt;
    testbeds = Repo.all(from(t in Testbed, order_by: t.inserted_at))&lt;br /&gt;
    {:noreply, assign(socket, testbeds: testbeds, sort: :inserted_at)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_______________________________________________________&lt;br /&gt;
&lt;br /&gt;
* Create a form with a post request. &lt;br /&gt;
* Create the route needed for that request&lt;br /&gt;
* Create the controller needed for that route&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Form==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;.form action={~p&amp;quot;/todos&amp;quot;} method=&amp;quot;post&amp;quot; class=&amp;quot;mt-10 space-y-8&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    &amp;lt;label for=&amp;quot;contact_name&amp;quot; class=&amp;quot;block text-sm font-semibold leading-6 text-zinc-800&amp;quot;&amp;gt;&lt;br /&gt;
      Name&lt;br /&gt;
    &amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;input&lt;br /&gt;
      id=&amp;quot;todo&amp;quot;&lt;br /&gt;
      type=&amp;quot;text&amp;quot;&lt;br /&gt;
      name=&amp;quot;todo&amp;quot;&lt;br /&gt;
      class=&amp;quot;mt-2 block w-full rounded-lg text-zinc-900 focus:ring-0 sm:text-sm sm:leading-6 border-zinc-300 focus:border-zinc-400&amp;quot;&lt;br /&gt;
    /&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;button&lt;br /&gt;
    type=&amp;quot;submit&amp;quot;&lt;br /&gt;
    class=&amp;quot;rounded-lg bg-zinc-900 hover:bg-zinc-700 py-2 px-3 text-sm font-semibold leading-6 text-white active:text-white/80&amp;quot;&lt;br /&gt;
  &amp;gt;&lt;br /&gt;
    Save Contact&lt;br /&gt;
  &amp;lt;/button&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/.form&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Controller==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# In your TodoController&lt;br /&gt;
defmodule AppWeb.TodoController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  # Action to handle the form submission (POST request)&lt;br /&gt;
  def create(conn, %{&amp;quot;todo&amp;quot; =&amp;gt; todo_name}) do&lt;br /&gt;
    # Here you can handle the form data (e.g., save it to the database)&lt;br /&gt;
    IO.puts(&amp;quot;Received Todo: #{todo_name}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    # For now, let's just redirect to the home page&lt;br /&gt;
    conn&lt;br /&gt;
    |&amp;gt; put_flash(:info, &amp;quot;Todo saved!&amp;quot;)&lt;br /&gt;
    |&amp;gt; redirect(to: &amp;quot;/&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
________________________________________________________&lt;br /&gt;
&lt;br /&gt;
# CRUD Forms&lt;br /&gt;
&lt;br /&gt;
To understand CRUD forms you will need to understand the following concepts. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Ecto Schema&lt;br /&gt;
* Ecto Context&lt;br /&gt;
* Form Basics&lt;br /&gt;
* form/1&lt;br /&gt;
* simple_form/1&lt;br /&gt;
* changesets&lt;br /&gt;
&lt;br /&gt;
We are not going to go in order. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The Context provides CRUD functions for the chosen data schema. Phoenix contexts define the interface through which other parts of the codebase can interact with the app layer.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_______________________&lt;br /&gt;
* Create routes&lt;br /&gt;
* create page with form (submit get request)&lt;br /&gt;
&lt;br /&gt;
(ecto schema, context, changesets)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_______________________________________________________&lt;br /&gt;
In that case, you really should switch it to prod mode. Instead of doing all that above with the &amp;quot;config/secret.exs&amp;quot; file, create the &amp;quot;.env&amp;quot; in the project root, then add DotenvParser.load_file(&amp;quot;.env&amp;quot;) to &amp;quot;config/runtime.exs&amp;quot; as the first line inside the if config_env() == :prod do. In the .env file, set the DATABASE_URL and SECRET_KEY_BASE. Then run it as MIX_ENV=prod mix phx.server.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def get_titles do&lt;br /&gt;
    urls = [&lt;br /&gt;
      &amp;quot;https://cointelegraph.com/rss&amp;quot;,&lt;br /&gt;
      &amp;quot;https://chaski.huffpost.com/us/auto/vertical/us-news&amp;quot;&lt;br /&gt;
      # Add more RSS feed URLs here&lt;br /&gt;
    ]&lt;br /&gt;
&lt;br /&gt;
    urls&lt;br /&gt;
    |&amp;gt; Enum.map(fn url -&amp;gt;&lt;br /&gt;
      with {:ok, feed} &amp;lt;- ElixirRss.fetch_and_parse(url) do&lt;br /&gt;
        Enum.map(feed.entries, &amp;amp; &amp;amp;1.title)&lt;br /&gt;
      else&lt;br /&gt;
        {:error, reason} -&amp;gt; {:error, reason}&lt;br /&gt;
      end&lt;br /&gt;
    end)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule App do&lt;br /&gt;
&lt;br /&gt;
  def get_titles() do&lt;br /&gt;
    data = [&lt;br /&gt;
      &amp;quot;https://cointelegraph.com/rss&amp;quot;,&lt;br /&gt;
      &amp;quot;https://chaski.huffpost.com/us/auto/vertical/us-news&amp;quot;&lt;br /&gt;
      # Add more RSS feed URLs here&lt;br /&gt;
    ]&lt;br /&gt;
&lt;br /&gt;
    data&lt;br /&gt;
    |&amp;gt; Enum.map(fn url -&amp;gt;&lt;br /&gt;
      case ElixirRss.fetch_and_parse(url) do&lt;br /&gt;
        {:ok, feed} -&amp;gt; feed.entries |&amp;gt; Enum.map(fn entry -&amp;gt; entry end)&lt;br /&gt;
        {:error, reason} -&amp;gt; {:error, reason}&lt;br /&gt;
      end&lt;br /&gt;
    end)&lt;br /&gt;
    |&amp;gt; Enum.map(fn entry_list -&amp;gt;&lt;br /&gt;
      entry_list&lt;br /&gt;
      |&amp;gt; Enum.map(fn entry -&amp;gt; entry.title end)&lt;br /&gt;
    end)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def hello do&lt;br /&gt;
    rss_feeds = [&lt;br /&gt;
      &amp;quot;https://cointelegraph.com/rss&amp;quot;,&lt;br /&gt;
      &amp;quot;https://chaski.huffpost.com/us/auto/vertical/us-news&amp;quot;&lt;br /&gt;
      # Add more RSS feed URLs here&lt;br /&gt;
    ]&lt;br /&gt;
&lt;br /&gt;
    rss_feeds&lt;br /&gt;
    |&amp;gt; Enum.map(fn url -&amp;gt;&lt;br /&gt;
      case ElixirRss.fetch_and_parse(url) do&lt;br /&gt;
        {:ok, feed} -&amp;gt; feed.entries |&amp;gt; Enum.map(fn entry -&amp;gt; entry end)&lt;br /&gt;
        {:error, reason} -&amp;gt; {:error, reason}&lt;br /&gt;
      end&lt;br /&gt;
    end)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    if connected?(socket) do&lt;br /&gt;
      Phoenix.PubSub.subscribe(App.PubSub, &amp;quot;message&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
    {:ok, assign(socket, message_item: &amp;quot;different&amp;quot;)}&lt;br /&gt;
  end&lt;br /&gt;
  def handle_info({:pubsub_transmission, text}, socket) do&lt;br /&gt;
    IO.inspect &amp;quot;pub sub working&amp;quot;&lt;br /&gt;
    {:noreply, assign(socket, message_item: text)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def loop(data) do&lt;br /&gt;
     IO.inspect data&lt;br /&gt;
     if data &amp;gt; 0 do&lt;br /&gt;
      IO.inspect &amp;quot;notify&amp;quot;&lt;br /&gt;
      # run code to compare files, loop. If different run pubsub code below&lt;br /&gt;
      :timer.sleep(2000)&lt;br /&gt;
      loop(data-1)&lt;br /&gt;
&lt;br /&gt;
     end&lt;br /&gt;
     if data &amp;lt;= 0 do&lt;br /&gt;
&lt;br /&gt;
      Phoenix.PubSub.broadcast(App.PubSub, &amp;quot;message&amp;quot;, {:pubsub_transmission, &amp;quot;data&amp;quot;})&lt;br /&gt;
      &amp;quot;done&amp;quot;&lt;br /&gt;
     end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;change-text&amp;quot;, _params, socket) do&lt;br /&gt;
    spawn(fn -&amp;gt; loop(3) end)&lt;br /&gt;
    {:noreply, assign(socket, message_item: &amp;quot;START&amp;quot; )}&lt;br /&gt;
  end&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
&lt;br /&gt;
    # AppWeb.PageLive.loop(&amp;quot;xxx&amp;quot;)&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    SANDBOX&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;.button phx-click=&amp;quot;change-text&amp;quot; value={@message_item}&amp;gt;CLICK ME&amp;lt;/.button&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;%= @message_item %&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
elixir :   1.16.2&lt;br /&gt;
&lt;br /&gt;
Erl:   20&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# PostGres&lt;br /&gt;
Created Saturday 18 February 2023&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Launch [PostGres](#PostGres) from Terminal&lt;br /&gt;
------------------------------------------&lt;br /&gt;
sudo -u postgres psql&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Set User Permission&lt;br /&gt;
-------------------&lt;br /&gt;
&amp;lt;https://commandprompt.com/education/how-to-create-a-superuser-in-postgresql/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ALTER USER user_name WITH PASSWORD 'new_password';&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Run Post Gres Commands&lt;br /&gt;
----------------------&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
sudo -i -u postgres&lt;br /&gt;
psql&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Create and Delete Database&lt;br /&gt;
&lt;br /&gt;
CREATE DATABASE name;&lt;br /&gt;
DROP DATABASE name;&lt;br /&gt;
## View user list&lt;br /&gt;
&lt;br /&gt;
\du&lt;br /&gt;
&lt;br /&gt;
 View all databases&lt;br /&gt;
&lt;br /&gt;
postgres=# \l&lt;br /&gt;
&lt;br /&gt;
 Change databases&lt;br /&gt;
&lt;br /&gt;
postgres=# \c    name-of-database&lt;br /&gt;
&lt;br /&gt;
View Tables&lt;br /&gt;
&lt;br /&gt;
After you change databases and are selected on one of them do this:&lt;br /&gt;
&lt;br /&gt;
\dt&lt;br /&gt;
&lt;br /&gt;
SELECT * FROM mytablename;&lt;br /&gt;
&lt;br /&gt;
EMPTY TABLE&lt;br /&gt;
DELETE FROM name-of-table&lt;br /&gt;
&lt;br /&gt;
CREATE TABLE&lt;br /&gt;
&lt;br /&gt;
CREATE TABLE table_name(&lt;br /&gt;
   column1 datatype,&lt;br /&gt;
   column2 datatype,&lt;br /&gt;
   column3 datatype,&lt;br /&gt;
   .....&lt;br /&gt;
   columnN datatype,&lt;br /&gt;
   PRIMARY KEY( one or more columns )&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
INSERT&lt;br /&gt;
&lt;br /&gt;
INSERT INTO ITEMS(id, name) VALUES(1,'htvjbjbgni');     Strings are single quote&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Roadmap==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.ItemsLive do&lt;br /&gt;
    use AppWeb, :live_view  &lt;br /&gt;
    def mount(_params, _session, socket)  do&lt;br /&gt;
      {:ok, assign(socket, switches: [&amp;quot;grindy&amp;quot;,&amp;quot;sonic&amp;quot;,&amp;quot;ogre&amp;quot;])}  &lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    def handle_event(&amp;quot;run&amp;quot;,_params,socket) do  &lt;br /&gt;
        &lt;br /&gt;
        IO.inspect &amp;quot;DOWNLOAD VIA SSH&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        {:noreply, redirect(socket, to: &amp;quot;/download&amp;quot;)}&lt;br /&gt;
&lt;br /&gt;
    end&lt;br /&gt;
   &lt;br /&gt;
&lt;br /&gt;
    def render(assigns) do&lt;br /&gt;
        &lt;br /&gt;
        ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        &amp;lt;ul&amp;gt;&lt;br /&gt;
        &amp;lt;%= for switch &amp;lt;- @switches do %&amp;gt;&lt;br /&gt;
         &amp;lt;a phx-submit=&amp;quot;click&amp;quot; href=&amp;quot;/download&amp;quot;&amp;gt;  &amp;lt;li&amp;gt; &amp;lt;%= switch %&amp;gt;  &amp;lt;/li&amp;gt; &amp;lt;/a&amp;gt;&lt;br /&gt;
&lt;br /&gt;
        &amp;lt;%end%&amp;gt;&lt;br /&gt;
        &amp;lt;/ul&amp;gt;&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot; &lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Notes==&lt;br /&gt;
List of Switches and the option to select the one needed.&lt;br /&gt;
Button to download JSON file.&lt;br /&gt;
Drag and Drop Palette to upload JSON file.&lt;br /&gt;
&lt;br /&gt;
After JSON file is uploaded a button titled &amp;quot;Make Active&amp;quot; is available.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://medium.com/@fraiha26/pushing-events-to-livecomponents-from-js-hooks-w-phoenix-elixir-d5544d4c3dfa&lt;br /&gt;
&lt;br /&gt;
Changeset notes and forms&lt;br /&gt;
&lt;br /&gt;
NOTE: Use case statements for pattern matching&lt;br /&gt;
____________________________________________&lt;br /&gt;
&lt;br /&gt;
Create a basic &amp;lt;.form&amp;gt;&amp;lt;/form&amp;gt; without error handling&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&amp;lt;.form :let={f} for={@changeset}  action={~p&amp;quot;/items&amp;quot;} &amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;.input field={f[:title]} type=&amp;quot;text&amp;quot; label=&amp;quot;Title&amp;quot; /&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
  &amp;lt;.button&amp;gt;Save Item&amp;lt;/.button&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;/.form&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With error handling looks like this:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;.form :let={f} for={@changeset}  action={~p&amp;quot;/items&amp;quot;} &amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;.error :if={@changeset.action}&amp;gt;&lt;br /&gt;
    Oops, something went wrong! Please check the errors below.&lt;br /&gt;
  &amp;lt;/.error&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;.input field={f[:title]} type=&amp;quot;text&amp;quot; label=&amp;quot;Title&amp;quot; /&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
  &amp;lt;.button&amp;gt;Save Item&amp;lt;/.button&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;/.form&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Create the routes for render and post to endpoint.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The controller for the page render needs to pass in the changeset via ```Items.change_item(%Item{})```&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  def new(conn, _params) do&lt;br /&gt;
    changeset = Items.change_item(%Item{})&lt;br /&gt;
    render(conn, :new, changeset: changeset)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Post route without error handling&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  def create(conn, %{&amp;quot;item&amp;quot; =&amp;gt; item_params}) do&lt;br /&gt;
    case Items.create_item(item_params) do&lt;br /&gt;
      {:ok, item} -&amp;gt;&lt;br /&gt;
        conn&lt;br /&gt;
        |&amp;gt; put_flash(:info, &amp;quot;Item created successfully.&amp;quot;)&lt;br /&gt;
        |&amp;gt; redirect(to: ~p&amp;quot;/items/#{item}&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With error handling&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  def create(conn, %{&amp;quot;item&amp;quot; =&amp;gt; item_params}) do&lt;br /&gt;
    case Items.create_item(item_params) do&lt;br /&gt;
      {:ok, item} -&amp;gt;&lt;br /&gt;
        conn&lt;br /&gt;
        |&amp;gt; put_flash(:info, &amp;quot;Item created successfully.&amp;quot;)&lt;br /&gt;
        |&amp;gt; redirect(to: ~p&amp;quot;/items/#{item}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
      {:error, %Ecto.Changeset{} = changeset} -&amp;gt;&lt;br /&gt;
        render(conn, :new, changeset: changeset)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_____________________________________________&lt;br /&gt;
https://medium.com/@vincentlin/phoenix-very-simple-form-c4b121697fcb&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''home.html.heex'''&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&amp;lt;form action=&amp;quot;/submit&amp;quot; method=&amp;quot;post&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;label for=&amp;quot;name&amp;quot;&amp;gt;Name:&amp;lt;/label&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;input type=&amp;quot;text&amp;quot; id=&amp;quot;name&amp;quot; name=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;_csrf_token&amp;quot; value={@csrf_token} /&amp;gt;&lt;br /&gt;
  &amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Submit&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
page_controller.ex&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.PageController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  def home(conn, _params) do&lt;br /&gt;
    # The home page is often custom made,&lt;br /&gt;
&lt;br /&gt;
    csrf_token = Plug.CSRFProtection.get_csrf_token()&lt;br /&gt;
    render(conn, :home, csrf_token: csrf_token)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def submit(conn, _params) do&lt;br /&gt;
    # The home page is often custom made,&lt;br /&gt;
     IO.inspect(_params)&lt;br /&gt;
     IO.inspect &amp;quot;___________________________&amp;quot;&lt;br /&gt;
    csrf_token = Plug.CSRFProtection.get_csrf_token()&lt;br /&gt;
    render(conn, :home, csrf_token: csrf_token)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
router.ex&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  scope &amp;quot;/&amp;quot;, AppWeb do&lt;br /&gt;
    pipe_through :browser&lt;br /&gt;
    post &amp;quot;/submit&amp;quot;, PageController, :submit&lt;br /&gt;
    get &amp;quot;/&amp;quot;, PageController, :home&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ecto.Adapters.SQL.query(Repo, &amp;quot;select * from artists where id=1&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ecto cheatsheet:  https://hexdocs.pm/ecto/crud.html&lt;br /&gt;
__________________________________________________________________&lt;br /&gt;
Most programming languages give you the ability to set global state by creating globally scoped variables. Elixir does not do this. Instead, Elixir provides a tool called a &amp;quot;processes&amp;quot; to persist  state. Elixir applications are composed of these &amp;quot;processes&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
Processes by themselves are complicated to use, thus Elixir provides abstractions to make working with processes easier. One of these abstractions is called a GenServer.&lt;br /&gt;
&lt;br /&gt;
GenServers are not only used to store state, they are also used to invoke work independent of the main application process. &lt;br /&gt;
&lt;br /&gt;
==Creating a GenServer to Store State==&lt;br /&gt;
&lt;br /&gt;
To Create a GenServer, start by creating a basic Module that ''uses'' the GenServer module (image below)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule App do  &lt;br /&gt;
  use GenServer&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We now need to describe the actions we want to perform. Being that this is used to store state, we will use basic CRUD actions: Create, Read, Update, Delete. To begins, empty functions describing each action is created.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule App do&lt;br /&gt;
   def create do &lt;br /&gt;
&lt;br /&gt;
   end&lt;br /&gt;
   def read do &lt;br /&gt;
&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
   def update do  &lt;br /&gt;
&lt;br /&gt;
   end &lt;br /&gt;
&lt;br /&gt;
   def delete do &lt;br /&gt;
&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==What now?==&lt;br /&gt;
&lt;br /&gt;
To fill in the functions with the appropriate code we must first have a basic understanding of how GenServers are structured.&lt;br /&gt;
&lt;br /&gt;
GenServers are composed of the GenServer module invoking callbacks. The callbacks have built in names that you, as a developer have to use.&lt;br /&gt;
&lt;br /&gt;
These callbacks are named:&lt;br /&gt;
&lt;br /&gt;
* init&lt;br /&gt;
* handle_cast&lt;br /&gt;
* handle_call&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To demonstrate, here is an example :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{:ok, pid} = GenServer.start(ModuleNameOfGenServer, %{})&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above function named &amp;quot;start&amp;quot; calls the function named init in the Module below.&lt;br /&gt;
In GenServer syntax the name of the GenServer functions always invoke callbacks that are determined by the language. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule ModuleNameOfGenServer do&lt;br /&gt;
  # 1&lt;br /&gt;
  def init(state \\ %{}) do&lt;br /&gt;
    {:ok, state}&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is a list of the GenServer functions and their corresponding callbacks.&lt;br /&gt;
&lt;br /&gt;
* GenServer.start/1  --&amp;gt;       init/1&lt;br /&gt;
* GenServer.call/3   --&amp;gt;       def handle_call/3&lt;br /&gt;
* GenServer.cast/2   --&amp;gt;       handle_cast/2&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Start and Call ==&lt;br /&gt;
&lt;br /&gt;
Call and Cast can be used to perform the same operations. The &lt;br /&gt;
&lt;br /&gt;
__________________________________________________________&lt;br /&gt;
Genserver timed events&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule Go do&lt;br /&gt;
  use GenServer&lt;br /&gt;
&lt;br /&gt;
  def go() do&lt;br /&gt;
    GenServer.start_link(__MODULE__, [])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def init(list) do&lt;br /&gt;
    :timer.apply_interval(1000, __MODULE__, :add, [self(), &amp;quot;weeeee&amp;quot;])&lt;br /&gt;
    {:ok, list}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def view(pid) do&lt;br /&gt;
    GenServer.call(pid, :view)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_call(:view, _from, list) do&lt;br /&gt;
    {:reply, list, list}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def add(pid, new_item) do&lt;br /&gt;
    GenServer.call(pid, {:item, new_item})&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_call({:item, new_item}, _from, state) do&lt;br /&gt;
    result = [new_item] ++ state&lt;br /&gt;
    {:reply, result, result}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule ShoppingList do&lt;br /&gt;
  use GenServer&lt;br /&gt;
&lt;br /&gt;
  def start_link() do&lt;br /&gt;
    GenServer.start_link(ShoppingList, [])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def init(list) do&lt;br /&gt;
    {:ok, list}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def view(pid) do&lt;br /&gt;
    GenServer.call(pid, :view)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_call(:view, _from, list) do&lt;br /&gt;
    {:reply, list, list}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def add(pid, new_item) do&lt;br /&gt;
    GenServer.call(pid, {:item, new_item})&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_call({:item, new_item}, _from, state) do&lt;br /&gt;
    result = [new_item] ++ state&lt;br /&gt;
    {:reply, result, result}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://blog.appsignal.com/2018/06/12/elixir-alchemy-deconstructing-genservers.html&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule KeyValue do&lt;br /&gt;
  # 1&lt;br /&gt;
  def init(state \\ %{}) do&lt;br /&gt;
    {:ok, state}&lt;br /&gt;
  end&lt;br /&gt;
 &lt;br /&gt;
  # 2&lt;br /&gt;
  def handle_cast({:put, key, value}, state) do&lt;br /&gt;
    {:noreply, Map.put(state, key, value)}&lt;br /&gt;
  end&lt;br /&gt;
 &lt;br /&gt;
  # 3&lt;br /&gt;
  def handle_call({:get, key}, _from, state) do&lt;br /&gt;
    {:reply, Map.fetch!(state, key), state}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
# {:ok, pid} = GenServer.start(KeyValue, %{})&lt;br /&gt;
# GenServer.cast(pid, {:put, :foo, &amp;quot;bar&amp;quot;})&lt;br /&gt;
# GenServer.call(pid, {:get, :foo})&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Send messages via these functions wrapped in module functions .You can look at these are functions used to fire &amp;quot;GenServer Events&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
* start_link&lt;br /&gt;
* GenServer.call&lt;br /&gt;
* GenServer.cast&lt;br /&gt;
&lt;br /&gt;
The corresponding server functions that reply are:&lt;br /&gt;
&lt;br /&gt;
* init&lt;br /&gt;
* handle__call&lt;br /&gt;
* handle_cast&lt;br /&gt;
* &lt;br /&gt;
&lt;br /&gt;
These can be looked at as &amp;quot;listeners&amp;quot; - in JavaScript parlance. &lt;br /&gt;
__________________________________________&lt;br /&gt;
&lt;br /&gt;
If you have experience with programming languages other than Elixir the idea of GenServers may be very foreign and require a strong context shift to learn. This document is intended to simplify the concept.&lt;br /&gt;
&lt;br /&gt;
* What: GenServers are simply a way to hold state and/or invoke actions based on incoming events. &lt;br /&gt;
* when &lt;br /&gt;
* where&lt;br /&gt;
* why&lt;br /&gt;
* how&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
___________________________________________&lt;br /&gt;
GenServer timer example&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule Timer do&lt;br /&gt;
  use GenServer&lt;br /&gt;
&lt;br /&gt;
  def init(_) do&lt;br /&gt;
    :timer.send_interval(1000, :xyz)&lt;br /&gt;
    {:ok, 0}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_info(:xyz, state) do&lt;br /&gt;
    IO.inspect(state)&lt;br /&gt;
    {:noreply, state + 1}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
[&lt;br /&gt;
   {&lt;br /&gt;
     data:{&lt;br /&gt;
        creationTime,&lt;br /&gt;
        publishDate,&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
     featured:{&lt;br /&gt;
        setAmount,&lt;br /&gt;
        items:[]&lt;br /&gt;
     },&lt;br /&gt;
&lt;br /&gt;
     children:{&lt;br /&gt;
        setAmount,&lt;br /&gt;
        items:[]&lt;br /&gt;
     },&lt;br /&gt;
     links:{&lt;br /&gt;
        setAmount,&lt;br /&gt;
        items:[]&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
jason.encode / jason.decode&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  def run(num) do&lt;br /&gt;
&lt;br /&gt;
    Enum.each(0..99999, fn(_x) -&amp;gt;&lt;br /&gt;
      task = Task.async(fn -&amp;gt; num + _x end)&lt;br /&gt;
    IO.inspect Task.await(task)&lt;br /&gt;
  end)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enum.map(feed.entries, fn x -&amp;gt; %{url: x.url, title: x.title} end)&lt;br /&gt;
&lt;br /&gt;
App is split:&lt;br /&gt;
&lt;br /&gt;
App that captures RSS in UI and lets admin select stories. THere are settings to determine the number of FEATURED,CHILD and LINK stories.&lt;br /&gt;
News categories are horizontal and scrollable.&lt;br /&gt;
This exports a json doc with all RSS data for each story.&lt;br /&gt;
The &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
App that reads the json data. This app creates tables and is the front end.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://stephenbussey.com/tags/elixir.html&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule AppWeb.GroupLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  alias App.TestBeds&lt;br /&gt;
  alias App.Groups&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    {:ok, assign(socket, testbeds: TestBeds.list_testbeds(), groups: Groups.list_groups())}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;select-group&amp;quot;, params, socket)  do  &lt;br /&gt;
     group = App.Groups.get_group!(params[&amp;quot;group-id&amp;quot;])&lt;br /&gt;
     testbed = App.TestBeds.get_test_bed!(params[&amp;quot;testbed_id&amp;quot;])&lt;br /&gt;
     App.TestBeds.update_test_bed(testbed, %{group_id: group.id})&lt;br /&gt;
     {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def updated_groups(testbed_id)  do  &lt;br /&gt;
     testbed = App.TestBeds.get_test_bed!(testbed_id)&lt;br /&gt;
     groups = App.Groups.list_groups&lt;br /&gt;
     tail = Enum.filter(groups, fn(item)-&amp;gt; item.id !== testbed.group_id end)&lt;br /&gt;
     head = Enum.filter(groups, fn(item)-&amp;gt; item.id == testbed.group_id end)&lt;br /&gt;
            |&amp;gt;Enum.at(0)&lt;br /&gt;
    [head | tail]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        &amp;lt;%= for testbed &amp;lt;- Enum.sort_by(@testbeds , &amp;amp;(&amp;quot;#{&amp;amp;1.name}&amp;quot;), :asc)do %&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;grid grid-cols-4 gap-4 p-8 rounded shadow bg-white&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;h2&amp;gt; Name&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;%= testbed.name %&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;h2&amp;gt; Group&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div&amp;gt;&lt;br /&gt;
            &amp;lt;form phx-change=&amp;quot;select-group&amp;quot; name=&amp;quot;testbed_id&amp;quot;  &amp;gt;&lt;br /&gt;
               &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;testbed_id&amp;quot; value={testbed.id}/&amp;gt;&lt;br /&gt;
               &amp;lt;select id=&amp;quot;group-selection&amp;quot;  name=&amp;quot;group-id&amp;quot; class=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;%= for group &amp;lt;- updated_groups(testbed.id) do %&amp;gt;&lt;br /&gt;
                  &amp;lt;%= if group !== nil do %&amp;gt;&lt;br /&gt;
                      &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}&amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
                      &amp;lt;%else%&amp;gt;&lt;br /&gt;
                      &amp;lt;option value= {&amp;quot;Unassigned&amp;quot;}&amp;gt;NONE&amp;lt;/option&amp;gt;&lt;br /&gt;
                  &amp;lt;% end %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
               &amp;lt;/select&amp;gt;&lt;br /&gt;
            &amp;lt;/form&amp;gt;&lt;br /&gt;
          &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
       &amp;lt;% end %&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Developer Notes ==&lt;br /&gt;
===Groups Feature ===&lt;br /&gt;
To complete this feature do these things.&lt;br /&gt;
* Run through the steps in [http://elixirblocks.com/index.php?title=Create_Foreign_Key_Relationship_Between_Ecto_Tables  | this document] to create Group table.&lt;br /&gt;
* Groups have these fields  '''name: string''', '''description: string''' and '''color: string'''  &lt;br /&gt;
* Add unique constraint in migration file: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def change do&lt;br /&gt;
     create unique_index(:groups, [:name])&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Port over Group LiveView code (temporarily placed at discussion page).&lt;br /&gt;
* On completion '''possibly''', create a Group named '''No Group''' and set all Testbeds to it.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
________&lt;br /&gt;
https://blog.appsignal.com/2022/10/11/phoenix-liveview-018-new-special-html-attributes.html&lt;br /&gt;
https://blixtdev.com/whats-new-phoenix-1-7/&lt;br /&gt;
https://github.com/devato/inertia_phoenix&lt;br /&gt;
https://phoenixonrails.com/blog/you-can-stop-using-form-for-in-phoenix&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://samuelmullen.com/articles/phoenix_templates_rendering_and_layouts&lt;br /&gt;
&lt;br /&gt;
WorkFlow of Todo App in Both LiveView and DeadView.&lt;br /&gt;
&lt;br /&gt;
Note:&lt;br /&gt;
&lt;br /&gt;
Create foreign key data.&lt;br /&gt;
Create live view. List all testbeds and form to assign each a group by group-name.&lt;br /&gt;
&lt;br /&gt;
Repeat in dead view&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Mental model and data flows&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
home.html.heex&lt;br /&gt;
&amp;lt;a href=&amp;quot;/data&amp;quot; name=&amp;quot;we are the world&amp;quot; &amp;gt;  click me&amp;lt;/a&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;%= @message %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
page controller&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  def home(conn, _params) do&lt;br /&gt;
    IO.inspect _params&lt;br /&gt;
    render(conn, :home, message: &amp;quot;Hello&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
get &amp;quot;/:yay&amp;quot;, PageController, :index&lt;br /&gt;
&lt;br /&gt;
get &amp;quot;/&amp;quot;, PageController, :index&lt;br /&gt;
&lt;br /&gt;
* Explain control flow of &amp;quot;Dead Views&amp;quot; and the Generator HTML Control flow.&lt;br /&gt;
* Proper Way to use Modal&lt;br /&gt;
* How to give Focus to Fields in Modal (or other forms fields)&lt;br /&gt;
* &lt;br /&gt;
* &lt;br /&gt;
* How to Create Database Seed Data.&lt;br /&gt;
* How to structure code so controller code is in one file and HTML Heex is in another&lt;br /&gt;
* How to Use Generators in a Real World Project&lt;br /&gt;
* How to Work with Database Data via Basic Commands and Custom Change sets.&lt;br /&gt;
* How to Render Database Data to LiveView (via Context Commands).&lt;br /&gt;
* How to Create a Chat using PubSub.&lt;br /&gt;
* How to Create Event Handlers in LiveView&lt;br /&gt;
* How to Create a Dynamic Route from Scratch.&lt;br /&gt;
* How to Use Elixirs Template language&lt;br /&gt;
* How to Work with Modal&lt;br /&gt;
* How to Use CSS From Scratch (Without bundler)&lt;br /&gt;
* How to use JS hooks&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
______________________&lt;br /&gt;
https://studioindie.co/blog/heex-guide/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
get &amp;quot;/&amp;quot;, PageController, :some-atom    #This is the route. some-atom is the controller name&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  def some-atom(conn, _params) do                 # controller name&lt;br /&gt;
    # The home page is often custom made,&lt;br /&gt;
    # so skip the default app layout.&lt;br /&gt;
    render(conn, :some-atom, layout: false)      # :some-atom is template name&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Controllers page_html.ex contains &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageHTML do&lt;br /&gt;
  use AppWeb, :html&lt;br /&gt;
&lt;br /&gt;
  embed_templates &amp;quot;page_html/*&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''page_html''' is the name of the folder in '''Controllers/page_html'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Controllers/page_html/some-atom.html.heex  (this is the template) &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__________________________________________&lt;br /&gt;
Set all association with preload:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  def list_groups do&lt;br /&gt;
    Repo.all(Group)&lt;br /&gt;
     |&amp;gt; Repo.preload([:testbeds])&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Insert Child into Parent ===&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
App.get_group!(2) # arg is id&lt;br /&gt;
|&amp;gt; Ecto.build_assoc(:testbeds)&lt;br /&gt;
|&amp;gt; Repo.insert()&lt;br /&gt;
&lt;br /&gt;
Or&lt;br /&gt;
&lt;br /&gt;
group = App.get_group!(2) # arg is id&lt;br /&gt;
&lt;br /&gt;
testbeds = Ecto.build_assoc(group, :testbeds)&lt;br /&gt;
&lt;br /&gt;
App.Group.create_group(testbeds)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
group = App.Groups.get_group!(1)&lt;br /&gt;
thing = Ecto.build_assoc(group, :testbeds, name: &amp;quot;DUMB&amp;quot;)&lt;br /&gt;
alias App.{Repo}&lt;br /&gt;
Repo.insert(thing)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
avatar = %Avatar{nick_name: &amp;quot;Elixir&amp;quot;, pic_url: &amp;quot;http://elixir-lang.org/images/logo.png&amp;quot;}&lt;br /&gt;
user = %User{name: &amp;quot;John Doe&amp;quot;, email: &amp;quot;john.doe@example.com&amp;quot;, avatar: avatar}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://www.reddit.com/r/elixir/comments/oh318k/is_there_a_way_to_avoid_ectoassociationnotloaded/h4mmcfi/?utm_source=share&amp;amp;utm_medium=web3x&amp;amp;utm_name=web3xcss&amp;amp;utm_term=1&amp;amp;utm_content=share_button&lt;br /&gt;
&lt;br /&gt;
# Create Group Table&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
mix phx.gen.html Groups Group groups name:string  &lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Set the resources / &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
mix ecto.migrate&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For testbeds create a migration file and add this field:   group_id:references:groups&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
def change do&lt;br /&gt;
    alter table(:testbeds) do    # customize to your code&lt;br /&gt;
      add :group_id, references(:groups)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Update Groups Schema (Don't forget alias / has_many)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule App.Groups.Group do&lt;br /&gt;
	use Ecto.Schema&lt;br /&gt;
	import Ecto.Changeset&lt;br /&gt;
	alias App.Testbeds.Testbed   # Alias!&lt;br /&gt;
&lt;br /&gt;
	schema &amp;quot;posts&amp;quot; do&lt;br /&gt;
		field :body, :string&lt;br /&gt;
		field :title, :string&lt;br /&gt;
		has_many :testbeds, Testbed    # Has many&lt;br /&gt;
&lt;br /&gt;
		timestamps()&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	@doc false&lt;br /&gt;
	def changeset(post, attrs) do&lt;br /&gt;
		post&lt;br /&gt;
		|&amp;gt; cast(attrs, [:title, :body])&lt;br /&gt;
		|&amp;gt; validate_required([:title, :body])&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
TESTBEDS Schema&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule App.Testbeds.Testbed do&lt;br /&gt;
  use Ecto.Schema&lt;br /&gt;
  import Ecto.Changeset&lt;br /&gt;
  alias App.Groups.Group      # Alias&lt;br /&gt;
  schema &amp;quot;testbeds&amp;quot; do&lt;br /&gt;
    field :name, :string&lt;br /&gt;
    belongs_to :group, Group    # Belongs to&lt;br /&gt;
    timestamps()&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  @doc false&lt;br /&gt;
  def changeset(testbed, attrs) do&lt;br /&gt;
    testbed&lt;br /&gt;
    |&amp;gt; cast(attrs, [:name])&lt;br /&gt;
    |&amp;gt; validate_required([:name])&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
_____________________________________&lt;br /&gt;
Side notes.&lt;br /&gt;
&lt;br /&gt;
defmodule App.Repo.Migrations.CreateTestbeds do&lt;br /&gt;
  use Ecto.Migration&lt;br /&gt;
&lt;br /&gt;
  def change do&lt;br /&gt;
    create table(:testbeds) do&lt;br /&gt;
      add :name, :string&lt;br /&gt;
      add :group_id, references(:groups, on_delete: :nothing)&lt;br /&gt;
&lt;br /&gt;
      timestamps()&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    create index(:testbeds, [:group_id])&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
________________________________&lt;br /&gt;
&lt;br /&gt;
mix phx.gen.context Comments Comment comments name:string content:text post_id:references:posts&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
mix phx.gen.html Testbeds Testbed testbeds name:string  group_id:references:groups&lt;br /&gt;
&lt;br /&gt;
https://graffino.com/web-development/first-steps-in-elixir-and-phoenix-create-a-blog-prototype&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://blog.logrocket.com/getting-started-ecto-phoenix/&lt;br /&gt;
&lt;br /&gt;
https://serokell.io/blog/ecto-guide-for-beginners&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
mix phx.gen.html Testbeds Testbed testbeds name:string&lt;br /&gt;
&lt;br /&gt;
mix phx.gen.html Groups Group groups name:string&lt;br /&gt;
&lt;br /&gt;
Create migration for &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
mix ecto.gen.migration add_testbed_group_reference&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Migration:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  def change do&lt;br /&gt;
    alter table(:testbeds) do    # customize to your code&lt;br /&gt;
      add :group_id, references(:groups)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Manually Change:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule App.Group do&lt;br /&gt;
  use Ecto.Schema&lt;br /&gt;
&lt;br /&gt;
  schema &amp;quot;groups&amp;quot; do&lt;br /&gt;
    field :title, :string&lt;br /&gt;
    field :tagline, :string&lt;br /&gt;
    has_many :testbeds, App.Testbed&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
testbeds&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule App.Repo.Migrations.AddTextbedGroups do&lt;br /&gt;
  use Ecto.Migration&lt;br /&gt;
&lt;br /&gt;
  def change do&lt;br /&gt;
    create table(:testbeds) do&lt;br /&gt;
      add :name, :string&lt;br /&gt;
      add :group_id, references(:groups)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
# lib/app/testbeds.ex&lt;br /&gt;
&lt;br /&gt;
defmodule App.Testbed do&lt;br /&gt;
  use Ecto.Schema&lt;br /&gt;
&lt;br /&gt;
  schema &amp;quot;testbedss&amp;quot; do&lt;br /&gt;
    field :name, :string&lt;br /&gt;
    belongs_to :group, App.Group&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_____________________&lt;br /&gt;
&lt;br /&gt;
%App.TestBeds.TestBed{&lt;br /&gt;
  __meta__: #Ecto.Schema.Metadata&amp;lt;:loaded, &amp;quot;testbeds&amp;quot;&amp;gt;,&lt;br /&gt;
  id: 1,&lt;br /&gt;
  developer: &amp;quot;None&amp;quot;,&lt;br /&gt;
  name: &amp;quot;sdfsd&amp;quot;,&lt;br /&gt;
  owner: &amp;quot;sdfsddf&amp;quot;,&lt;br /&gt;
  note: &amp;quot;sdsfsddf&amp;quot;,&lt;br /&gt;
  status: &amp;quot;Available&amp;quot;,&lt;br /&gt;
  url: &amp;quot;sdf&amp;quot;,&lt;br /&gt;
  version: &amp;quot;ddf&amp;quot;,&lt;br /&gt;
  manager: &amp;quot;sf&amp;quot;,&lt;br /&gt;
  inserted_at: ~N[2023-08-21 13:45:39],&lt;br /&gt;
  updated_at: ~N[2023-08-21 13:45:44]&lt;br /&gt;
}&lt;br /&gt;
________________________________________________________________---&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.SendLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  &lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    {:ok, socket}&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  def handle_event(&amp;quot;send&amp;quot;, %{&amp;quot;text&amp;quot; =&amp;gt; text}, socket) do&lt;br /&gt;
&lt;br /&gt;
    AppWeb.Endpoint.broadcast(topic, &amp;quot;message&amp;quot;, text)&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  defp topic do&lt;br /&gt;
    &amp;quot;chat&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def render(assigns)do   &lt;br /&gt;
   ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
  &amp;lt;h1&amp;gt;Send Message&amp;lt;/h1&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;form phx-submit=&amp;quot;send&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;text&amp;quot; /&amp;gt;&lt;br /&gt;
    &amp;lt;button type=&amp;quot;submit&amp;quot;&amp;gt;Send&amp;lt;/button&amp;gt;&lt;br /&gt;
  &amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
______________________________________________________________&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.ReceiveLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  &lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    if connected?(socket) do&lt;br /&gt;
      AppWeb.Endpoint.subscribe(topic)&lt;br /&gt;
    end&lt;br /&gt;
    {:ok, assign(socket, messages: &amp;quot;&amp;quot;)}&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def handle_info(%{event: &amp;quot;message&amp;quot;, payload: message}, socket) do&lt;br /&gt;
    IO.inspect message&lt;br /&gt;
    {:noreply, assign(socket, messages: message)}&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  defp topic do&lt;br /&gt;
    &amp;quot;chat&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns)do   &lt;br /&gt;
   ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
  &amp;lt;h1&amp;gt;ChatLive&amp;lt;/h1&amp;gt;&lt;br /&gt;
  &amp;lt;%= @messages %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
______________________________________________________________&lt;br /&gt;
When you hover over a list of items this hook finds items with the same name and sets the opacity of all others to 0. You see all the items similar to the one you are hovering over.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
TestbedVersionHover: {&lt;br /&gt;
			// https://jsfiddle.net/IrvinDominin/7K2Z3/&lt;br /&gt;
            mounted() {&lt;br /&gt;
&lt;br /&gt;
                let rows = document.getElementsByClassName(&amp;quot;testbed-version&amp;quot;)&lt;br /&gt;
                // this.ele = element&lt;br /&gt;
				// rows = this.ele;&lt;br /&gt;
                &lt;br /&gt;
				for (var i = 0; i &amp;lt; rows.length; i++) {&lt;br /&gt;
					rows[i].onmouseenter = function (event) {&lt;br /&gt;
						for (var j = 0; j &amp;lt; rows.length; j++) {&lt;br /&gt;
							let preversion = this.textContent;&lt;br /&gt;
							let version = preversion.slice(0,5)&lt;br /&gt;
							let compareVersion = rows[j].textContent.slice(0,5)&lt;br /&gt;
							if (compareVersion === version) continue&lt;br /&gt;
							rows[j].className += &amp;quot; other&amp;quot;;&lt;br /&gt;
						}&lt;br /&gt;
					};&lt;br /&gt;
				&lt;br /&gt;
					rows[i].onmouseleave = function (event) {&lt;br /&gt;
						var hovers = document.getElementsByClassName('other');&lt;br /&gt;
						var len = hovers.length;&lt;br /&gt;
						for (var j = 0; j &amp;lt; len; j++) {&lt;br /&gt;
							hovers[0].className = hovers[0].className.replace(/\sother(\s|$)/, '');&lt;br /&gt;
						}&lt;br /&gt;
					};&lt;br /&gt;
				}&lt;br /&gt;
&lt;br /&gt;
                // this.ele.addEventListener(&amp;quot;click&amp;quot;, (e) =&amp;gt; {&lt;br /&gt;
                //     console.log(e.target)&lt;br /&gt;
                    &lt;br /&gt;
                // });&lt;br /&gt;
&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* How to Create Database Seed Data.&lt;br /&gt;
* How to structure code so controller code is in one file and HTML Heex is in another&lt;br /&gt;
* How to Use Generators in a Real World Project&lt;br /&gt;
* How to Work with Database Data via Basic Commands and Custom Change sets.&lt;br /&gt;
* How to Render Database Data to LiveView (via Context Commands).&lt;br /&gt;
* How to Create a Chat using PubSub.&lt;br /&gt;
* How to Create Event Handlers in LiveView&lt;br /&gt;
* How to Create a Dynamic Route from Scratch.&lt;br /&gt;
* How to Use Elixirs Template language&lt;br /&gt;
* How to Work with Modal&lt;br /&gt;
* How to Use CSS From Scratch (Without bundler)&lt;br /&gt;
* How to use JS hooks&lt;br /&gt;
* Dissect Table Component and Update it to Order List in Reverse.&lt;br /&gt;
&lt;br /&gt;
Selenium&lt;br /&gt;
https://www.builder.io/blog/debug-nodejs&lt;br /&gt;
&lt;br /&gt;
https://marketplace.visualstudio.com/items?itemName=ms-vscode.live-server#running-the-extension&lt;br /&gt;
&lt;br /&gt;
This was added recently (see microsoft/vscode#109276).&lt;br /&gt;
    1. Open the palette (Ctrl + Shift + P)&lt;br /&gt;
    2. Select &amp;quot;Simple Browser: Preview&amp;quot;&lt;br /&gt;
    3. Enter web address&lt;br /&gt;
&lt;br /&gt;
_______________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
const {By, Key, Builder} = require(&amp;quot;selenium-webdriver&amp;quot;);&lt;br /&gt;
const assert = require(&amp;quot;assert&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
require(&amp;quot;chromedriver&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
async function test_case(){&lt;br /&gt;
  let driver = await new Builder().forBrowser(&amp;quot;chrome&amp;quot;).build();&lt;br /&gt;
  await driver.get(&amp;quot;sie&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  await driver.findElement(By.name('password')).clear();&lt;br /&gt;
  await driver.findElement(By.name('identification')).clear();&lt;br /&gt;
  await driver.findElement(By.name('identification')).sendKeys(&amp;quot;bill&amp;quot;);&lt;br /&gt;
  await driver.findElement(By.name('password')).sendKeys(&amp;quot;password&amp;quot;, Key.RETURN);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 setTimeout(()=&amp;gt;{&lt;br /&gt;
   driver.findElement(By.className(&amp;quot;req_lan_license&amp;quot;)).click();&lt;br /&gt;
 },5000)&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageLive do &lt;br /&gt;
&lt;br /&gt;
  use AppWeb, :live_view  &lt;br /&gt;
  alias App.Testbeds &lt;br /&gt;
  def mount(_params, _session, socket)do   &lt;br /&gt;
     {:ok, assign(socket, testbeds: Testbeds.list_testbeds())}   &lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
    def button_event(&amp;quot;invoke_editing&amp;quot;) do&lt;br /&gt;
    %JS{}&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;active&amp;quot;, to: &amp;quot;#editing_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#editing_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#preview_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;active&amp;quot;, to: &amp;quot;#preview_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;active&amp;quot;, to: &amp;quot;#preview&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#preview&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#editing&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;active&amp;quot;, to: &amp;quot;#editing&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def button_event(&amp;quot;invoke_preview&amp;quot;) do&lt;br /&gt;
    %JS{}&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;active&amp;quot;, to: &amp;quot;#preview_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#preview_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#editing_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;active&amp;quot;, to: &amp;quot;#editing_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;active&amp;quot;, to: &amp;quot;#editing&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#editing&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#preview&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;active&amp;quot;, to: &amp;quot;#preview&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;send&amp;quot;, params, socket) do&lt;br /&gt;
    hide_modal(&amp;quot;notes-modal-0&amp;quot;)&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do  &lt;br /&gt;
     ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
		&amp;lt;.modal id={&amp;quot;notes-modal-#{testbed.id}&amp;quot;}&amp;gt;&lt;br /&gt;
		    &amp;lt;.button phx-click={button_event(&amp;quot;invoke_editing&amp;quot;)} id=&amp;quot;editing_button&amp;quot; class=&amp;quot;hidden&amp;quot;&amp;gt;&lt;br /&gt;
		      Preview&lt;br /&gt;
		    &amp;lt;/.button&amp;gt;&lt;br /&gt;
		    &amp;lt;.button phx-click={button_event(&amp;quot;invoke_preview&amp;quot;)} id=&amp;quot;preview_button&amp;quot;&amp;gt;&lt;br /&gt;
		      Edit Me&lt;br /&gt;
		    &amp;lt;/.button&amp;gt;&lt;br /&gt;
		    &amp;lt;div id=&amp;quot;editing&amp;quot;&amp;gt; PREVIEWING THE WORK&amp;lt;/div&amp;gt;&lt;br /&gt;
		    &amp;lt;form phx-submit = &amp;quot;send&amp;quot;   id=&amp;quot;preview&amp;quot; class=&amp;quot;hidden&amp;quot;&amp;gt;&lt;br /&gt;
		      &amp;lt;textarea value = {testbed.note}&amp;gt;&amp;lt;/textarea&amp;gt;&lt;br /&gt;
		      &amp;lt;.button type=&amp;quot;submit&amp;quot; phx-click={hide_modal(&amp;quot;notes-modal-#{testbed.id}&amp;quot;)}&amp;gt;SAVE WORK&amp;lt;/.button&amp;gt;&lt;br /&gt;
		    &amp;lt;/form&amp;gt;&lt;br /&gt;
		&amp;lt;/.modal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;%= if testbed.note do %&amp;gt;&lt;br /&gt;
      &amp;lt;div phx-click={show_modal(&amp;quot;notes-modal-#{testbed.id}&amp;quot;)}&amp;gt;READ ME  ...&amp;lt;%= testbed.note %&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
	   &lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
       &lt;br /&gt;
      &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
import {HfInference} from &amp;quot;@huggingface/inference&amp;quot;;&lt;br /&gt;
import dotenv from &amp;quot;dotenv&amp;quot;;&lt;br /&gt;
dotenv.config()&lt;br /&gt;
&lt;br /&gt;
const HF_ACCESS_TOKEN = process.env.HF_ACCESS_TOKEN&lt;br /&gt;
&lt;br /&gt;
const hf = new HfInference(HF_ACCESS_TOKEN);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*______Uncomment for this example______________________&lt;br /&gt;
&lt;br /&gt;
const model = &amp;quot;nlpconnect/vit-gpt2-image-captioning&amp;quot;;&lt;br /&gt;
const imageURL = &amp;quot;https://i.imgur.com/lTvb7Et.png&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
const response = await fetch(imageURL);&lt;br /&gt;
const imageBlob = await response.blob();&lt;br /&gt;
&lt;br /&gt;
const result  = await hf.imageToText({&lt;br /&gt;
	data: imageBlob,&lt;br /&gt;
	model: model,&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
_______________________________________________________*/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*________Another example ___________________*/&lt;br /&gt;
&lt;br /&gt;
const result = await hf.summarization({&lt;br /&gt;
	model: 'facebook/bart-large-cnn',&lt;br /&gt;
	inputs: &amp;quot;The role of a dumb man is to get smarter oogy bookie boo&amp;quot;,&lt;br /&gt;
	parameters:{&lt;br /&gt;
		max_length: 100&lt;br /&gt;
	}&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
console.log(result);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
________________________________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://fly.io/phoenix-files/sdeb-toggling-element/&lt;br /&gt;
https://www.youtube.com/watch?v=vBgZvQapqhs&lt;br /&gt;
&lt;br /&gt;
https://blog.testdouble.com/posts/2022-11-28-how-to-use-javascript-with-phoenix-liveview/&lt;br /&gt;
&lt;br /&gt;
https://hexdocs.pm/phoenix_live_view/0.19.3/Phoenix.Component.html&lt;br /&gt;
_______________________________________&lt;br /&gt;
https://www.smashingmagazine.com/2011/10/quick-look-math-animations-javascript/&lt;br /&gt;
* Depth first traversal&lt;br /&gt;
* Breadth first traversal&lt;br /&gt;
&lt;br /&gt;
https://dev.to/codesphere/10-algorithms-every-developer-should-learn-3lnm&lt;br /&gt;
&lt;br /&gt;
https://www.youtube.com/watch?v=fPz40W9mfCg&lt;br /&gt;
&lt;br /&gt;
__________________________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.GroupLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  alias App.TestBeds&lt;br /&gt;
  alias App.Groups&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    {:ok, assign(socket, testbeds: TestBeds.list_testbeds(), groups: Groups.list_groups())}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;select-group&amp;quot;, params, socket)  do  &lt;br /&gt;
         &lt;br /&gt;
       IO.inspect params&lt;br /&gt;
       {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div class=&amp;quot;grid grid-columns-2 grid-flow-col gap-4&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;column-1&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;%= testbed.name %&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;column-2&amp;quot;&amp;gt;    &lt;br /&gt;
            &amp;lt;form phx-change=&amp;quot;select-group&amp;quot;  &amp;gt;&lt;br /&gt;
               &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;testbed_id&amp;quot; value={testbed.id}/&amp;gt;&lt;br /&gt;
               &amp;lt;select id=&amp;quot;group-selection&amp;quot;  name=&amp;quot;group-id&amp;quot; &amp;gt;&lt;br /&gt;
                &amp;lt;%= for group &amp;lt;- @groups do %&amp;gt;&lt;br /&gt;
                  &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}  &amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
               &amp;lt;/select&amp;gt;&lt;br /&gt;
            &amp;lt;/form&amp;gt;&lt;br /&gt;
         &amp;lt;/div&amp;gt;&lt;br /&gt;
       &amp;lt;% end %&amp;gt;&lt;br /&gt;
   &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
____________________________&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.GroupLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  alias App.TestBeds&lt;br /&gt;
  alias App.Groups&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
&lt;br /&gt;
    {:ok, assign(socket, testbeds: TestBeds.list_testbeds(), groups: Groups.list_groups(), messages: [])}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;select-group&amp;quot;, params, socket)  do  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
      group = App.Groups.get_group!(params[&amp;quot;group-id&amp;quot;])&lt;br /&gt;
       # IO.inspect group&lt;br /&gt;
       testbed = App.TestBeds.get_test_bed!(params[&amp;quot;testbed_id&amp;quot;])&lt;br /&gt;
     &lt;br /&gt;
       App.TestBeds.update_test_bed(testbed, %{group_id: group.id})&lt;br /&gt;
         &lt;br /&gt;
    &lt;br /&gt;
       {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def updated_groups(testbed_id)  do  &lt;br /&gt;
       groups = App.Groups.list_groups&lt;br /&gt;
       tail = Enum.filter(groups, fn(item)-&amp;gt; item.id !== testbed_id end)&lt;br /&gt;
       head = Enum.filter(groups, fn(item)-&amp;gt; item.id == testbed_id end)&lt;br /&gt;
              |&amp;gt;Enum.at(0)&lt;br /&gt;
     [head | tail]&lt;br /&gt;
         &lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
 # def handle_event(&amp;quot;groups&amp;quot;, params, socket)do  &lt;br /&gt;
 #       selected_testbed = %{name: &amp;quot;my testbed name&amp;quot;, id: 3}&lt;br /&gt;
 #       groups = App.Groups.list_groups&lt;br /&gt;
 #       tail = Enum.filter(groups, fn(item)-&amp;gt; item.id !== selected_testbed.id end)&lt;br /&gt;
 #       head = Enum.filter(groups, fn(item)-&amp;gt; item.id == selected_testbed.id end)&lt;br /&gt;
 #              |&amp;gt;Enum.at(0)&lt;br /&gt;
         &lt;br /&gt;
 &lt;br /&gt;
 #       # result = Enum.filter([1, 2, 3], fn x -&amp;gt; x.id !== 1 end)&lt;br /&gt;
 #      IO.inspect [head | tail]&lt;br /&gt;
         &lt;br /&gt;
 #      #&lt;br /&gt;
 #      {:noreply, socket, assigns.message:}&lt;br /&gt;
 #  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    &lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
       &amp;lt;%!-- &amp;lt;div phx-click = &amp;quot;groups&amp;quot;&amp;gt;CLICK ME&amp;lt;/div&amp;gt; --%&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;grid grid-cols-4 gap-4 p-8 rounded shadow bg-white&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;h2&amp;gt; Name&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;%= testbed.name %&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;h2&amp;gt; Group&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;form phx-change=&amp;quot;select-group&amp;quot; name=&amp;quot;testbed_id&amp;quot;  &amp;gt;&lt;br /&gt;
               &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;testbed_id&amp;quot; value={testbed.id}/&amp;gt;&lt;br /&gt;
               &amp;lt;select id=&amp;quot;group-selection&amp;quot;  name=&amp;quot;group-id&amp;quot; class=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
                &amp;lt;%= for group &amp;lt;- updated_groups(testbed.id) do %&amp;gt;&lt;br /&gt;
                  &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}  &amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
                  &amp;lt;!-- Write code to reorder with testbed.group_id matching group_id --&amp;gt;&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
               &amp;lt;/select&amp;gt;&lt;br /&gt;
            &amp;lt;/form&amp;gt;&lt;br /&gt;
          &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
       &amp;lt;% end %&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_____________________________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
   use AppWeb, :live_view  &lt;br /&gt;
     alias App.Testbeds&lt;br /&gt;
  alias App.Groups&lt;br /&gt;
   def mount(_params, _session, socket)  do&lt;br /&gt;
	     {:ok, assign(socket, testbeds: Testbeds.list_testbeds(), groups: Groups.list_groups())}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
   def handle_event(&amp;quot;select-group&amp;quot;, params, socket)  do  &lt;br /&gt;
       group = App.Groups.get_group!(params[&amp;quot;group-id&amp;quot;])&lt;br /&gt;
       testbed = App.Testbeds.get_testbed!(params[&amp;quot;testbed_id&amp;quot;])&lt;br /&gt;
       result = App.Testbeds.update_testbed(testbed, %{group_id: group.id})&lt;br /&gt;
       IO.inspect result&lt;br /&gt;
      &lt;br /&gt;
       {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
    def updated_groups(testbed_id)  do  &lt;br /&gt;
       testbed = App.Testbeds.get_testbed!(testbed_id)&lt;br /&gt;
       groups = App.Groups.list_groups&lt;br /&gt;
       tail = Enum.filter(groups, fn(item)-&amp;gt; item.id !== testbed.group_id end)&lt;br /&gt;
       head = Enum.filter(groups, fn(item)-&amp;gt; item.id == testbed.group_id end)&lt;br /&gt;
              |&amp;gt;Enum.at(0)&lt;br /&gt;
 &lt;br /&gt;
       [head | tail]&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    &lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;grid grid-cols-4 gap-4 p-8 rounded shadow bg-white&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;h2&amp;gt; Name&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;%= testbed.name %&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;h2&amp;gt; Group&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;form phx-change=&amp;quot;select-group&amp;quot; name=&amp;quot;testbed_id&amp;quot;  &amp;gt;&lt;br /&gt;
               &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;testbed_id&amp;quot; value={testbed.id}/&amp;gt;&lt;br /&gt;
               &amp;lt;select id=&amp;quot;group-selection&amp;quot;  name=&amp;quot;group-id&amp;quot; class=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
                &amp;lt;%= for group &amp;lt;- updated_groups(testbed.id) do %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
                  &amp;lt;%!-- &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}&amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt; --%&amp;gt;&lt;br /&gt;
                  &amp;lt;!-- Write code to reorder with testbed.group_id matching group_id --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
                  &amp;lt;%= if group !== nil do %&amp;gt;&lt;br /&gt;
                      &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}&amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
       &lt;br /&gt;
                  &amp;lt;% end %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
               &amp;lt;/select&amp;gt;&lt;br /&gt;
            &amp;lt;/form&amp;gt;&lt;br /&gt;
          &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
       &amp;lt;% end %&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  has_many :testbeds, TestBed, on_delete: :restrict   # Has many&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://elixirforum.com/t/ecto-has-many-on-delete-protect/49550&lt;br /&gt;
&lt;br /&gt;
https://hexdocs.pm/ecto/Ecto.Changeset.html#unique_constraint/3&lt;br /&gt;
&lt;br /&gt;
____________________________________________________________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== How to Create a Mix Project and Use It in Another Mix Project ==&lt;br /&gt;
&lt;br /&gt;
To create and use a **Mix project** inside another **Mix project** in Elixir, follow the steps below:&lt;br /&gt;
&lt;br /&gt;
=== 1. Create a New Mix Project ===&lt;br /&gt;
&lt;br /&gt;
First, you need to create a new Mix project. Let's call this project `library_project`. Run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mix new library_project --module LibraryProject&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will create a new Elixir Mix project named `library_project`. The `--module` flag specifies the name of the module that will be created (in this case `LibraryProject`).&lt;br /&gt;
&lt;br /&gt;
The directory structure of `library_project` will look like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
library_project/&lt;br /&gt;
  |_ lib/&lt;br /&gt;
      |_ library_project.ex&lt;br /&gt;
  |_ mix.exs&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can then add some basic functionality inside the `library_project/lib/library_project.ex` file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule LibraryProject do&lt;br /&gt;
  def hello do&lt;br /&gt;
    IO.puts &amp;quot;Hello from LibraryProject!&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now, `library_project` is ready to be used by another Mix project.&lt;br /&gt;
&lt;br /&gt;
=== 2. Create a Second Mix Project ===&lt;br /&gt;
&lt;br /&gt;
Next, create the second Mix project where you want to use `library_project`. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mix new app_project --module AppProject&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will create another Elixir project called `app_project`.&lt;br /&gt;
&lt;br /&gt;
The directory structure for this project will look like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
app_project/&lt;br /&gt;
  |_ lib/&lt;br /&gt;
      |_ app_project.ex&lt;br /&gt;
  |_ mix.exs&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 3. Add `library_project` as a Dependency in `app_project` ===&lt;br /&gt;
&lt;br /&gt;
Now, you want to make `library_project` available in `app_project`. There are two main ways to do this:&lt;br /&gt;
&lt;br /&gt;
==== Option 1: Local Dependency (via `path`) ====&lt;br /&gt;
&lt;br /&gt;
If `library_project` is a local project (i.e., it's stored in a different directory), you can add it to the `mix.exs` of `app_project` as a local dependency by specifying the path to `library_project`.&lt;br /&gt;
&lt;br /&gt;
Edit the `mix.exs` of `app_project`:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule AppProject.MixProject do&lt;br /&gt;
  use Mix.Project&lt;br /&gt;
&lt;br /&gt;
  def project do&lt;br /&gt;
    [&lt;br /&gt;
      app: :app_project,&lt;br /&gt;
      version: &amp;quot;0.1.0&amp;quot;,&lt;br /&gt;
      elixir: &amp;quot;~&amp;gt; 1.14&amp;quot;,&lt;br /&gt;
      start_permanent: Mix.env() == :prod,&lt;br /&gt;
      deps: deps()&lt;br /&gt;
    ]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  defp deps do&lt;br /&gt;
    [&lt;br /&gt;
      {:library_project, path: &amp;quot;../library_project&amp;quot;}  # Add the local dependency&lt;br /&gt;
    ]&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here, `{:library_project, path: &amp;quot;../library_project&amp;quot;}` tells Mix to use the local `library_project` located in the `../library_project` directory (relative to `app_project`).&lt;br /&gt;
&lt;br /&gt;
After updating the `mix.exs`, run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd app_project&lt;br /&gt;
mix deps.get&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will fetch the dependency and compile `library_project`.&lt;br /&gt;
&lt;br /&gt;
==== Option 2: Publish and Fetch as a Hex Package ====&lt;br /&gt;
&lt;br /&gt;
If you want to use `library_project` as a package in another project (for example, by publishing it to **Hex.pm**, Elixir’s package manager), you need to publish it to Hex and then add it as a dependency.&lt;br /&gt;
&lt;br /&gt;
1. Publish `library_project` to Hex (if it's public or for your private use).&lt;br /&gt;
2. Add `library_project` to your `app_project`’s `mix.exs` dependencies:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defp deps do&lt;br /&gt;
  [&lt;br /&gt;
    {:library_project, &amp;quot;~&amp;gt; 0.1.0&amp;quot;}  # Specify the published version from Hex&lt;br /&gt;
  ]&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Run `mix deps.get` to fetch the package from Hex.&lt;br /&gt;
&lt;br /&gt;
=== 4. Use `library_project` in `app_project` ===&lt;br /&gt;
&lt;br /&gt;
Now, you can use the functionality from `library_project` inside your `app_project`. For example, in `app_project/lib/app_project.ex`, you can call the function from `library_project`:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule AppProject do&lt;br /&gt;
  def start do&lt;br /&gt;
    IO.puts &amp;quot;Starting app_project!&amp;quot;&lt;br /&gt;
    LibraryProject.hello()  # Call the function from the library_project&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 5. Run the App ===&lt;br /&gt;
&lt;br /&gt;
Finally, you can run your `app_project`:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd app_project&lt;br /&gt;
mix run -e &amp;quot;AppProject.start()&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will print:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Starting app_project!&lt;br /&gt;
Hello from LibraryProject!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Recap of the Process ==&lt;br /&gt;
1. **Create the `library_project`**: Use `mix new` to generate a library project.&lt;br /&gt;
2. **Create the `app_project`**: Create the second project where you will use the library.&lt;br /&gt;
3. **Add the `library_project` as a dependency**:&lt;br /&gt;
   - Use the `path` option to point to the local project or publish it to Hex for public access.&lt;br /&gt;
4. **Use the `library_project` in the `app_project`**: Call functions or use modules from the library inside the second project.&lt;br /&gt;
5. **Run the app**: Use `mix run` to execute the project.&lt;br /&gt;
&lt;br /&gt;
This way, you can reuse code from one Mix project in another by adding it as a dependency.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==z==&lt;br /&gt;
Overloaded functions are extremely common in Elixir applications. They are&lt;br /&gt;
regularly used for recursive functions and for changing behavior based on&lt;br /&gt;
configuration.&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>http://elixirblocks.com/index.php?title=Understanding_Forms_and_Changesets&amp;diff=1878</id>
		<title>Understanding Forms and Changesets</title>
		<link rel="alternate" type="text/html" href="http://elixirblocks.com/index.php?title=Understanding_Forms_and_Changesets&amp;diff=1878"/>
		<updated>2024-12-29T10:30:48Z</updated>

		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{In_progress}}&lt;br /&gt;
&lt;br /&gt;
This tutorial assumes you have a basic understanding of Elixir and that you have explored Phoenix. It also assumes that you understand HTML forms. &lt;br /&gt;
&lt;br /&gt;
The methodology of this tutorial includes converting a conventional HTML form into a Phoenix template that uses Elixir to communicate with back end code. You also learn how changesets integrate with controllers. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Getting Started=&lt;br /&gt;
&lt;br /&gt;
To begin, create a new empty Phoenix app named app. If you do not know how to do that follow this tutorial:&lt;br /&gt;
&lt;br /&gt;
[[How to Create an Empty Phoenix Application|How to Create an Empty Phoenix Application]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Creating an HTML Form and Post Request==&lt;br /&gt;
&lt;br /&gt;
In the [[router]] create these two routes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  scope &amp;quot;/&amp;quot;, AppWeb do&lt;br /&gt;
    pipe_through :browser&lt;br /&gt;
&lt;br /&gt;
    get &amp;quot;/&amp;quot;, PageController, :index       # First route&lt;br /&gt;
    post &amp;quot;/create&amp;quot;, PageController, :new  # Second route&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Place the code below in a file named  '''page_controller.ex'''. Place the file in the controller directory.&lt;br /&gt;
&lt;br /&gt;
'''app/lib/app_web/controllers/page_controller.ex'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.PageController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  def index(conn, params) do&lt;br /&gt;
    IO.inspect params&lt;br /&gt;
    csrf_token = Plug.CSRFProtection.get_csrf_token()&lt;br /&gt;
    render(conn, :index, data: &amp;quot;Hello World&amp;quot;,form: %{},csrf_token: csrf_token)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def new(conn, params) do&lt;br /&gt;
      IO.inspect params&lt;br /&gt;
      redirect(conn, to: &amp;quot;/&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In the controllers directory create a file named '''page_html.ex'''&lt;br /&gt;
&lt;br /&gt;
In this file, copy this code.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageHTML do&lt;br /&gt;
  use AppWeb, :html&lt;br /&gt;
&lt;br /&gt;
  embed_templates &amp;quot;page_html/*&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In the controllers directory create another directory named '''page_html''' (technically you can place this directory outside the controllers and it will still work).&lt;br /&gt;
&lt;br /&gt;
'''app/lib/app_web/controllers/page_html'''&lt;br /&gt;
&lt;br /&gt;
This directory will contain heex templates for the PageController.&lt;br /&gt;
&lt;br /&gt;
In the page_html directory place a file named '''index.html.heex'''.&lt;br /&gt;
&lt;br /&gt;
Inside the file copy the following code.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;%=@data%&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;form method=&amp;quot;POST&amp;quot; action=&amp;quot;/create&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;_csrf_token&amp;quot; value={@csrf_token} /&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;example&amp;quot; /&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;submit&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;/form&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Run the server:   mix phx.server&lt;br /&gt;
&lt;br /&gt;
You should see a form field and a submit button with the text &amp;quot;Hello World&amp;quot; above them. Type into the form and submit it, the terminal will display your input. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you replace the form with the built in form helper, you can remove the csrf code. CSRF protection comes built in with the form helper. Delete or comment out the code in index.html.heex and replace it with the code below.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;.form :let={f} action={~p&amp;quot;/create&amp;quot;}&amp;gt;&lt;br /&gt;
    &amp;lt;.input field={f[:x]} name=&amp;quot;submitted-data&amp;quot; /&amp;gt;&lt;br /&gt;
  &amp;lt;/.form&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Delete or comment out the code in page_controller.ex and replace it with the code below.&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  def index(conn, params) do&lt;br /&gt;
    IO.inspect params&lt;br /&gt;
    render(conn, :index, data: &amp;quot;Hello World&amp;quot;,form: %{})&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def new(conn, params) do&lt;br /&gt;
      IO.inspect params&lt;br /&gt;
      redirect(conn, to: &amp;quot;/&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When you run the server and visit the landing page, you should see the page render without error.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Form Changesets===&lt;br /&gt;
Without Changesets we have these two problems:&lt;br /&gt;
&lt;br /&gt;
* We lose what we typed.&lt;br /&gt;
* The app doesn’t tell us what our errors were.&lt;br /&gt;
&lt;br /&gt;
Changesets solve both of these problems.&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>http://elixirblocks.com/index.php?title=How_to_Think_About_Phoenix_Dead_Views&amp;diff=1877</id>
		<title>How to Think About Phoenix Dead Views</title>
		<link rel="alternate" type="text/html" href="http://elixirblocks.com/index.php?title=How_to_Think_About_Phoenix_Dead_Views&amp;diff=1877"/>
		<updated>2024-12-27T09:21:47Z</updated>

		<summary type="html">&lt;p&gt;Admin: Created page with &amp;quot;Each page (resource) has a route.  These routes are assigned a controller and a function from that controller.   In the code below, when a user goes to the &amp;quot;/&amp;quot; route a controller named PageController is found and a function named home is invoked.  Controllers are simply modules and the third argument (in this case named '''home''') is a function on the controller.  &amp;lt;source&amp;gt;   get &amp;quot;/&amp;quot;, PageController, :home &amp;lt;/source&amp;gt;&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Each page (resource) has a route.&lt;br /&gt;
&lt;br /&gt;
These routes are assigned a controller and a function from that controller. &lt;br /&gt;
&lt;br /&gt;
In the code below, when a user goes to the &amp;quot;/&amp;quot; route a controller named PageController is found and a function named home is invoked.&lt;br /&gt;
&lt;br /&gt;
Controllers are simply modules and the third argument (in this case named '''home''') is a function on the controller.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  get &amp;quot;/&amp;quot;, PageController, :home&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>http://elixirblocks.com/index.php?title=Phoenix_Flash_Message&amp;diff=1876</id>
		<title>Phoenix Flash Message</title>
		<link rel="alternate" type="text/html" href="http://elixirblocks.com/index.php?title=Phoenix_Flash_Message&amp;diff=1876"/>
		<updated>2024-12-27T09:12:55Z</updated>

		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In Phoenix the flash message is invoked from the controller.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  def create(conn, %{&amp;quot;doink&amp;quot; =&amp;gt; doink_params}) do&lt;br /&gt;
    case Doinks.create_doink(doink_params) do&lt;br /&gt;
      {:ok, doink} -&amp;gt;&lt;br /&gt;
        conn&lt;br /&gt;
        |&amp;gt; put_flash(:info, &amp;quot;Doink created successfully.&amp;quot;)&lt;br /&gt;
        |&amp;gt; redirect(to: ~p&amp;quot;/doinks/#{doink}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
      {:error, %Ecto.Changeset{} = changeset} -&amp;gt;&lt;br /&gt;
        render(conn, :new, changeset: changeset)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The flash component itself needs to be in the view. For a new instance it defaults to being in the the layout via  app_web/layouts/app.html.heex and its accessible to all controllers.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
    &amp;lt;.flash_group flash={@flash} /&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>http://elixirblocks.com/index.php?title=Phoenix_Flash_Message&amp;diff=1875</id>
		<title>Phoenix Flash Message</title>
		<link rel="alternate" type="text/html" href="http://elixirblocks.com/index.php?title=Phoenix_Flash_Message&amp;diff=1875"/>
		<updated>2024-12-27T09:12:00Z</updated>

		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In Phoenix the flash message is invoked from the controller.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  def create(conn, %{&amp;quot;doink&amp;quot; =&amp;gt; doink_params}) do&lt;br /&gt;
    case Doinks.create_doink(doink_params) do&lt;br /&gt;
      {:ok, doink} -&amp;gt;&lt;br /&gt;
        conn&lt;br /&gt;
        |&amp;gt; put_flash(:info, &amp;quot;Doink created successfully.&amp;quot;)&lt;br /&gt;
        |&amp;gt; redirect(to: ~p&amp;quot;/doinks/#{doink}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
      {:error, %Ecto.Changeset{} = changeset} -&amp;gt;&lt;br /&gt;
        render(conn, :new, changeset: changeset)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The flash component itself needs to be in the view, for a new instance it defaults to being in the the layout via  app_web/layouts/app.html.heex&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
    &amp;lt;.flash_group flash={@flash} /&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>http://elixirblocks.com/index.php?title=Phoenix_Flash_Message&amp;diff=1874</id>
		<title>Phoenix Flash Message</title>
		<link rel="alternate" type="text/html" href="http://elixirblocks.com/index.php?title=Phoenix_Flash_Message&amp;diff=1874"/>
		<updated>2024-12-27T09:11:11Z</updated>

		<summary type="html">&lt;p&gt;Admin: Created page with &amp;quot;In Phoenix the flash message is invoked from the controller.  &amp;lt;source&amp;gt;   def create(conn, %{&amp;quot;doink&amp;quot; =&amp;gt; doink_params}) do     case Doinks.create_doink(doink_params) do       {:ok, doink} -&amp;gt;         conn         |&amp;gt; put_flash(:info, &amp;quot;Doink created successfully.&amp;quot;)         |&amp;gt; redirect(to: ~p&amp;quot;/doinks/#{doink}&amp;quot;)        {:error, %Ecto.Changeset{} = changeset} -&amp;gt;         render(conn, :new, changeset: changeset)     end   end &amp;lt;/source&amp;gt;    The message itself needs to be in the view...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In Phoenix the flash message is invoked from the controller.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  def create(conn, %{&amp;quot;doink&amp;quot; =&amp;gt; doink_params}) do&lt;br /&gt;
    case Doinks.create_doink(doink_params) do&lt;br /&gt;
      {:ok, doink} -&amp;gt;&lt;br /&gt;
        conn&lt;br /&gt;
        |&amp;gt; put_flash(:info, &amp;quot;Doink created successfully.&amp;quot;)&lt;br /&gt;
        |&amp;gt; redirect(to: ~p&amp;quot;/doinks/#{doink}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
      {:error, %Ecto.Changeset{} = changeset} -&amp;gt;&lt;br /&gt;
        render(conn, :new, changeset: changeset)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The message itself needs to be in the view, for a new instance it defaults to being in the the layout via  app_web/layouts/app.html.heex&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
    &amp;lt;.flash_group flash={@flash} /&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>http://elixirblocks.com/index.php?title=User:Admin&amp;diff=1873</id>
		<title>User:Admin</title>
		<link rel="alternate" type="text/html" href="http://elixirblocks.com/index.php?title=User:Admin&amp;diff=1873"/>
		<updated>2024-12-24T03:21:46Z</updated>

		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;_______________________________________________________&lt;br /&gt;
&lt;br /&gt;
* Create a form with a post request. &lt;br /&gt;
* Create the route needed for that request&lt;br /&gt;
* Create the controller needed for that route&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Form==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;.form action={~p&amp;quot;/todos&amp;quot;} method=&amp;quot;post&amp;quot; class=&amp;quot;mt-10 space-y-8&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    &amp;lt;label for=&amp;quot;contact_name&amp;quot; class=&amp;quot;block text-sm font-semibold leading-6 text-zinc-800&amp;quot;&amp;gt;&lt;br /&gt;
      Name&lt;br /&gt;
    &amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;input&lt;br /&gt;
      id=&amp;quot;todo&amp;quot;&lt;br /&gt;
      type=&amp;quot;text&amp;quot;&lt;br /&gt;
      name=&amp;quot;todo&amp;quot;&lt;br /&gt;
      class=&amp;quot;mt-2 block w-full rounded-lg text-zinc-900 focus:ring-0 sm:text-sm sm:leading-6 border-zinc-300 focus:border-zinc-400&amp;quot;&lt;br /&gt;
    /&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;button&lt;br /&gt;
    type=&amp;quot;submit&amp;quot;&lt;br /&gt;
    class=&amp;quot;rounded-lg bg-zinc-900 hover:bg-zinc-700 py-2 px-3 text-sm font-semibold leading-6 text-white active:text-white/80&amp;quot;&lt;br /&gt;
  &amp;gt;&lt;br /&gt;
    Save Contact&lt;br /&gt;
  &amp;lt;/button&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/.form&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Controller==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# In your TodoController&lt;br /&gt;
defmodule AppWeb.TodoController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  # Action to handle the form submission (POST request)&lt;br /&gt;
  def create(conn, %{&amp;quot;todo&amp;quot; =&amp;gt; todo_name}) do&lt;br /&gt;
    # Here you can handle the form data (e.g., save it to the database)&lt;br /&gt;
    IO.puts(&amp;quot;Received Todo: #{todo_name}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    # For now, let's just redirect to the home page&lt;br /&gt;
    conn&lt;br /&gt;
    |&amp;gt; put_flash(:info, &amp;quot;Todo saved!&amp;quot;)&lt;br /&gt;
    |&amp;gt; redirect(to: &amp;quot;/&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
________________________________________________________&lt;br /&gt;
&lt;br /&gt;
# CRUD Forms&lt;br /&gt;
&lt;br /&gt;
To understand CRUD forms you will need to understand the following concepts. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Ecto Schema&lt;br /&gt;
* Ecto Context&lt;br /&gt;
* Form Basics&lt;br /&gt;
* form/1&lt;br /&gt;
* simple_form/1&lt;br /&gt;
* changesets&lt;br /&gt;
&lt;br /&gt;
We are not going to go in order. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The Context provides CRUD functions for the chosen data schema. Phoenix contexts define the interface through which other parts of the codebase can interact with the app layer.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_______________________&lt;br /&gt;
* Create routes&lt;br /&gt;
* create page with form (submit get request)&lt;br /&gt;
&lt;br /&gt;
(ecto schema, context, changesets)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_______________________________________________________&lt;br /&gt;
In that case, you really should switch it to prod mode. Instead of doing all that above with the &amp;quot;config/secret.exs&amp;quot; file, create the &amp;quot;.env&amp;quot; in the project root, then add DotenvParser.load_file(&amp;quot;.env&amp;quot;) to &amp;quot;config/runtime.exs&amp;quot; as the first line inside the if config_env() == :prod do. In the .env file, set the DATABASE_URL and SECRET_KEY_BASE. Then run it as MIX_ENV=prod mix phx.server.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def get_titles do&lt;br /&gt;
    urls = [&lt;br /&gt;
      &amp;quot;https://cointelegraph.com/rss&amp;quot;,&lt;br /&gt;
      &amp;quot;https://chaski.huffpost.com/us/auto/vertical/us-news&amp;quot;&lt;br /&gt;
      # Add more RSS feed URLs here&lt;br /&gt;
    ]&lt;br /&gt;
&lt;br /&gt;
    urls&lt;br /&gt;
    |&amp;gt; Enum.map(fn url -&amp;gt;&lt;br /&gt;
      with {:ok, feed} &amp;lt;- ElixirRss.fetch_and_parse(url) do&lt;br /&gt;
        Enum.map(feed.entries, &amp;amp; &amp;amp;1.title)&lt;br /&gt;
      else&lt;br /&gt;
        {:error, reason} -&amp;gt; {:error, reason}&lt;br /&gt;
      end&lt;br /&gt;
    end)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule App do&lt;br /&gt;
&lt;br /&gt;
  def get_titles() do&lt;br /&gt;
    data = [&lt;br /&gt;
      &amp;quot;https://cointelegraph.com/rss&amp;quot;,&lt;br /&gt;
      &amp;quot;https://chaski.huffpost.com/us/auto/vertical/us-news&amp;quot;&lt;br /&gt;
      # Add more RSS feed URLs here&lt;br /&gt;
    ]&lt;br /&gt;
&lt;br /&gt;
    data&lt;br /&gt;
    |&amp;gt; Enum.map(fn url -&amp;gt;&lt;br /&gt;
      case ElixirRss.fetch_and_parse(url) do&lt;br /&gt;
        {:ok, feed} -&amp;gt; feed.entries |&amp;gt; Enum.map(fn entry -&amp;gt; entry end)&lt;br /&gt;
        {:error, reason} -&amp;gt; {:error, reason}&lt;br /&gt;
      end&lt;br /&gt;
    end)&lt;br /&gt;
    |&amp;gt; Enum.map(fn entry_list -&amp;gt;&lt;br /&gt;
      entry_list&lt;br /&gt;
      |&amp;gt; Enum.map(fn entry -&amp;gt; entry.title end)&lt;br /&gt;
    end)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def hello do&lt;br /&gt;
    rss_feeds = [&lt;br /&gt;
      &amp;quot;https://cointelegraph.com/rss&amp;quot;,&lt;br /&gt;
      &amp;quot;https://chaski.huffpost.com/us/auto/vertical/us-news&amp;quot;&lt;br /&gt;
      # Add more RSS feed URLs here&lt;br /&gt;
    ]&lt;br /&gt;
&lt;br /&gt;
    rss_feeds&lt;br /&gt;
    |&amp;gt; Enum.map(fn url -&amp;gt;&lt;br /&gt;
      case ElixirRss.fetch_and_parse(url) do&lt;br /&gt;
        {:ok, feed} -&amp;gt; feed.entries |&amp;gt; Enum.map(fn entry -&amp;gt; entry end)&lt;br /&gt;
        {:error, reason} -&amp;gt; {:error, reason}&lt;br /&gt;
      end&lt;br /&gt;
    end)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    if connected?(socket) do&lt;br /&gt;
      Phoenix.PubSub.subscribe(App.PubSub, &amp;quot;message&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
    {:ok, assign(socket, message_item: &amp;quot;different&amp;quot;)}&lt;br /&gt;
  end&lt;br /&gt;
  def handle_info({:pubsub_transmission, text}, socket) do&lt;br /&gt;
    IO.inspect &amp;quot;pub sub working&amp;quot;&lt;br /&gt;
    {:noreply, assign(socket, message_item: text)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def loop(data) do&lt;br /&gt;
     IO.inspect data&lt;br /&gt;
     if data &amp;gt; 0 do&lt;br /&gt;
      IO.inspect &amp;quot;notify&amp;quot;&lt;br /&gt;
      # run code to compare files, loop. If different run pubsub code below&lt;br /&gt;
      :timer.sleep(2000)&lt;br /&gt;
      loop(data-1)&lt;br /&gt;
&lt;br /&gt;
     end&lt;br /&gt;
     if data &amp;lt;= 0 do&lt;br /&gt;
&lt;br /&gt;
      Phoenix.PubSub.broadcast(App.PubSub, &amp;quot;message&amp;quot;, {:pubsub_transmission, &amp;quot;data&amp;quot;})&lt;br /&gt;
      &amp;quot;done&amp;quot;&lt;br /&gt;
     end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;change-text&amp;quot;, _params, socket) do&lt;br /&gt;
    spawn(fn -&amp;gt; loop(3) end)&lt;br /&gt;
    {:noreply, assign(socket, message_item: &amp;quot;START&amp;quot; )}&lt;br /&gt;
  end&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
&lt;br /&gt;
    # AppWeb.PageLive.loop(&amp;quot;xxx&amp;quot;)&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    SANDBOX&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;.button phx-click=&amp;quot;change-text&amp;quot; value={@message_item}&amp;gt;CLICK ME&amp;lt;/.button&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;%= @message_item %&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
elixir :   1.16.2&lt;br /&gt;
&lt;br /&gt;
Erl:   20&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# PostGres&lt;br /&gt;
Created Saturday 18 February 2023&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Launch [PostGres](#PostGres) from Terminal&lt;br /&gt;
------------------------------------------&lt;br /&gt;
sudo -u postgres psql&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Set User Permission&lt;br /&gt;
-------------------&lt;br /&gt;
&amp;lt;https://commandprompt.com/education/how-to-create-a-superuser-in-postgresql/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ALTER USER user_name WITH PASSWORD 'new_password';&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Run Post Gres Commands&lt;br /&gt;
----------------------&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
sudo -i -u postgres&lt;br /&gt;
psql&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Create and Delete Database&lt;br /&gt;
&lt;br /&gt;
CREATE DATABASE name;&lt;br /&gt;
DROP DATABASE name;&lt;br /&gt;
## View user list&lt;br /&gt;
&lt;br /&gt;
\du&lt;br /&gt;
&lt;br /&gt;
 View all databases&lt;br /&gt;
&lt;br /&gt;
postgres=# \l&lt;br /&gt;
&lt;br /&gt;
 Change databases&lt;br /&gt;
&lt;br /&gt;
postgres=# \c    name-of-database&lt;br /&gt;
&lt;br /&gt;
View Tables&lt;br /&gt;
&lt;br /&gt;
After you change databases and are selected on one of them do this:&lt;br /&gt;
&lt;br /&gt;
\dt&lt;br /&gt;
&lt;br /&gt;
SELECT * FROM mytablename;&lt;br /&gt;
&lt;br /&gt;
EMPTY TABLE&lt;br /&gt;
DELETE FROM name-of-table&lt;br /&gt;
&lt;br /&gt;
CREATE TABLE&lt;br /&gt;
&lt;br /&gt;
CREATE TABLE table_name(&lt;br /&gt;
   column1 datatype,&lt;br /&gt;
   column2 datatype,&lt;br /&gt;
   column3 datatype,&lt;br /&gt;
   .....&lt;br /&gt;
   columnN datatype,&lt;br /&gt;
   PRIMARY KEY( one or more columns )&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
INSERT&lt;br /&gt;
&lt;br /&gt;
INSERT INTO ITEMS(id, name) VALUES(1,'htvjbjbgni');     Strings are single quote&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Roadmap==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.ItemsLive do&lt;br /&gt;
    use AppWeb, :live_view  &lt;br /&gt;
    def mount(_params, _session, socket)  do&lt;br /&gt;
      {:ok, assign(socket, switches: [&amp;quot;grindy&amp;quot;,&amp;quot;sonic&amp;quot;,&amp;quot;ogre&amp;quot;])}  &lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    def handle_event(&amp;quot;run&amp;quot;,_params,socket) do  &lt;br /&gt;
        &lt;br /&gt;
        IO.inspect &amp;quot;DOWNLOAD VIA SSH&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        {:noreply, redirect(socket, to: &amp;quot;/download&amp;quot;)}&lt;br /&gt;
&lt;br /&gt;
    end&lt;br /&gt;
   &lt;br /&gt;
&lt;br /&gt;
    def render(assigns) do&lt;br /&gt;
        &lt;br /&gt;
        ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        &amp;lt;ul&amp;gt;&lt;br /&gt;
        &amp;lt;%= for switch &amp;lt;- @switches do %&amp;gt;&lt;br /&gt;
         &amp;lt;a phx-submit=&amp;quot;click&amp;quot; href=&amp;quot;/download&amp;quot;&amp;gt;  &amp;lt;li&amp;gt; &amp;lt;%= switch %&amp;gt;  &amp;lt;/li&amp;gt; &amp;lt;/a&amp;gt;&lt;br /&gt;
&lt;br /&gt;
        &amp;lt;%end%&amp;gt;&lt;br /&gt;
        &amp;lt;/ul&amp;gt;&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot; &lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Notes==&lt;br /&gt;
List of Switches and the option to select the one needed.&lt;br /&gt;
Button to download JSON file.&lt;br /&gt;
Drag and Drop Palette to upload JSON file.&lt;br /&gt;
&lt;br /&gt;
After JSON file is uploaded a button titled &amp;quot;Make Active&amp;quot; is available.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://medium.com/@fraiha26/pushing-events-to-livecomponents-from-js-hooks-w-phoenix-elixir-d5544d4c3dfa&lt;br /&gt;
&lt;br /&gt;
Changeset notes and forms&lt;br /&gt;
&lt;br /&gt;
NOTE: Use case statements for pattern matching&lt;br /&gt;
____________________________________________&lt;br /&gt;
&lt;br /&gt;
Create a basic &amp;lt;.form&amp;gt;&amp;lt;/form&amp;gt; without error handling&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&amp;lt;.form :let={f} for={@changeset}  action={~p&amp;quot;/items&amp;quot;} &amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;.input field={f[:title]} type=&amp;quot;text&amp;quot; label=&amp;quot;Title&amp;quot; /&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
  &amp;lt;.button&amp;gt;Save Item&amp;lt;/.button&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;/.form&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With error handling looks like this:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;.form :let={f} for={@changeset}  action={~p&amp;quot;/items&amp;quot;} &amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;.error :if={@changeset.action}&amp;gt;&lt;br /&gt;
    Oops, something went wrong! Please check the errors below.&lt;br /&gt;
  &amp;lt;/.error&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;.input field={f[:title]} type=&amp;quot;text&amp;quot; label=&amp;quot;Title&amp;quot; /&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
  &amp;lt;.button&amp;gt;Save Item&amp;lt;/.button&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;/.form&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Create the routes for render and post to endpoint.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The controller for the page render needs to pass in the changeset via ```Items.change_item(%Item{})```&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  def new(conn, _params) do&lt;br /&gt;
    changeset = Items.change_item(%Item{})&lt;br /&gt;
    render(conn, :new, changeset: changeset)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Post route without error handling&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  def create(conn, %{&amp;quot;item&amp;quot; =&amp;gt; item_params}) do&lt;br /&gt;
    case Items.create_item(item_params) do&lt;br /&gt;
      {:ok, item} -&amp;gt;&lt;br /&gt;
        conn&lt;br /&gt;
        |&amp;gt; put_flash(:info, &amp;quot;Item created successfully.&amp;quot;)&lt;br /&gt;
        |&amp;gt; redirect(to: ~p&amp;quot;/items/#{item}&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With error handling&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  def create(conn, %{&amp;quot;item&amp;quot; =&amp;gt; item_params}) do&lt;br /&gt;
    case Items.create_item(item_params) do&lt;br /&gt;
      {:ok, item} -&amp;gt;&lt;br /&gt;
        conn&lt;br /&gt;
        |&amp;gt; put_flash(:info, &amp;quot;Item created successfully.&amp;quot;)&lt;br /&gt;
        |&amp;gt; redirect(to: ~p&amp;quot;/items/#{item}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
      {:error, %Ecto.Changeset{} = changeset} -&amp;gt;&lt;br /&gt;
        render(conn, :new, changeset: changeset)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_____________________________________________&lt;br /&gt;
https://medium.com/@vincentlin/phoenix-very-simple-form-c4b121697fcb&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''home.html.heex'''&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&amp;lt;form action=&amp;quot;/submit&amp;quot; method=&amp;quot;post&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;label for=&amp;quot;name&amp;quot;&amp;gt;Name:&amp;lt;/label&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;input type=&amp;quot;text&amp;quot; id=&amp;quot;name&amp;quot; name=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;_csrf_token&amp;quot; value={@csrf_token} /&amp;gt;&lt;br /&gt;
  &amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Submit&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
page_controller.ex&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.PageController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  def home(conn, _params) do&lt;br /&gt;
    # The home page is often custom made,&lt;br /&gt;
&lt;br /&gt;
    csrf_token = Plug.CSRFProtection.get_csrf_token()&lt;br /&gt;
    render(conn, :home, csrf_token: csrf_token)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def submit(conn, _params) do&lt;br /&gt;
    # The home page is often custom made,&lt;br /&gt;
     IO.inspect(_params)&lt;br /&gt;
     IO.inspect &amp;quot;___________________________&amp;quot;&lt;br /&gt;
    csrf_token = Plug.CSRFProtection.get_csrf_token()&lt;br /&gt;
    render(conn, :home, csrf_token: csrf_token)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
router.ex&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  scope &amp;quot;/&amp;quot;, AppWeb do&lt;br /&gt;
    pipe_through :browser&lt;br /&gt;
    post &amp;quot;/submit&amp;quot;, PageController, :submit&lt;br /&gt;
    get &amp;quot;/&amp;quot;, PageController, :home&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ecto.Adapters.SQL.query(Repo, &amp;quot;select * from artists where id=1&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ecto cheatsheet:  https://hexdocs.pm/ecto/crud.html&lt;br /&gt;
__________________________________________________________________&lt;br /&gt;
Most programming languages give you the ability to set global state by creating globally scoped variables. Elixir does not do this. Instead, Elixir provides a tool called a &amp;quot;processes&amp;quot; to persist  state. Elixir applications are composed of these &amp;quot;processes&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
Processes by themselves are complicated to use, thus Elixir provides abstractions to make working with processes easier. One of these abstractions is called a GenServer.&lt;br /&gt;
&lt;br /&gt;
GenServers are not only used to store state, they are also used to invoke work independent of the main application process. &lt;br /&gt;
&lt;br /&gt;
==Creating a GenServer to Store State==&lt;br /&gt;
&lt;br /&gt;
To Create a GenServer, start by creating a basic Module that ''uses'' the GenServer module (image below)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule App do  &lt;br /&gt;
  use GenServer&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We now need to describe the actions we want to perform. Being that this is used to store state, we will use basic CRUD actions: Create, Read, Update, Delete. To begins, empty functions describing each action is created.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule App do&lt;br /&gt;
   def create do &lt;br /&gt;
&lt;br /&gt;
   end&lt;br /&gt;
   def read do &lt;br /&gt;
&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
   def update do  &lt;br /&gt;
&lt;br /&gt;
   end &lt;br /&gt;
&lt;br /&gt;
   def delete do &lt;br /&gt;
&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==What now?==&lt;br /&gt;
&lt;br /&gt;
To fill in the functions with the appropriate code we must first have a basic understanding of how GenServers are structured.&lt;br /&gt;
&lt;br /&gt;
GenServers are composed of the GenServer module invoking callbacks. The callbacks have built in names that you, as a developer have to use.&lt;br /&gt;
&lt;br /&gt;
These callbacks are named:&lt;br /&gt;
&lt;br /&gt;
* init&lt;br /&gt;
* handle_cast&lt;br /&gt;
* handle_call&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To demonstrate, here is an example :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{:ok, pid} = GenServer.start(ModuleNameOfGenServer, %{})&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above function named &amp;quot;start&amp;quot; calls the function named init in the Module below.&lt;br /&gt;
In GenServer syntax the name of the GenServer functions always invoke callbacks that are determined by the language. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule ModuleNameOfGenServer do&lt;br /&gt;
  # 1&lt;br /&gt;
  def init(state \\ %{}) do&lt;br /&gt;
    {:ok, state}&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is a list of the GenServer functions and their corresponding callbacks.&lt;br /&gt;
&lt;br /&gt;
* GenServer.start/1  --&amp;gt;       init/1&lt;br /&gt;
* GenServer.call/3   --&amp;gt;       def handle_call/3&lt;br /&gt;
* GenServer.cast/2   --&amp;gt;       handle_cast/2&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Start and Call ==&lt;br /&gt;
&lt;br /&gt;
Call and Cast can be used to perform the same operations. The &lt;br /&gt;
&lt;br /&gt;
__________________________________________________________&lt;br /&gt;
Genserver timed events&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule Go do&lt;br /&gt;
  use GenServer&lt;br /&gt;
&lt;br /&gt;
  def go() do&lt;br /&gt;
    GenServer.start_link(__MODULE__, [])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def init(list) do&lt;br /&gt;
    :timer.apply_interval(1000, __MODULE__, :add, [self(), &amp;quot;weeeee&amp;quot;])&lt;br /&gt;
    {:ok, list}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def view(pid) do&lt;br /&gt;
    GenServer.call(pid, :view)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_call(:view, _from, list) do&lt;br /&gt;
    {:reply, list, list}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def add(pid, new_item) do&lt;br /&gt;
    GenServer.call(pid, {:item, new_item})&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_call({:item, new_item}, _from, state) do&lt;br /&gt;
    result = [new_item] ++ state&lt;br /&gt;
    {:reply, result, result}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule ShoppingList do&lt;br /&gt;
  use GenServer&lt;br /&gt;
&lt;br /&gt;
  def start_link() do&lt;br /&gt;
    GenServer.start_link(ShoppingList, [])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def init(list) do&lt;br /&gt;
    {:ok, list}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def view(pid) do&lt;br /&gt;
    GenServer.call(pid, :view)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_call(:view, _from, list) do&lt;br /&gt;
    {:reply, list, list}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def add(pid, new_item) do&lt;br /&gt;
    GenServer.call(pid, {:item, new_item})&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_call({:item, new_item}, _from, state) do&lt;br /&gt;
    result = [new_item] ++ state&lt;br /&gt;
    {:reply, result, result}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://blog.appsignal.com/2018/06/12/elixir-alchemy-deconstructing-genservers.html&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule KeyValue do&lt;br /&gt;
  # 1&lt;br /&gt;
  def init(state \\ %{}) do&lt;br /&gt;
    {:ok, state}&lt;br /&gt;
  end&lt;br /&gt;
 &lt;br /&gt;
  # 2&lt;br /&gt;
  def handle_cast({:put, key, value}, state) do&lt;br /&gt;
    {:noreply, Map.put(state, key, value)}&lt;br /&gt;
  end&lt;br /&gt;
 &lt;br /&gt;
  # 3&lt;br /&gt;
  def handle_call({:get, key}, _from, state) do&lt;br /&gt;
    {:reply, Map.fetch!(state, key), state}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
# {:ok, pid} = GenServer.start(KeyValue, %{})&lt;br /&gt;
# GenServer.cast(pid, {:put, :foo, &amp;quot;bar&amp;quot;})&lt;br /&gt;
# GenServer.call(pid, {:get, :foo})&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Send messages via these functions wrapped in module functions .You can look at these are functions used to fire &amp;quot;GenServer Events&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
* start_link&lt;br /&gt;
* GenServer.call&lt;br /&gt;
* GenServer.cast&lt;br /&gt;
&lt;br /&gt;
The corresponding server functions that reply are:&lt;br /&gt;
&lt;br /&gt;
* init&lt;br /&gt;
* handle__call&lt;br /&gt;
* handle_cast&lt;br /&gt;
* &lt;br /&gt;
&lt;br /&gt;
These can be looked at as &amp;quot;listeners&amp;quot; - in JavaScript parlance. &lt;br /&gt;
__________________________________________&lt;br /&gt;
&lt;br /&gt;
If you have experience with programming languages other than Elixir the idea of GenServers may be very foreign and require a strong context shift to learn. This document is intended to simplify the concept.&lt;br /&gt;
&lt;br /&gt;
* What: GenServers are simply a way to hold state and/or invoke actions based on incoming events. &lt;br /&gt;
* when &lt;br /&gt;
* where&lt;br /&gt;
* why&lt;br /&gt;
* how&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
___________________________________________&lt;br /&gt;
GenServer timer example&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule Timer do&lt;br /&gt;
  use GenServer&lt;br /&gt;
&lt;br /&gt;
  def init(_) do&lt;br /&gt;
    :timer.send_interval(1000, :xyz)&lt;br /&gt;
    {:ok, 0}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_info(:xyz, state) do&lt;br /&gt;
    IO.inspect(state)&lt;br /&gt;
    {:noreply, state + 1}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
[&lt;br /&gt;
   {&lt;br /&gt;
     data:{&lt;br /&gt;
        creationTime,&lt;br /&gt;
        publishDate,&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
     featured:{&lt;br /&gt;
        setAmount,&lt;br /&gt;
        items:[]&lt;br /&gt;
     },&lt;br /&gt;
&lt;br /&gt;
     children:{&lt;br /&gt;
        setAmount,&lt;br /&gt;
        items:[]&lt;br /&gt;
     },&lt;br /&gt;
     links:{&lt;br /&gt;
        setAmount,&lt;br /&gt;
        items:[]&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
jason.encode / jason.decode&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  def run(num) do&lt;br /&gt;
&lt;br /&gt;
    Enum.each(0..99999, fn(_x) -&amp;gt;&lt;br /&gt;
      task = Task.async(fn -&amp;gt; num + _x end)&lt;br /&gt;
    IO.inspect Task.await(task)&lt;br /&gt;
  end)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enum.map(feed.entries, fn x -&amp;gt; %{url: x.url, title: x.title} end)&lt;br /&gt;
&lt;br /&gt;
App is split:&lt;br /&gt;
&lt;br /&gt;
App that captures RSS in UI and lets admin select stories. THere are settings to determine the number of FEATURED,CHILD and LINK stories.&lt;br /&gt;
News categories are horizontal and scrollable.&lt;br /&gt;
This exports a json doc with all RSS data for each story.&lt;br /&gt;
The &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
App that reads the json data. This app creates tables and is the front end.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://stephenbussey.com/tags/elixir.html&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule AppWeb.GroupLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  alias App.TestBeds&lt;br /&gt;
  alias App.Groups&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    {:ok, assign(socket, testbeds: TestBeds.list_testbeds(), groups: Groups.list_groups())}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;select-group&amp;quot;, params, socket)  do  &lt;br /&gt;
     group = App.Groups.get_group!(params[&amp;quot;group-id&amp;quot;])&lt;br /&gt;
     testbed = App.TestBeds.get_test_bed!(params[&amp;quot;testbed_id&amp;quot;])&lt;br /&gt;
     App.TestBeds.update_test_bed(testbed, %{group_id: group.id})&lt;br /&gt;
     {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def updated_groups(testbed_id)  do  &lt;br /&gt;
     testbed = App.TestBeds.get_test_bed!(testbed_id)&lt;br /&gt;
     groups = App.Groups.list_groups&lt;br /&gt;
     tail = Enum.filter(groups, fn(item)-&amp;gt; item.id !== testbed.group_id end)&lt;br /&gt;
     head = Enum.filter(groups, fn(item)-&amp;gt; item.id == testbed.group_id end)&lt;br /&gt;
            |&amp;gt;Enum.at(0)&lt;br /&gt;
    [head | tail]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        &amp;lt;%= for testbed &amp;lt;- Enum.sort_by(@testbeds , &amp;amp;(&amp;quot;#{&amp;amp;1.name}&amp;quot;), :asc)do %&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;grid grid-cols-4 gap-4 p-8 rounded shadow bg-white&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;h2&amp;gt; Name&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;%= testbed.name %&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;h2&amp;gt; Group&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div&amp;gt;&lt;br /&gt;
            &amp;lt;form phx-change=&amp;quot;select-group&amp;quot; name=&amp;quot;testbed_id&amp;quot;  &amp;gt;&lt;br /&gt;
               &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;testbed_id&amp;quot; value={testbed.id}/&amp;gt;&lt;br /&gt;
               &amp;lt;select id=&amp;quot;group-selection&amp;quot;  name=&amp;quot;group-id&amp;quot; class=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;%= for group &amp;lt;- updated_groups(testbed.id) do %&amp;gt;&lt;br /&gt;
                  &amp;lt;%= if group !== nil do %&amp;gt;&lt;br /&gt;
                      &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}&amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
                      &amp;lt;%else%&amp;gt;&lt;br /&gt;
                      &amp;lt;option value= {&amp;quot;Unassigned&amp;quot;}&amp;gt;NONE&amp;lt;/option&amp;gt;&lt;br /&gt;
                  &amp;lt;% end %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
               &amp;lt;/select&amp;gt;&lt;br /&gt;
            &amp;lt;/form&amp;gt;&lt;br /&gt;
          &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
       &amp;lt;% end %&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Developer Notes ==&lt;br /&gt;
===Groups Feature ===&lt;br /&gt;
To complete this feature do these things.&lt;br /&gt;
* Run through the steps in [http://elixirblocks.com/index.php?title=Create_Foreign_Key_Relationship_Between_Ecto_Tables  | this document] to create Group table.&lt;br /&gt;
* Groups have these fields  '''name: string''', '''description: string''' and '''color: string'''  &lt;br /&gt;
* Add unique constraint in migration file: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def change do&lt;br /&gt;
     create unique_index(:groups, [:name])&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Port over Group LiveView code (temporarily placed at discussion page).&lt;br /&gt;
* On completion '''possibly''', create a Group named '''No Group''' and set all Testbeds to it.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
________&lt;br /&gt;
https://blog.appsignal.com/2022/10/11/phoenix-liveview-018-new-special-html-attributes.html&lt;br /&gt;
https://blixtdev.com/whats-new-phoenix-1-7/&lt;br /&gt;
https://github.com/devato/inertia_phoenix&lt;br /&gt;
https://phoenixonrails.com/blog/you-can-stop-using-form-for-in-phoenix&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://samuelmullen.com/articles/phoenix_templates_rendering_and_layouts&lt;br /&gt;
&lt;br /&gt;
WorkFlow of Todo App in Both LiveView and DeadView.&lt;br /&gt;
&lt;br /&gt;
Note:&lt;br /&gt;
&lt;br /&gt;
Create foreign key data.&lt;br /&gt;
Create live view. List all testbeds and form to assign each a group by group-name.&lt;br /&gt;
&lt;br /&gt;
Repeat in dead view&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Mental model and data flows&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
home.html.heex&lt;br /&gt;
&amp;lt;a href=&amp;quot;/data&amp;quot; name=&amp;quot;we are the world&amp;quot; &amp;gt;  click me&amp;lt;/a&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;%= @message %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
page controller&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  def home(conn, _params) do&lt;br /&gt;
    IO.inspect _params&lt;br /&gt;
    render(conn, :home, message: &amp;quot;Hello&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
get &amp;quot;/:yay&amp;quot;, PageController, :index&lt;br /&gt;
&lt;br /&gt;
get &amp;quot;/&amp;quot;, PageController, :index&lt;br /&gt;
&lt;br /&gt;
* Explain control flow of &amp;quot;Dead Views&amp;quot; and the Generator HTML Control flow.&lt;br /&gt;
* Proper Way to use Modal&lt;br /&gt;
* How to give Focus to Fields in Modal (or other forms fields)&lt;br /&gt;
* &lt;br /&gt;
* &lt;br /&gt;
* How to Create Database Seed Data.&lt;br /&gt;
* How to structure code so controller code is in one file and HTML Heex is in another&lt;br /&gt;
* How to Use Generators in a Real World Project&lt;br /&gt;
* How to Work with Database Data via Basic Commands and Custom Change sets.&lt;br /&gt;
* How to Render Database Data to LiveView (via Context Commands).&lt;br /&gt;
* How to Create a Chat using PubSub.&lt;br /&gt;
* How to Create Event Handlers in LiveView&lt;br /&gt;
* How to Create a Dynamic Route from Scratch.&lt;br /&gt;
* How to Use Elixirs Template language&lt;br /&gt;
* How to Work with Modal&lt;br /&gt;
* How to Use CSS From Scratch (Without bundler)&lt;br /&gt;
* How to use JS hooks&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
______________________&lt;br /&gt;
https://studioindie.co/blog/heex-guide/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
get &amp;quot;/&amp;quot;, PageController, :some-atom    #This is the route. some-atom is the controller name&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  def some-atom(conn, _params) do                 # controller name&lt;br /&gt;
    # The home page is often custom made,&lt;br /&gt;
    # so skip the default app layout.&lt;br /&gt;
    render(conn, :some-atom, layout: false)      # :some-atom is template name&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Controllers page_html.ex contains &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageHTML do&lt;br /&gt;
  use AppWeb, :html&lt;br /&gt;
&lt;br /&gt;
  embed_templates &amp;quot;page_html/*&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''page_html''' is the name of the folder in '''Controllers/page_html'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Controllers/page_html/some-atom.html.heex  (this is the template) &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__________________________________________&lt;br /&gt;
Set all association with preload:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  def list_groups do&lt;br /&gt;
    Repo.all(Group)&lt;br /&gt;
     |&amp;gt; Repo.preload([:testbeds])&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Insert Child into Parent ===&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
App.get_group!(2) # arg is id&lt;br /&gt;
|&amp;gt; Ecto.build_assoc(:testbeds)&lt;br /&gt;
|&amp;gt; Repo.insert()&lt;br /&gt;
&lt;br /&gt;
Or&lt;br /&gt;
&lt;br /&gt;
group = App.get_group!(2) # arg is id&lt;br /&gt;
&lt;br /&gt;
testbeds = Ecto.build_assoc(group, :testbeds)&lt;br /&gt;
&lt;br /&gt;
App.Group.create_group(testbeds)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
group = App.Groups.get_group!(1)&lt;br /&gt;
thing = Ecto.build_assoc(group, :testbeds, name: &amp;quot;DUMB&amp;quot;)&lt;br /&gt;
alias App.{Repo}&lt;br /&gt;
Repo.insert(thing)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
avatar = %Avatar{nick_name: &amp;quot;Elixir&amp;quot;, pic_url: &amp;quot;http://elixir-lang.org/images/logo.png&amp;quot;}&lt;br /&gt;
user = %User{name: &amp;quot;John Doe&amp;quot;, email: &amp;quot;john.doe@example.com&amp;quot;, avatar: avatar}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://www.reddit.com/r/elixir/comments/oh318k/is_there_a_way_to_avoid_ectoassociationnotloaded/h4mmcfi/?utm_source=share&amp;amp;utm_medium=web3x&amp;amp;utm_name=web3xcss&amp;amp;utm_term=1&amp;amp;utm_content=share_button&lt;br /&gt;
&lt;br /&gt;
# Create Group Table&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
mix phx.gen.html Groups Group groups name:string  &lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Set the resources / &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
mix ecto.migrate&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For testbeds create a migration file and add this field:   group_id:references:groups&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
def change do&lt;br /&gt;
    alter table(:testbeds) do    # customize to your code&lt;br /&gt;
      add :group_id, references(:groups)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Update Groups Schema (Don't forget alias / has_many)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule App.Groups.Group do&lt;br /&gt;
	use Ecto.Schema&lt;br /&gt;
	import Ecto.Changeset&lt;br /&gt;
	alias App.Testbeds.Testbed   # Alias!&lt;br /&gt;
&lt;br /&gt;
	schema &amp;quot;posts&amp;quot; do&lt;br /&gt;
		field :body, :string&lt;br /&gt;
		field :title, :string&lt;br /&gt;
		has_many :testbeds, Testbed    # Has many&lt;br /&gt;
&lt;br /&gt;
		timestamps()&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	@doc false&lt;br /&gt;
	def changeset(post, attrs) do&lt;br /&gt;
		post&lt;br /&gt;
		|&amp;gt; cast(attrs, [:title, :body])&lt;br /&gt;
		|&amp;gt; validate_required([:title, :body])&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
TESTBEDS Schema&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule App.Testbeds.Testbed do&lt;br /&gt;
  use Ecto.Schema&lt;br /&gt;
  import Ecto.Changeset&lt;br /&gt;
  alias App.Groups.Group      # Alias&lt;br /&gt;
  schema &amp;quot;testbeds&amp;quot; do&lt;br /&gt;
    field :name, :string&lt;br /&gt;
    belongs_to :group, Group    # Belongs to&lt;br /&gt;
    timestamps()&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  @doc false&lt;br /&gt;
  def changeset(testbed, attrs) do&lt;br /&gt;
    testbed&lt;br /&gt;
    |&amp;gt; cast(attrs, [:name])&lt;br /&gt;
    |&amp;gt; validate_required([:name])&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
_____________________________________&lt;br /&gt;
Side notes.&lt;br /&gt;
&lt;br /&gt;
defmodule App.Repo.Migrations.CreateTestbeds do&lt;br /&gt;
  use Ecto.Migration&lt;br /&gt;
&lt;br /&gt;
  def change do&lt;br /&gt;
    create table(:testbeds) do&lt;br /&gt;
      add :name, :string&lt;br /&gt;
      add :group_id, references(:groups, on_delete: :nothing)&lt;br /&gt;
&lt;br /&gt;
      timestamps()&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    create index(:testbeds, [:group_id])&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
________________________________&lt;br /&gt;
&lt;br /&gt;
mix phx.gen.context Comments Comment comments name:string content:text post_id:references:posts&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
mix phx.gen.html Testbeds Testbed testbeds name:string  group_id:references:groups&lt;br /&gt;
&lt;br /&gt;
https://graffino.com/web-development/first-steps-in-elixir-and-phoenix-create-a-blog-prototype&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://blog.logrocket.com/getting-started-ecto-phoenix/&lt;br /&gt;
&lt;br /&gt;
https://serokell.io/blog/ecto-guide-for-beginners&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
mix phx.gen.html Testbeds Testbed testbeds name:string&lt;br /&gt;
&lt;br /&gt;
mix phx.gen.html Groups Group groups name:string&lt;br /&gt;
&lt;br /&gt;
Create migration for &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
mix ecto.gen.migration add_testbed_group_reference&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Migration:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  def change do&lt;br /&gt;
    alter table(:testbeds) do    # customize to your code&lt;br /&gt;
      add :group_id, references(:groups)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Manually Change:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule App.Group do&lt;br /&gt;
  use Ecto.Schema&lt;br /&gt;
&lt;br /&gt;
  schema &amp;quot;groups&amp;quot; do&lt;br /&gt;
    field :title, :string&lt;br /&gt;
    field :tagline, :string&lt;br /&gt;
    has_many :testbeds, App.Testbed&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
testbeds&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule App.Repo.Migrations.AddTextbedGroups do&lt;br /&gt;
  use Ecto.Migration&lt;br /&gt;
&lt;br /&gt;
  def change do&lt;br /&gt;
    create table(:testbeds) do&lt;br /&gt;
      add :name, :string&lt;br /&gt;
      add :group_id, references(:groups)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
# lib/app/testbeds.ex&lt;br /&gt;
&lt;br /&gt;
defmodule App.Testbed do&lt;br /&gt;
  use Ecto.Schema&lt;br /&gt;
&lt;br /&gt;
  schema &amp;quot;testbedss&amp;quot; do&lt;br /&gt;
    field :name, :string&lt;br /&gt;
    belongs_to :group, App.Group&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_____________________&lt;br /&gt;
&lt;br /&gt;
%App.TestBeds.TestBed{&lt;br /&gt;
  __meta__: #Ecto.Schema.Metadata&amp;lt;:loaded, &amp;quot;testbeds&amp;quot;&amp;gt;,&lt;br /&gt;
  id: 1,&lt;br /&gt;
  developer: &amp;quot;None&amp;quot;,&lt;br /&gt;
  name: &amp;quot;sdfsd&amp;quot;,&lt;br /&gt;
  owner: &amp;quot;sdfsddf&amp;quot;,&lt;br /&gt;
  note: &amp;quot;sdsfsddf&amp;quot;,&lt;br /&gt;
  status: &amp;quot;Available&amp;quot;,&lt;br /&gt;
  url: &amp;quot;sdf&amp;quot;,&lt;br /&gt;
  version: &amp;quot;ddf&amp;quot;,&lt;br /&gt;
  manager: &amp;quot;sf&amp;quot;,&lt;br /&gt;
  inserted_at: ~N[2023-08-21 13:45:39],&lt;br /&gt;
  updated_at: ~N[2023-08-21 13:45:44]&lt;br /&gt;
}&lt;br /&gt;
________________________________________________________________---&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.SendLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  &lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    {:ok, socket}&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  def handle_event(&amp;quot;send&amp;quot;, %{&amp;quot;text&amp;quot; =&amp;gt; text}, socket) do&lt;br /&gt;
&lt;br /&gt;
    AppWeb.Endpoint.broadcast(topic, &amp;quot;message&amp;quot;, text)&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  defp topic do&lt;br /&gt;
    &amp;quot;chat&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def render(assigns)do   &lt;br /&gt;
   ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
  &amp;lt;h1&amp;gt;Send Message&amp;lt;/h1&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;form phx-submit=&amp;quot;send&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;text&amp;quot; /&amp;gt;&lt;br /&gt;
    &amp;lt;button type=&amp;quot;submit&amp;quot;&amp;gt;Send&amp;lt;/button&amp;gt;&lt;br /&gt;
  &amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
______________________________________________________________&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.ReceiveLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  &lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    if connected?(socket) do&lt;br /&gt;
      AppWeb.Endpoint.subscribe(topic)&lt;br /&gt;
    end&lt;br /&gt;
    {:ok, assign(socket, messages: &amp;quot;&amp;quot;)}&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def handle_info(%{event: &amp;quot;message&amp;quot;, payload: message}, socket) do&lt;br /&gt;
    IO.inspect message&lt;br /&gt;
    {:noreply, assign(socket, messages: message)}&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  defp topic do&lt;br /&gt;
    &amp;quot;chat&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns)do   &lt;br /&gt;
   ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
  &amp;lt;h1&amp;gt;ChatLive&amp;lt;/h1&amp;gt;&lt;br /&gt;
  &amp;lt;%= @messages %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
______________________________________________________________&lt;br /&gt;
When you hover over a list of items this hook finds items with the same name and sets the opacity of all others to 0. You see all the items similar to the one you are hovering over.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
TestbedVersionHover: {&lt;br /&gt;
			// https://jsfiddle.net/IrvinDominin/7K2Z3/&lt;br /&gt;
            mounted() {&lt;br /&gt;
&lt;br /&gt;
                let rows = document.getElementsByClassName(&amp;quot;testbed-version&amp;quot;)&lt;br /&gt;
                // this.ele = element&lt;br /&gt;
				// rows = this.ele;&lt;br /&gt;
                &lt;br /&gt;
				for (var i = 0; i &amp;lt; rows.length; i++) {&lt;br /&gt;
					rows[i].onmouseenter = function (event) {&lt;br /&gt;
						for (var j = 0; j &amp;lt; rows.length; j++) {&lt;br /&gt;
							let preversion = this.textContent;&lt;br /&gt;
							let version = preversion.slice(0,5)&lt;br /&gt;
							let compareVersion = rows[j].textContent.slice(0,5)&lt;br /&gt;
							if (compareVersion === version) continue&lt;br /&gt;
							rows[j].className += &amp;quot; other&amp;quot;;&lt;br /&gt;
						}&lt;br /&gt;
					};&lt;br /&gt;
				&lt;br /&gt;
					rows[i].onmouseleave = function (event) {&lt;br /&gt;
						var hovers = document.getElementsByClassName('other');&lt;br /&gt;
						var len = hovers.length;&lt;br /&gt;
						for (var j = 0; j &amp;lt; len; j++) {&lt;br /&gt;
							hovers[0].className = hovers[0].className.replace(/\sother(\s|$)/, '');&lt;br /&gt;
						}&lt;br /&gt;
					};&lt;br /&gt;
				}&lt;br /&gt;
&lt;br /&gt;
                // this.ele.addEventListener(&amp;quot;click&amp;quot;, (e) =&amp;gt; {&lt;br /&gt;
                //     console.log(e.target)&lt;br /&gt;
                    &lt;br /&gt;
                // });&lt;br /&gt;
&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* How to Create Database Seed Data.&lt;br /&gt;
* How to structure code so controller code is in one file and HTML Heex is in another&lt;br /&gt;
* How to Use Generators in a Real World Project&lt;br /&gt;
* How to Work with Database Data via Basic Commands and Custom Change sets.&lt;br /&gt;
* How to Render Database Data to LiveView (via Context Commands).&lt;br /&gt;
* How to Create a Chat using PubSub.&lt;br /&gt;
* How to Create Event Handlers in LiveView&lt;br /&gt;
* How to Create a Dynamic Route from Scratch.&lt;br /&gt;
* How to Use Elixirs Template language&lt;br /&gt;
* How to Work with Modal&lt;br /&gt;
* How to Use CSS From Scratch (Without bundler)&lt;br /&gt;
* How to use JS hooks&lt;br /&gt;
* Dissect Table Component and Update it to Order List in Reverse.&lt;br /&gt;
&lt;br /&gt;
Selenium&lt;br /&gt;
https://www.builder.io/blog/debug-nodejs&lt;br /&gt;
&lt;br /&gt;
https://marketplace.visualstudio.com/items?itemName=ms-vscode.live-server#running-the-extension&lt;br /&gt;
&lt;br /&gt;
This was added recently (see microsoft/vscode#109276).&lt;br /&gt;
    1. Open the palette (Ctrl + Shift + P)&lt;br /&gt;
    2. Select &amp;quot;Simple Browser: Preview&amp;quot;&lt;br /&gt;
    3. Enter web address&lt;br /&gt;
&lt;br /&gt;
_______________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
const {By, Key, Builder} = require(&amp;quot;selenium-webdriver&amp;quot;);&lt;br /&gt;
const assert = require(&amp;quot;assert&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
require(&amp;quot;chromedriver&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
async function test_case(){&lt;br /&gt;
  let driver = await new Builder().forBrowser(&amp;quot;chrome&amp;quot;).build();&lt;br /&gt;
  await driver.get(&amp;quot;sie&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  await driver.findElement(By.name('password')).clear();&lt;br /&gt;
  await driver.findElement(By.name('identification')).clear();&lt;br /&gt;
  await driver.findElement(By.name('identification')).sendKeys(&amp;quot;bill&amp;quot;);&lt;br /&gt;
  await driver.findElement(By.name('password')).sendKeys(&amp;quot;password&amp;quot;, Key.RETURN);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 setTimeout(()=&amp;gt;{&lt;br /&gt;
   driver.findElement(By.className(&amp;quot;req_lan_license&amp;quot;)).click();&lt;br /&gt;
 },5000)&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageLive do &lt;br /&gt;
&lt;br /&gt;
  use AppWeb, :live_view  &lt;br /&gt;
  alias App.Testbeds &lt;br /&gt;
  def mount(_params, _session, socket)do   &lt;br /&gt;
     {:ok, assign(socket, testbeds: Testbeds.list_testbeds())}   &lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
    def button_event(&amp;quot;invoke_editing&amp;quot;) do&lt;br /&gt;
    %JS{}&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;active&amp;quot;, to: &amp;quot;#editing_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#editing_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#preview_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;active&amp;quot;, to: &amp;quot;#preview_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;active&amp;quot;, to: &amp;quot;#preview&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#preview&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#editing&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;active&amp;quot;, to: &amp;quot;#editing&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def button_event(&amp;quot;invoke_preview&amp;quot;) do&lt;br /&gt;
    %JS{}&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;active&amp;quot;, to: &amp;quot;#preview_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#preview_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#editing_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;active&amp;quot;, to: &amp;quot;#editing_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;active&amp;quot;, to: &amp;quot;#editing&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#editing&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#preview&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;active&amp;quot;, to: &amp;quot;#preview&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;send&amp;quot;, params, socket) do&lt;br /&gt;
    hide_modal(&amp;quot;notes-modal-0&amp;quot;)&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do  &lt;br /&gt;
     ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
		&amp;lt;.modal id={&amp;quot;notes-modal-#{testbed.id}&amp;quot;}&amp;gt;&lt;br /&gt;
		    &amp;lt;.button phx-click={button_event(&amp;quot;invoke_editing&amp;quot;)} id=&amp;quot;editing_button&amp;quot; class=&amp;quot;hidden&amp;quot;&amp;gt;&lt;br /&gt;
		      Preview&lt;br /&gt;
		    &amp;lt;/.button&amp;gt;&lt;br /&gt;
		    &amp;lt;.button phx-click={button_event(&amp;quot;invoke_preview&amp;quot;)} id=&amp;quot;preview_button&amp;quot;&amp;gt;&lt;br /&gt;
		      Edit Me&lt;br /&gt;
		    &amp;lt;/.button&amp;gt;&lt;br /&gt;
		    &amp;lt;div id=&amp;quot;editing&amp;quot;&amp;gt; PREVIEWING THE WORK&amp;lt;/div&amp;gt;&lt;br /&gt;
		    &amp;lt;form phx-submit = &amp;quot;send&amp;quot;   id=&amp;quot;preview&amp;quot; class=&amp;quot;hidden&amp;quot;&amp;gt;&lt;br /&gt;
		      &amp;lt;textarea value = {testbed.note}&amp;gt;&amp;lt;/textarea&amp;gt;&lt;br /&gt;
		      &amp;lt;.button type=&amp;quot;submit&amp;quot; phx-click={hide_modal(&amp;quot;notes-modal-#{testbed.id}&amp;quot;)}&amp;gt;SAVE WORK&amp;lt;/.button&amp;gt;&lt;br /&gt;
		    &amp;lt;/form&amp;gt;&lt;br /&gt;
		&amp;lt;/.modal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;%= if testbed.note do %&amp;gt;&lt;br /&gt;
      &amp;lt;div phx-click={show_modal(&amp;quot;notes-modal-#{testbed.id}&amp;quot;)}&amp;gt;READ ME  ...&amp;lt;%= testbed.note %&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
	   &lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
       &lt;br /&gt;
      &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
import {HfInference} from &amp;quot;@huggingface/inference&amp;quot;;&lt;br /&gt;
import dotenv from &amp;quot;dotenv&amp;quot;;&lt;br /&gt;
dotenv.config()&lt;br /&gt;
&lt;br /&gt;
const HF_ACCESS_TOKEN = process.env.HF_ACCESS_TOKEN&lt;br /&gt;
&lt;br /&gt;
const hf = new HfInference(HF_ACCESS_TOKEN);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*______Uncomment for this example______________________&lt;br /&gt;
&lt;br /&gt;
const model = &amp;quot;nlpconnect/vit-gpt2-image-captioning&amp;quot;;&lt;br /&gt;
const imageURL = &amp;quot;https://i.imgur.com/lTvb7Et.png&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
const response = await fetch(imageURL);&lt;br /&gt;
const imageBlob = await response.blob();&lt;br /&gt;
&lt;br /&gt;
const result  = await hf.imageToText({&lt;br /&gt;
	data: imageBlob,&lt;br /&gt;
	model: model,&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
_______________________________________________________*/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*________Another example ___________________*/&lt;br /&gt;
&lt;br /&gt;
const result = await hf.summarization({&lt;br /&gt;
	model: 'facebook/bart-large-cnn',&lt;br /&gt;
	inputs: &amp;quot;The role of a dumb man is to get smarter oogy bookie boo&amp;quot;,&lt;br /&gt;
	parameters:{&lt;br /&gt;
		max_length: 100&lt;br /&gt;
	}&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
console.log(result);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
________________________________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://fly.io/phoenix-files/sdeb-toggling-element/&lt;br /&gt;
https://www.youtube.com/watch?v=vBgZvQapqhs&lt;br /&gt;
&lt;br /&gt;
https://blog.testdouble.com/posts/2022-11-28-how-to-use-javascript-with-phoenix-liveview/&lt;br /&gt;
&lt;br /&gt;
https://hexdocs.pm/phoenix_live_view/0.19.3/Phoenix.Component.html&lt;br /&gt;
_______________________________________&lt;br /&gt;
https://www.smashingmagazine.com/2011/10/quick-look-math-animations-javascript/&lt;br /&gt;
* Depth first traversal&lt;br /&gt;
* Breadth first traversal&lt;br /&gt;
&lt;br /&gt;
https://dev.to/codesphere/10-algorithms-every-developer-should-learn-3lnm&lt;br /&gt;
&lt;br /&gt;
https://www.youtube.com/watch?v=fPz40W9mfCg&lt;br /&gt;
&lt;br /&gt;
__________________________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.GroupLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  alias App.TestBeds&lt;br /&gt;
  alias App.Groups&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    {:ok, assign(socket, testbeds: TestBeds.list_testbeds(), groups: Groups.list_groups())}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;select-group&amp;quot;, params, socket)  do  &lt;br /&gt;
         &lt;br /&gt;
       IO.inspect params&lt;br /&gt;
       {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div class=&amp;quot;grid grid-columns-2 grid-flow-col gap-4&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;column-1&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;%= testbed.name %&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;column-2&amp;quot;&amp;gt;    &lt;br /&gt;
            &amp;lt;form phx-change=&amp;quot;select-group&amp;quot;  &amp;gt;&lt;br /&gt;
               &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;testbed_id&amp;quot; value={testbed.id}/&amp;gt;&lt;br /&gt;
               &amp;lt;select id=&amp;quot;group-selection&amp;quot;  name=&amp;quot;group-id&amp;quot; &amp;gt;&lt;br /&gt;
                &amp;lt;%= for group &amp;lt;- @groups do %&amp;gt;&lt;br /&gt;
                  &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}  &amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
               &amp;lt;/select&amp;gt;&lt;br /&gt;
            &amp;lt;/form&amp;gt;&lt;br /&gt;
         &amp;lt;/div&amp;gt;&lt;br /&gt;
       &amp;lt;% end %&amp;gt;&lt;br /&gt;
   &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
____________________________&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.GroupLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  alias App.TestBeds&lt;br /&gt;
  alias App.Groups&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
&lt;br /&gt;
    {:ok, assign(socket, testbeds: TestBeds.list_testbeds(), groups: Groups.list_groups(), messages: [])}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;select-group&amp;quot;, params, socket)  do  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
      group = App.Groups.get_group!(params[&amp;quot;group-id&amp;quot;])&lt;br /&gt;
       # IO.inspect group&lt;br /&gt;
       testbed = App.TestBeds.get_test_bed!(params[&amp;quot;testbed_id&amp;quot;])&lt;br /&gt;
     &lt;br /&gt;
       App.TestBeds.update_test_bed(testbed, %{group_id: group.id})&lt;br /&gt;
         &lt;br /&gt;
    &lt;br /&gt;
       {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def updated_groups(testbed_id)  do  &lt;br /&gt;
       groups = App.Groups.list_groups&lt;br /&gt;
       tail = Enum.filter(groups, fn(item)-&amp;gt; item.id !== testbed_id end)&lt;br /&gt;
       head = Enum.filter(groups, fn(item)-&amp;gt; item.id == testbed_id end)&lt;br /&gt;
              |&amp;gt;Enum.at(0)&lt;br /&gt;
     [head | tail]&lt;br /&gt;
         &lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
 # def handle_event(&amp;quot;groups&amp;quot;, params, socket)do  &lt;br /&gt;
 #       selected_testbed = %{name: &amp;quot;my testbed name&amp;quot;, id: 3}&lt;br /&gt;
 #       groups = App.Groups.list_groups&lt;br /&gt;
 #       tail = Enum.filter(groups, fn(item)-&amp;gt; item.id !== selected_testbed.id end)&lt;br /&gt;
 #       head = Enum.filter(groups, fn(item)-&amp;gt; item.id == selected_testbed.id end)&lt;br /&gt;
 #              |&amp;gt;Enum.at(0)&lt;br /&gt;
         &lt;br /&gt;
 &lt;br /&gt;
 #       # result = Enum.filter([1, 2, 3], fn x -&amp;gt; x.id !== 1 end)&lt;br /&gt;
 #      IO.inspect [head | tail]&lt;br /&gt;
         &lt;br /&gt;
 #      #&lt;br /&gt;
 #      {:noreply, socket, assigns.message:}&lt;br /&gt;
 #  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    &lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
       &amp;lt;%!-- &amp;lt;div phx-click = &amp;quot;groups&amp;quot;&amp;gt;CLICK ME&amp;lt;/div&amp;gt; --%&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;grid grid-cols-4 gap-4 p-8 rounded shadow bg-white&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;h2&amp;gt; Name&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;%= testbed.name %&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;h2&amp;gt; Group&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;form phx-change=&amp;quot;select-group&amp;quot; name=&amp;quot;testbed_id&amp;quot;  &amp;gt;&lt;br /&gt;
               &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;testbed_id&amp;quot; value={testbed.id}/&amp;gt;&lt;br /&gt;
               &amp;lt;select id=&amp;quot;group-selection&amp;quot;  name=&amp;quot;group-id&amp;quot; class=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
                &amp;lt;%= for group &amp;lt;- updated_groups(testbed.id) do %&amp;gt;&lt;br /&gt;
                  &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}  &amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
                  &amp;lt;!-- Write code to reorder with testbed.group_id matching group_id --&amp;gt;&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
               &amp;lt;/select&amp;gt;&lt;br /&gt;
            &amp;lt;/form&amp;gt;&lt;br /&gt;
          &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
       &amp;lt;% end %&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_____________________________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
   use AppWeb, :live_view  &lt;br /&gt;
     alias App.Testbeds&lt;br /&gt;
  alias App.Groups&lt;br /&gt;
   def mount(_params, _session, socket)  do&lt;br /&gt;
	     {:ok, assign(socket, testbeds: Testbeds.list_testbeds(), groups: Groups.list_groups())}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
   def handle_event(&amp;quot;select-group&amp;quot;, params, socket)  do  &lt;br /&gt;
       group = App.Groups.get_group!(params[&amp;quot;group-id&amp;quot;])&lt;br /&gt;
       testbed = App.Testbeds.get_testbed!(params[&amp;quot;testbed_id&amp;quot;])&lt;br /&gt;
       result = App.Testbeds.update_testbed(testbed, %{group_id: group.id})&lt;br /&gt;
       IO.inspect result&lt;br /&gt;
      &lt;br /&gt;
       {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
    def updated_groups(testbed_id)  do  &lt;br /&gt;
       testbed = App.Testbeds.get_testbed!(testbed_id)&lt;br /&gt;
       groups = App.Groups.list_groups&lt;br /&gt;
       tail = Enum.filter(groups, fn(item)-&amp;gt; item.id !== testbed.group_id end)&lt;br /&gt;
       head = Enum.filter(groups, fn(item)-&amp;gt; item.id == testbed.group_id end)&lt;br /&gt;
              |&amp;gt;Enum.at(0)&lt;br /&gt;
 &lt;br /&gt;
       [head | tail]&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    &lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;grid grid-cols-4 gap-4 p-8 rounded shadow bg-white&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;h2&amp;gt; Name&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;%= testbed.name %&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;h2&amp;gt; Group&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;form phx-change=&amp;quot;select-group&amp;quot; name=&amp;quot;testbed_id&amp;quot;  &amp;gt;&lt;br /&gt;
               &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;testbed_id&amp;quot; value={testbed.id}/&amp;gt;&lt;br /&gt;
               &amp;lt;select id=&amp;quot;group-selection&amp;quot;  name=&amp;quot;group-id&amp;quot; class=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
                &amp;lt;%= for group &amp;lt;- updated_groups(testbed.id) do %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
                  &amp;lt;%!-- &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}&amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt; --%&amp;gt;&lt;br /&gt;
                  &amp;lt;!-- Write code to reorder with testbed.group_id matching group_id --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
                  &amp;lt;%= if group !== nil do %&amp;gt;&lt;br /&gt;
                      &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}&amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
       &lt;br /&gt;
                  &amp;lt;% end %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
               &amp;lt;/select&amp;gt;&lt;br /&gt;
            &amp;lt;/form&amp;gt;&lt;br /&gt;
          &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
       &amp;lt;% end %&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  has_many :testbeds, TestBed, on_delete: :restrict   # Has many&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://elixirforum.com/t/ecto-has-many-on-delete-protect/49550&lt;br /&gt;
&lt;br /&gt;
https://hexdocs.pm/ecto/Ecto.Changeset.html#unique_constraint/3&lt;br /&gt;
&lt;br /&gt;
____________________________________________________________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== How to Create a Mix Project and Use It in Another Mix Project ==&lt;br /&gt;
&lt;br /&gt;
To create and use a **Mix project** inside another **Mix project** in Elixir, follow the steps below:&lt;br /&gt;
&lt;br /&gt;
=== 1. Create a New Mix Project ===&lt;br /&gt;
&lt;br /&gt;
First, you need to create a new Mix project. Let's call this project `library_project`. Run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mix new library_project --module LibraryProject&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will create a new Elixir Mix project named `library_project`. The `--module` flag specifies the name of the module that will be created (in this case `LibraryProject`).&lt;br /&gt;
&lt;br /&gt;
The directory structure of `library_project` will look like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
library_project/&lt;br /&gt;
  |_ lib/&lt;br /&gt;
      |_ library_project.ex&lt;br /&gt;
  |_ mix.exs&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can then add some basic functionality inside the `library_project/lib/library_project.ex` file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule LibraryProject do&lt;br /&gt;
  def hello do&lt;br /&gt;
    IO.puts &amp;quot;Hello from LibraryProject!&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now, `library_project` is ready to be used by another Mix project.&lt;br /&gt;
&lt;br /&gt;
=== 2. Create a Second Mix Project ===&lt;br /&gt;
&lt;br /&gt;
Next, create the second Mix project where you want to use `library_project`. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mix new app_project --module AppProject&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will create another Elixir project called `app_project`.&lt;br /&gt;
&lt;br /&gt;
The directory structure for this project will look like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
app_project/&lt;br /&gt;
  |_ lib/&lt;br /&gt;
      |_ app_project.ex&lt;br /&gt;
  |_ mix.exs&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 3. Add `library_project` as a Dependency in `app_project` ===&lt;br /&gt;
&lt;br /&gt;
Now, you want to make `library_project` available in `app_project`. There are two main ways to do this:&lt;br /&gt;
&lt;br /&gt;
==== Option 1: Local Dependency (via `path`) ====&lt;br /&gt;
&lt;br /&gt;
If `library_project` is a local project (i.e., it's stored in a different directory), you can add it to the `mix.exs` of `app_project` as a local dependency by specifying the path to `library_project`.&lt;br /&gt;
&lt;br /&gt;
Edit the `mix.exs` of `app_project`:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule AppProject.MixProject do&lt;br /&gt;
  use Mix.Project&lt;br /&gt;
&lt;br /&gt;
  def project do&lt;br /&gt;
    [&lt;br /&gt;
      app: :app_project,&lt;br /&gt;
      version: &amp;quot;0.1.0&amp;quot;,&lt;br /&gt;
      elixir: &amp;quot;~&amp;gt; 1.14&amp;quot;,&lt;br /&gt;
      start_permanent: Mix.env() == :prod,&lt;br /&gt;
      deps: deps()&lt;br /&gt;
    ]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  defp deps do&lt;br /&gt;
    [&lt;br /&gt;
      {:library_project, path: &amp;quot;../library_project&amp;quot;}  # Add the local dependency&lt;br /&gt;
    ]&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here, `{:library_project, path: &amp;quot;../library_project&amp;quot;}` tells Mix to use the local `library_project` located in the `../library_project` directory (relative to `app_project`).&lt;br /&gt;
&lt;br /&gt;
After updating the `mix.exs`, run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd app_project&lt;br /&gt;
mix deps.get&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will fetch the dependency and compile `library_project`.&lt;br /&gt;
&lt;br /&gt;
==== Option 2: Publish and Fetch as a Hex Package ====&lt;br /&gt;
&lt;br /&gt;
If you want to use `library_project` as a package in another project (for example, by publishing it to **Hex.pm**, Elixir’s package manager), you need to publish it to Hex and then add it as a dependency.&lt;br /&gt;
&lt;br /&gt;
1. Publish `library_project` to Hex (if it's public or for your private use).&lt;br /&gt;
2. Add `library_project` to your `app_project`’s `mix.exs` dependencies:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defp deps do&lt;br /&gt;
  [&lt;br /&gt;
    {:library_project, &amp;quot;~&amp;gt; 0.1.0&amp;quot;}  # Specify the published version from Hex&lt;br /&gt;
  ]&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Run `mix deps.get` to fetch the package from Hex.&lt;br /&gt;
&lt;br /&gt;
=== 4. Use `library_project` in `app_project` ===&lt;br /&gt;
&lt;br /&gt;
Now, you can use the functionality from `library_project` inside your `app_project`. For example, in `app_project/lib/app_project.ex`, you can call the function from `library_project`:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule AppProject do&lt;br /&gt;
  def start do&lt;br /&gt;
    IO.puts &amp;quot;Starting app_project!&amp;quot;&lt;br /&gt;
    LibraryProject.hello()  # Call the function from the library_project&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 5. Run the App ===&lt;br /&gt;
&lt;br /&gt;
Finally, you can run your `app_project`:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd app_project&lt;br /&gt;
mix run -e &amp;quot;AppProject.start()&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will print:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Starting app_project!&lt;br /&gt;
Hello from LibraryProject!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Recap of the Process ==&lt;br /&gt;
1. **Create the `library_project`**: Use `mix new` to generate a library project.&lt;br /&gt;
2. **Create the `app_project`**: Create the second project where you will use the library.&lt;br /&gt;
3. **Add the `library_project` as a dependency**:&lt;br /&gt;
   - Use the `path` option to point to the local project or publish it to Hex for public access.&lt;br /&gt;
4. **Use the `library_project` in the `app_project`**: Call functions or use modules from the library inside the second project.&lt;br /&gt;
5. **Run the app**: Use `mix run` to execute the project.&lt;br /&gt;
&lt;br /&gt;
This way, you can reuse code from one Mix project in another by adding it as a dependency.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==z==&lt;br /&gt;
Overloaded functions are extremely common in Elixir applications. They are&lt;br /&gt;
regularly used for recursive functions and for changing behavior based on&lt;br /&gt;
configuration.&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>http://elixirblocks.com/index.php?title=User:Admin&amp;diff=1872</id>
		<title>User:Admin</title>
		<link rel="alternate" type="text/html" href="http://elixirblocks.com/index.php?title=User:Admin&amp;diff=1872"/>
		<updated>2024-12-24T02:47:43Z</updated>

		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;________________________________________________________&lt;br /&gt;
&lt;br /&gt;
# CRUD Forms&lt;br /&gt;
&lt;br /&gt;
To understand CRUD forms you will need to understand the following concepts. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Ecto Schema&lt;br /&gt;
* Ecto Context&lt;br /&gt;
* Form Basics&lt;br /&gt;
* form/1&lt;br /&gt;
* simple_form/1&lt;br /&gt;
* changesets&lt;br /&gt;
&lt;br /&gt;
We are not going to go in order. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The Context provides CRUD functions for the chosen data schema. Phoenix contexts define the interface through which other parts of the codebase can interact with the app layer.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_______________________&lt;br /&gt;
* Create routes&lt;br /&gt;
* create page with form (submit get request)&lt;br /&gt;
&lt;br /&gt;
(ecto schema, context, changesets)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_______________________________________________________&lt;br /&gt;
In that case, you really should switch it to prod mode. Instead of doing all that above with the &amp;quot;config/secret.exs&amp;quot; file, create the &amp;quot;.env&amp;quot; in the project root, then add DotenvParser.load_file(&amp;quot;.env&amp;quot;) to &amp;quot;config/runtime.exs&amp;quot; as the first line inside the if config_env() == :prod do. In the .env file, set the DATABASE_URL and SECRET_KEY_BASE. Then run it as MIX_ENV=prod mix phx.server.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def get_titles do&lt;br /&gt;
    urls = [&lt;br /&gt;
      &amp;quot;https://cointelegraph.com/rss&amp;quot;,&lt;br /&gt;
      &amp;quot;https://chaski.huffpost.com/us/auto/vertical/us-news&amp;quot;&lt;br /&gt;
      # Add more RSS feed URLs here&lt;br /&gt;
    ]&lt;br /&gt;
&lt;br /&gt;
    urls&lt;br /&gt;
    |&amp;gt; Enum.map(fn url -&amp;gt;&lt;br /&gt;
      with {:ok, feed} &amp;lt;- ElixirRss.fetch_and_parse(url) do&lt;br /&gt;
        Enum.map(feed.entries, &amp;amp; &amp;amp;1.title)&lt;br /&gt;
      else&lt;br /&gt;
        {:error, reason} -&amp;gt; {:error, reason}&lt;br /&gt;
      end&lt;br /&gt;
    end)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule App do&lt;br /&gt;
&lt;br /&gt;
  def get_titles() do&lt;br /&gt;
    data = [&lt;br /&gt;
      &amp;quot;https://cointelegraph.com/rss&amp;quot;,&lt;br /&gt;
      &amp;quot;https://chaski.huffpost.com/us/auto/vertical/us-news&amp;quot;&lt;br /&gt;
      # Add more RSS feed URLs here&lt;br /&gt;
    ]&lt;br /&gt;
&lt;br /&gt;
    data&lt;br /&gt;
    |&amp;gt; Enum.map(fn url -&amp;gt;&lt;br /&gt;
      case ElixirRss.fetch_and_parse(url) do&lt;br /&gt;
        {:ok, feed} -&amp;gt; feed.entries |&amp;gt; Enum.map(fn entry -&amp;gt; entry end)&lt;br /&gt;
        {:error, reason} -&amp;gt; {:error, reason}&lt;br /&gt;
      end&lt;br /&gt;
    end)&lt;br /&gt;
    |&amp;gt; Enum.map(fn entry_list -&amp;gt;&lt;br /&gt;
      entry_list&lt;br /&gt;
      |&amp;gt; Enum.map(fn entry -&amp;gt; entry.title end)&lt;br /&gt;
    end)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def hello do&lt;br /&gt;
    rss_feeds = [&lt;br /&gt;
      &amp;quot;https://cointelegraph.com/rss&amp;quot;,&lt;br /&gt;
      &amp;quot;https://chaski.huffpost.com/us/auto/vertical/us-news&amp;quot;&lt;br /&gt;
      # Add more RSS feed URLs here&lt;br /&gt;
    ]&lt;br /&gt;
&lt;br /&gt;
    rss_feeds&lt;br /&gt;
    |&amp;gt; Enum.map(fn url -&amp;gt;&lt;br /&gt;
      case ElixirRss.fetch_and_parse(url) do&lt;br /&gt;
        {:ok, feed} -&amp;gt; feed.entries |&amp;gt; Enum.map(fn entry -&amp;gt; entry end)&lt;br /&gt;
        {:error, reason} -&amp;gt; {:error, reason}&lt;br /&gt;
      end&lt;br /&gt;
    end)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    if connected?(socket) do&lt;br /&gt;
      Phoenix.PubSub.subscribe(App.PubSub, &amp;quot;message&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
    {:ok, assign(socket, message_item: &amp;quot;different&amp;quot;)}&lt;br /&gt;
  end&lt;br /&gt;
  def handle_info({:pubsub_transmission, text}, socket) do&lt;br /&gt;
    IO.inspect &amp;quot;pub sub working&amp;quot;&lt;br /&gt;
    {:noreply, assign(socket, message_item: text)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def loop(data) do&lt;br /&gt;
     IO.inspect data&lt;br /&gt;
     if data &amp;gt; 0 do&lt;br /&gt;
      IO.inspect &amp;quot;notify&amp;quot;&lt;br /&gt;
      # run code to compare files, loop. If different run pubsub code below&lt;br /&gt;
      :timer.sleep(2000)&lt;br /&gt;
      loop(data-1)&lt;br /&gt;
&lt;br /&gt;
     end&lt;br /&gt;
     if data &amp;lt;= 0 do&lt;br /&gt;
&lt;br /&gt;
      Phoenix.PubSub.broadcast(App.PubSub, &amp;quot;message&amp;quot;, {:pubsub_transmission, &amp;quot;data&amp;quot;})&lt;br /&gt;
      &amp;quot;done&amp;quot;&lt;br /&gt;
     end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;change-text&amp;quot;, _params, socket) do&lt;br /&gt;
    spawn(fn -&amp;gt; loop(3) end)&lt;br /&gt;
    {:noreply, assign(socket, message_item: &amp;quot;START&amp;quot; )}&lt;br /&gt;
  end&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
&lt;br /&gt;
    # AppWeb.PageLive.loop(&amp;quot;xxx&amp;quot;)&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    SANDBOX&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;.button phx-click=&amp;quot;change-text&amp;quot; value={@message_item}&amp;gt;CLICK ME&amp;lt;/.button&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;%= @message_item %&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
elixir :   1.16.2&lt;br /&gt;
&lt;br /&gt;
Erl:   20&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# PostGres&lt;br /&gt;
Created Saturday 18 February 2023&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Launch [PostGres](#PostGres) from Terminal&lt;br /&gt;
------------------------------------------&lt;br /&gt;
sudo -u postgres psql&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Set User Permission&lt;br /&gt;
-------------------&lt;br /&gt;
&amp;lt;https://commandprompt.com/education/how-to-create-a-superuser-in-postgresql/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ALTER USER user_name WITH PASSWORD 'new_password';&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Run Post Gres Commands&lt;br /&gt;
----------------------&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
sudo -i -u postgres&lt;br /&gt;
psql&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Create and Delete Database&lt;br /&gt;
&lt;br /&gt;
CREATE DATABASE name;&lt;br /&gt;
DROP DATABASE name;&lt;br /&gt;
## View user list&lt;br /&gt;
&lt;br /&gt;
\du&lt;br /&gt;
&lt;br /&gt;
 View all databases&lt;br /&gt;
&lt;br /&gt;
postgres=# \l&lt;br /&gt;
&lt;br /&gt;
 Change databases&lt;br /&gt;
&lt;br /&gt;
postgres=# \c    name-of-database&lt;br /&gt;
&lt;br /&gt;
View Tables&lt;br /&gt;
&lt;br /&gt;
After you change databases and are selected on one of them do this:&lt;br /&gt;
&lt;br /&gt;
\dt&lt;br /&gt;
&lt;br /&gt;
SELECT * FROM mytablename;&lt;br /&gt;
&lt;br /&gt;
EMPTY TABLE&lt;br /&gt;
DELETE FROM name-of-table&lt;br /&gt;
&lt;br /&gt;
CREATE TABLE&lt;br /&gt;
&lt;br /&gt;
CREATE TABLE table_name(&lt;br /&gt;
   column1 datatype,&lt;br /&gt;
   column2 datatype,&lt;br /&gt;
   column3 datatype,&lt;br /&gt;
   .....&lt;br /&gt;
   columnN datatype,&lt;br /&gt;
   PRIMARY KEY( one or more columns )&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
INSERT&lt;br /&gt;
&lt;br /&gt;
INSERT INTO ITEMS(id, name) VALUES(1,'htvjbjbgni');     Strings are single quote&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Roadmap==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.ItemsLive do&lt;br /&gt;
    use AppWeb, :live_view  &lt;br /&gt;
    def mount(_params, _session, socket)  do&lt;br /&gt;
      {:ok, assign(socket, switches: [&amp;quot;grindy&amp;quot;,&amp;quot;sonic&amp;quot;,&amp;quot;ogre&amp;quot;])}  &lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    def handle_event(&amp;quot;run&amp;quot;,_params,socket) do  &lt;br /&gt;
        &lt;br /&gt;
        IO.inspect &amp;quot;DOWNLOAD VIA SSH&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        {:noreply, redirect(socket, to: &amp;quot;/download&amp;quot;)}&lt;br /&gt;
&lt;br /&gt;
    end&lt;br /&gt;
   &lt;br /&gt;
&lt;br /&gt;
    def render(assigns) do&lt;br /&gt;
        &lt;br /&gt;
        ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        &amp;lt;ul&amp;gt;&lt;br /&gt;
        &amp;lt;%= for switch &amp;lt;- @switches do %&amp;gt;&lt;br /&gt;
         &amp;lt;a phx-submit=&amp;quot;click&amp;quot; href=&amp;quot;/download&amp;quot;&amp;gt;  &amp;lt;li&amp;gt; &amp;lt;%= switch %&amp;gt;  &amp;lt;/li&amp;gt; &amp;lt;/a&amp;gt;&lt;br /&gt;
&lt;br /&gt;
        &amp;lt;%end%&amp;gt;&lt;br /&gt;
        &amp;lt;/ul&amp;gt;&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot; &lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Notes==&lt;br /&gt;
List of Switches and the option to select the one needed.&lt;br /&gt;
Button to download JSON file.&lt;br /&gt;
Drag and Drop Palette to upload JSON file.&lt;br /&gt;
&lt;br /&gt;
After JSON file is uploaded a button titled &amp;quot;Make Active&amp;quot; is available.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://medium.com/@fraiha26/pushing-events-to-livecomponents-from-js-hooks-w-phoenix-elixir-d5544d4c3dfa&lt;br /&gt;
&lt;br /&gt;
Changeset notes and forms&lt;br /&gt;
&lt;br /&gt;
NOTE: Use case statements for pattern matching&lt;br /&gt;
____________________________________________&lt;br /&gt;
&lt;br /&gt;
Create a basic &amp;lt;.form&amp;gt;&amp;lt;/form&amp;gt; without error handling&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&amp;lt;.form :let={f} for={@changeset}  action={~p&amp;quot;/items&amp;quot;} &amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;.input field={f[:title]} type=&amp;quot;text&amp;quot; label=&amp;quot;Title&amp;quot; /&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
  &amp;lt;.button&amp;gt;Save Item&amp;lt;/.button&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;/.form&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With error handling looks like this:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;.form :let={f} for={@changeset}  action={~p&amp;quot;/items&amp;quot;} &amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;.error :if={@changeset.action}&amp;gt;&lt;br /&gt;
    Oops, something went wrong! Please check the errors below.&lt;br /&gt;
  &amp;lt;/.error&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;.input field={f[:title]} type=&amp;quot;text&amp;quot; label=&amp;quot;Title&amp;quot; /&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
  &amp;lt;.button&amp;gt;Save Item&amp;lt;/.button&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;/.form&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Create the routes for render and post to endpoint.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The controller for the page render needs to pass in the changeset via ```Items.change_item(%Item{})```&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  def new(conn, _params) do&lt;br /&gt;
    changeset = Items.change_item(%Item{})&lt;br /&gt;
    render(conn, :new, changeset: changeset)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Post route without error handling&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  def create(conn, %{&amp;quot;item&amp;quot; =&amp;gt; item_params}) do&lt;br /&gt;
    case Items.create_item(item_params) do&lt;br /&gt;
      {:ok, item} -&amp;gt;&lt;br /&gt;
        conn&lt;br /&gt;
        |&amp;gt; put_flash(:info, &amp;quot;Item created successfully.&amp;quot;)&lt;br /&gt;
        |&amp;gt; redirect(to: ~p&amp;quot;/items/#{item}&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With error handling&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  def create(conn, %{&amp;quot;item&amp;quot; =&amp;gt; item_params}) do&lt;br /&gt;
    case Items.create_item(item_params) do&lt;br /&gt;
      {:ok, item} -&amp;gt;&lt;br /&gt;
        conn&lt;br /&gt;
        |&amp;gt; put_flash(:info, &amp;quot;Item created successfully.&amp;quot;)&lt;br /&gt;
        |&amp;gt; redirect(to: ~p&amp;quot;/items/#{item}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
      {:error, %Ecto.Changeset{} = changeset} -&amp;gt;&lt;br /&gt;
        render(conn, :new, changeset: changeset)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_____________________________________________&lt;br /&gt;
https://medium.com/@vincentlin/phoenix-very-simple-form-c4b121697fcb&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''home.html.heex'''&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&amp;lt;form action=&amp;quot;/submit&amp;quot; method=&amp;quot;post&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;label for=&amp;quot;name&amp;quot;&amp;gt;Name:&amp;lt;/label&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;input type=&amp;quot;text&amp;quot; id=&amp;quot;name&amp;quot; name=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;_csrf_token&amp;quot; value={@csrf_token} /&amp;gt;&lt;br /&gt;
  &amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Submit&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
page_controller.ex&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.PageController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  def home(conn, _params) do&lt;br /&gt;
    # The home page is often custom made,&lt;br /&gt;
&lt;br /&gt;
    csrf_token = Plug.CSRFProtection.get_csrf_token()&lt;br /&gt;
    render(conn, :home, csrf_token: csrf_token)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def submit(conn, _params) do&lt;br /&gt;
    # The home page is often custom made,&lt;br /&gt;
     IO.inspect(_params)&lt;br /&gt;
     IO.inspect &amp;quot;___________________________&amp;quot;&lt;br /&gt;
    csrf_token = Plug.CSRFProtection.get_csrf_token()&lt;br /&gt;
    render(conn, :home, csrf_token: csrf_token)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
router.ex&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  scope &amp;quot;/&amp;quot;, AppWeb do&lt;br /&gt;
    pipe_through :browser&lt;br /&gt;
    post &amp;quot;/submit&amp;quot;, PageController, :submit&lt;br /&gt;
    get &amp;quot;/&amp;quot;, PageController, :home&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ecto.Adapters.SQL.query(Repo, &amp;quot;select * from artists where id=1&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ecto cheatsheet:  https://hexdocs.pm/ecto/crud.html&lt;br /&gt;
__________________________________________________________________&lt;br /&gt;
Most programming languages give you the ability to set global state by creating globally scoped variables. Elixir does not do this. Instead, Elixir provides a tool called a &amp;quot;processes&amp;quot; to persist  state. Elixir applications are composed of these &amp;quot;processes&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
Processes by themselves are complicated to use, thus Elixir provides abstractions to make working with processes easier. One of these abstractions is called a GenServer.&lt;br /&gt;
&lt;br /&gt;
GenServers are not only used to store state, they are also used to invoke work independent of the main application process. &lt;br /&gt;
&lt;br /&gt;
==Creating a GenServer to Store State==&lt;br /&gt;
&lt;br /&gt;
To Create a GenServer, start by creating a basic Module that ''uses'' the GenServer module (image below)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule App do  &lt;br /&gt;
  use GenServer&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We now need to describe the actions we want to perform. Being that this is used to store state, we will use basic CRUD actions: Create, Read, Update, Delete. To begins, empty functions describing each action is created.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule App do&lt;br /&gt;
   def create do &lt;br /&gt;
&lt;br /&gt;
   end&lt;br /&gt;
   def read do &lt;br /&gt;
&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
   def update do  &lt;br /&gt;
&lt;br /&gt;
   end &lt;br /&gt;
&lt;br /&gt;
   def delete do &lt;br /&gt;
&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==What now?==&lt;br /&gt;
&lt;br /&gt;
To fill in the functions with the appropriate code we must first have a basic understanding of how GenServers are structured.&lt;br /&gt;
&lt;br /&gt;
GenServers are composed of the GenServer module invoking callbacks. The callbacks have built in names that you, as a developer have to use.&lt;br /&gt;
&lt;br /&gt;
These callbacks are named:&lt;br /&gt;
&lt;br /&gt;
* init&lt;br /&gt;
* handle_cast&lt;br /&gt;
* handle_call&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To demonstrate, here is an example :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{:ok, pid} = GenServer.start(ModuleNameOfGenServer, %{})&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above function named &amp;quot;start&amp;quot; calls the function named init in the Module below.&lt;br /&gt;
In GenServer syntax the name of the GenServer functions always invoke callbacks that are determined by the language. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule ModuleNameOfGenServer do&lt;br /&gt;
  # 1&lt;br /&gt;
  def init(state \\ %{}) do&lt;br /&gt;
    {:ok, state}&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is a list of the GenServer functions and their corresponding callbacks.&lt;br /&gt;
&lt;br /&gt;
* GenServer.start/1  --&amp;gt;       init/1&lt;br /&gt;
* GenServer.call/3   --&amp;gt;       def handle_call/3&lt;br /&gt;
* GenServer.cast/2   --&amp;gt;       handle_cast/2&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Start and Call ==&lt;br /&gt;
&lt;br /&gt;
Call and Cast can be used to perform the same operations. The &lt;br /&gt;
&lt;br /&gt;
__________________________________________________________&lt;br /&gt;
Genserver timed events&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule Go do&lt;br /&gt;
  use GenServer&lt;br /&gt;
&lt;br /&gt;
  def go() do&lt;br /&gt;
    GenServer.start_link(__MODULE__, [])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def init(list) do&lt;br /&gt;
    :timer.apply_interval(1000, __MODULE__, :add, [self(), &amp;quot;weeeee&amp;quot;])&lt;br /&gt;
    {:ok, list}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def view(pid) do&lt;br /&gt;
    GenServer.call(pid, :view)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_call(:view, _from, list) do&lt;br /&gt;
    {:reply, list, list}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def add(pid, new_item) do&lt;br /&gt;
    GenServer.call(pid, {:item, new_item})&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_call({:item, new_item}, _from, state) do&lt;br /&gt;
    result = [new_item] ++ state&lt;br /&gt;
    {:reply, result, result}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule ShoppingList do&lt;br /&gt;
  use GenServer&lt;br /&gt;
&lt;br /&gt;
  def start_link() do&lt;br /&gt;
    GenServer.start_link(ShoppingList, [])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def init(list) do&lt;br /&gt;
    {:ok, list}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def view(pid) do&lt;br /&gt;
    GenServer.call(pid, :view)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_call(:view, _from, list) do&lt;br /&gt;
    {:reply, list, list}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def add(pid, new_item) do&lt;br /&gt;
    GenServer.call(pid, {:item, new_item})&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_call({:item, new_item}, _from, state) do&lt;br /&gt;
    result = [new_item] ++ state&lt;br /&gt;
    {:reply, result, result}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://blog.appsignal.com/2018/06/12/elixir-alchemy-deconstructing-genservers.html&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule KeyValue do&lt;br /&gt;
  # 1&lt;br /&gt;
  def init(state \\ %{}) do&lt;br /&gt;
    {:ok, state}&lt;br /&gt;
  end&lt;br /&gt;
 &lt;br /&gt;
  # 2&lt;br /&gt;
  def handle_cast({:put, key, value}, state) do&lt;br /&gt;
    {:noreply, Map.put(state, key, value)}&lt;br /&gt;
  end&lt;br /&gt;
 &lt;br /&gt;
  # 3&lt;br /&gt;
  def handle_call({:get, key}, _from, state) do&lt;br /&gt;
    {:reply, Map.fetch!(state, key), state}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
# {:ok, pid} = GenServer.start(KeyValue, %{})&lt;br /&gt;
# GenServer.cast(pid, {:put, :foo, &amp;quot;bar&amp;quot;})&lt;br /&gt;
# GenServer.call(pid, {:get, :foo})&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Send messages via these functions wrapped in module functions .You can look at these are functions used to fire &amp;quot;GenServer Events&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
* start_link&lt;br /&gt;
* GenServer.call&lt;br /&gt;
* GenServer.cast&lt;br /&gt;
&lt;br /&gt;
The corresponding server functions that reply are:&lt;br /&gt;
&lt;br /&gt;
* init&lt;br /&gt;
* handle__call&lt;br /&gt;
* handle_cast&lt;br /&gt;
* &lt;br /&gt;
&lt;br /&gt;
These can be looked at as &amp;quot;listeners&amp;quot; - in JavaScript parlance. &lt;br /&gt;
__________________________________________&lt;br /&gt;
&lt;br /&gt;
If you have experience with programming languages other than Elixir the idea of GenServers may be very foreign and require a strong context shift to learn. This document is intended to simplify the concept.&lt;br /&gt;
&lt;br /&gt;
* What: GenServers are simply a way to hold state and/or invoke actions based on incoming events. &lt;br /&gt;
* when &lt;br /&gt;
* where&lt;br /&gt;
* why&lt;br /&gt;
* how&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
___________________________________________&lt;br /&gt;
GenServer timer example&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule Timer do&lt;br /&gt;
  use GenServer&lt;br /&gt;
&lt;br /&gt;
  def init(_) do&lt;br /&gt;
    :timer.send_interval(1000, :xyz)&lt;br /&gt;
    {:ok, 0}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_info(:xyz, state) do&lt;br /&gt;
    IO.inspect(state)&lt;br /&gt;
    {:noreply, state + 1}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
[&lt;br /&gt;
   {&lt;br /&gt;
     data:{&lt;br /&gt;
        creationTime,&lt;br /&gt;
        publishDate,&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
     featured:{&lt;br /&gt;
        setAmount,&lt;br /&gt;
        items:[]&lt;br /&gt;
     },&lt;br /&gt;
&lt;br /&gt;
     children:{&lt;br /&gt;
        setAmount,&lt;br /&gt;
        items:[]&lt;br /&gt;
     },&lt;br /&gt;
     links:{&lt;br /&gt;
        setAmount,&lt;br /&gt;
        items:[]&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
jason.encode / jason.decode&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  def run(num) do&lt;br /&gt;
&lt;br /&gt;
    Enum.each(0..99999, fn(_x) -&amp;gt;&lt;br /&gt;
      task = Task.async(fn -&amp;gt; num + _x end)&lt;br /&gt;
    IO.inspect Task.await(task)&lt;br /&gt;
  end)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enum.map(feed.entries, fn x -&amp;gt; %{url: x.url, title: x.title} end)&lt;br /&gt;
&lt;br /&gt;
App is split:&lt;br /&gt;
&lt;br /&gt;
App that captures RSS in UI and lets admin select stories. THere are settings to determine the number of FEATURED,CHILD and LINK stories.&lt;br /&gt;
News categories are horizontal and scrollable.&lt;br /&gt;
This exports a json doc with all RSS data for each story.&lt;br /&gt;
The &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
App that reads the json data. This app creates tables and is the front end.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://stephenbussey.com/tags/elixir.html&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule AppWeb.GroupLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  alias App.TestBeds&lt;br /&gt;
  alias App.Groups&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    {:ok, assign(socket, testbeds: TestBeds.list_testbeds(), groups: Groups.list_groups())}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;select-group&amp;quot;, params, socket)  do  &lt;br /&gt;
     group = App.Groups.get_group!(params[&amp;quot;group-id&amp;quot;])&lt;br /&gt;
     testbed = App.TestBeds.get_test_bed!(params[&amp;quot;testbed_id&amp;quot;])&lt;br /&gt;
     App.TestBeds.update_test_bed(testbed, %{group_id: group.id})&lt;br /&gt;
     {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def updated_groups(testbed_id)  do  &lt;br /&gt;
     testbed = App.TestBeds.get_test_bed!(testbed_id)&lt;br /&gt;
     groups = App.Groups.list_groups&lt;br /&gt;
     tail = Enum.filter(groups, fn(item)-&amp;gt; item.id !== testbed.group_id end)&lt;br /&gt;
     head = Enum.filter(groups, fn(item)-&amp;gt; item.id == testbed.group_id end)&lt;br /&gt;
            |&amp;gt;Enum.at(0)&lt;br /&gt;
    [head | tail]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        &amp;lt;%= for testbed &amp;lt;- Enum.sort_by(@testbeds , &amp;amp;(&amp;quot;#{&amp;amp;1.name}&amp;quot;), :asc)do %&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;grid grid-cols-4 gap-4 p-8 rounded shadow bg-white&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;h2&amp;gt; Name&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;%= testbed.name %&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;h2&amp;gt; Group&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div&amp;gt;&lt;br /&gt;
            &amp;lt;form phx-change=&amp;quot;select-group&amp;quot; name=&amp;quot;testbed_id&amp;quot;  &amp;gt;&lt;br /&gt;
               &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;testbed_id&amp;quot; value={testbed.id}/&amp;gt;&lt;br /&gt;
               &amp;lt;select id=&amp;quot;group-selection&amp;quot;  name=&amp;quot;group-id&amp;quot; class=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;%= for group &amp;lt;- updated_groups(testbed.id) do %&amp;gt;&lt;br /&gt;
                  &amp;lt;%= if group !== nil do %&amp;gt;&lt;br /&gt;
                      &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}&amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
                      &amp;lt;%else%&amp;gt;&lt;br /&gt;
                      &amp;lt;option value= {&amp;quot;Unassigned&amp;quot;}&amp;gt;NONE&amp;lt;/option&amp;gt;&lt;br /&gt;
                  &amp;lt;% end %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
               &amp;lt;/select&amp;gt;&lt;br /&gt;
            &amp;lt;/form&amp;gt;&lt;br /&gt;
          &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
       &amp;lt;% end %&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Developer Notes ==&lt;br /&gt;
===Groups Feature ===&lt;br /&gt;
To complete this feature do these things.&lt;br /&gt;
* Run through the steps in [http://elixirblocks.com/index.php?title=Create_Foreign_Key_Relationship_Between_Ecto_Tables  | this document] to create Group table.&lt;br /&gt;
* Groups have these fields  '''name: string''', '''description: string''' and '''color: string'''  &lt;br /&gt;
* Add unique constraint in migration file: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def change do&lt;br /&gt;
     create unique_index(:groups, [:name])&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Port over Group LiveView code (temporarily placed at discussion page).&lt;br /&gt;
* On completion '''possibly''', create a Group named '''No Group''' and set all Testbeds to it.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
________&lt;br /&gt;
https://blog.appsignal.com/2022/10/11/phoenix-liveview-018-new-special-html-attributes.html&lt;br /&gt;
https://blixtdev.com/whats-new-phoenix-1-7/&lt;br /&gt;
https://github.com/devato/inertia_phoenix&lt;br /&gt;
https://phoenixonrails.com/blog/you-can-stop-using-form-for-in-phoenix&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://samuelmullen.com/articles/phoenix_templates_rendering_and_layouts&lt;br /&gt;
&lt;br /&gt;
WorkFlow of Todo App in Both LiveView and DeadView.&lt;br /&gt;
&lt;br /&gt;
Note:&lt;br /&gt;
&lt;br /&gt;
Create foreign key data.&lt;br /&gt;
Create live view. List all testbeds and form to assign each a group by group-name.&lt;br /&gt;
&lt;br /&gt;
Repeat in dead view&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Mental model and data flows&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
home.html.heex&lt;br /&gt;
&amp;lt;a href=&amp;quot;/data&amp;quot; name=&amp;quot;we are the world&amp;quot; &amp;gt;  click me&amp;lt;/a&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;%= @message %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
page controller&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  def home(conn, _params) do&lt;br /&gt;
    IO.inspect _params&lt;br /&gt;
    render(conn, :home, message: &amp;quot;Hello&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
get &amp;quot;/:yay&amp;quot;, PageController, :index&lt;br /&gt;
&lt;br /&gt;
get &amp;quot;/&amp;quot;, PageController, :index&lt;br /&gt;
&lt;br /&gt;
* Explain control flow of &amp;quot;Dead Views&amp;quot; and the Generator HTML Control flow.&lt;br /&gt;
* Proper Way to use Modal&lt;br /&gt;
* How to give Focus to Fields in Modal (or other forms fields)&lt;br /&gt;
* &lt;br /&gt;
* &lt;br /&gt;
* How to Create Database Seed Data.&lt;br /&gt;
* How to structure code so controller code is in one file and HTML Heex is in another&lt;br /&gt;
* How to Use Generators in a Real World Project&lt;br /&gt;
* How to Work with Database Data via Basic Commands and Custom Change sets.&lt;br /&gt;
* How to Render Database Data to LiveView (via Context Commands).&lt;br /&gt;
* How to Create a Chat using PubSub.&lt;br /&gt;
* How to Create Event Handlers in LiveView&lt;br /&gt;
* How to Create a Dynamic Route from Scratch.&lt;br /&gt;
* How to Use Elixirs Template language&lt;br /&gt;
* How to Work with Modal&lt;br /&gt;
* How to Use CSS From Scratch (Without bundler)&lt;br /&gt;
* How to use JS hooks&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
______________________&lt;br /&gt;
https://studioindie.co/blog/heex-guide/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
get &amp;quot;/&amp;quot;, PageController, :some-atom    #This is the route. some-atom is the controller name&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  def some-atom(conn, _params) do                 # controller name&lt;br /&gt;
    # The home page is often custom made,&lt;br /&gt;
    # so skip the default app layout.&lt;br /&gt;
    render(conn, :some-atom, layout: false)      # :some-atom is template name&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Controllers page_html.ex contains &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageHTML do&lt;br /&gt;
  use AppWeb, :html&lt;br /&gt;
&lt;br /&gt;
  embed_templates &amp;quot;page_html/*&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''page_html''' is the name of the folder in '''Controllers/page_html'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Controllers/page_html/some-atom.html.heex  (this is the template) &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__________________________________________&lt;br /&gt;
Set all association with preload:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  def list_groups do&lt;br /&gt;
    Repo.all(Group)&lt;br /&gt;
     |&amp;gt; Repo.preload([:testbeds])&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Insert Child into Parent ===&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
App.get_group!(2) # arg is id&lt;br /&gt;
|&amp;gt; Ecto.build_assoc(:testbeds)&lt;br /&gt;
|&amp;gt; Repo.insert()&lt;br /&gt;
&lt;br /&gt;
Or&lt;br /&gt;
&lt;br /&gt;
group = App.get_group!(2) # arg is id&lt;br /&gt;
&lt;br /&gt;
testbeds = Ecto.build_assoc(group, :testbeds)&lt;br /&gt;
&lt;br /&gt;
App.Group.create_group(testbeds)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
group = App.Groups.get_group!(1)&lt;br /&gt;
thing = Ecto.build_assoc(group, :testbeds, name: &amp;quot;DUMB&amp;quot;)&lt;br /&gt;
alias App.{Repo}&lt;br /&gt;
Repo.insert(thing)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
avatar = %Avatar{nick_name: &amp;quot;Elixir&amp;quot;, pic_url: &amp;quot;http://elixir-lang.org/images/logo.png&amp;quot;}&lt;br /&gt;
user = %User{name: &amp;quot;John Doe&amp;quot;, email: &amp;quot;john.doe@example.com&amp;quot;, avatar: avatar}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://www.reddit.com/r/elixir/comments/oh318k/is_there_a_way_to_avoid_ectoassociationnotloaded/h4mmcfi/?utm_source=share&amp;amp;utm_medium=web3x&amp;amp;utm_name=web3xcss&amp;amp;utm_term=1&amp;amp;utm_content=share_button&lt;br /&gt;
&lt;br /&gt;
# Create Group Table&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
mix phx.gen.html Groups Group groups name:string  &lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Set the resources / &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
mix ecto.migrate&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For testbeds create a migration file and add this field:   group_id:references:groups&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
def change do&lt;br /&gt;
    alter table(:testbeds) do    # customize to your code&lt;br /&gt;
      add :group_id, references(:groups)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Update Groups Schema (Don't forget alias / has_many)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule App.Groups.Group do&lt;br /&gt;
	use Ecto.Schema&lt;br /&gt;
	import Ecto.Changeset&lt;br /&gt;
	alias App.Testbeds.Testbed   # Alias!&lt;br /&gt;
&lt;br /&gt;
	schema &amp;quot;posts&amp;quot; do&lt;br /&gt;
		field :body, :string&lt;br /&gt;
		field :title, :string&lt;br /&gt;
		has_many :testbeds, Testbed    # Has many&lt;br /&gt;
&lt;br /&gt;
		timestamps()&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	@doc false&lt;br /&gt;
	def changeset(post, attrs) do&lt;br /&gt;
		post&lt;br /&gt;
		|&amp;gt; cast(attrs, [:title, :body])&lt;br /&gt;
		|&amp;gt; validate_required([:title, :body])&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
TESTBEDS Schema&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule App.Testbeds.Testbed do&lt;br /&gt;
  use Ecto.Schema&lt;br /&gt;
  import Ecto.Changeset&lt;br /&gt;
  alias App.Groups.Group      # Alias&lt;br /&gt;
  schema &amp;quot;testbeds&amp;quot; do&lt;br /&gt;
    field :name, :string&lt;br /&gt;
    belongs_to :group, Group    # Belongs to&lt;br /&gt;
    timestamps()&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  @doc false&lt;br /&gt;
  def changeset(testbed, attrs) do&lt;br /&gt;
    testbed&lt;br /&gt;
    |&amp;gt; cast(attrs, [:name])&lt;br /&gt;
    |&amp;gt; validate_required([:name])&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
_____________________________________&lt;br /&gt;
Side notes.&lt;br /&gt;
&lt;br /&gt;
defmodule App.Repo.Migrations.CreateTestbeds do&lt;br /&gt;
  use Ecto.Migration&lt;br /&gt;
&lt;br /&gt;
  def change do&lt;br /&gt;
    create table(:testbeds) do&lt;br /&gt;
      add :name, :string&lt;br /&gt;
      add :group_id, references(:groups, on_delete: :nothing)&lt;br /&gt;
&lt;br /&gt;
      timestamps()&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    create index(:testbeds, [:group_id])&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
________________________________&lt;br /&gt;
&lt;br /&gt;
mix phx.gen.context Comments Comment comments name:string content:text post_id:references:posts&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
mix phx.gen.html Testbeds Testbed testbeds name:string  group_id:references:groups&lt;br /&gt;
&lt;br /&gt;
https://graffino.com/web-development/first-steps-in-elixir-and-phoenix-create-a-blog-prototype&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://blog.logrocket.com/getting-started-ecto-phoenix/&lt;br /&gt;
&lt;br /&gt;
https://serokell.io/blog/ecto-guide-for-beginners&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
mix phx.gen.html Testbeds Testbed testbeds name:string&lt;br /&gt;
&lt;br /&gt;
mix phx.gen.html Groups Group groups name:string&lt;br /&gt;
&lt;br /&gt;
Create migration for &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
mix ecto.gen.migration add_testbed_group_reference&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Migration:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  def change do&lt;br /&gt;
    alter table(:testbeds) do    # customize to your code&lt;br /&gt;
      add :group_id, references(:groups)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Manually Change:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule App.Group do&lt;br /&gt;
  use Ecto.Schema&lt;br /&gt;
&lt;br /&gt;
  schema &amp;quot;groups&amp;quot; do&lt;br /&gt;
    field :title, :string&lt;br /&gt;
    field :tagline, :string&lt;br /&gt;
    has_many :testbeds, App.Testbed&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
testbeds&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule App.Repo.Migrations.AddTextbedGroups do&lt;br /&gt;
  use Ecto.Migration&lt;br /&gt;
&lt;br /&gt;
  def change do&lt;br /&gt;
    create table(:testbeds) do&lt;br /&gt;
      add :name, :string&lt;br /&gt;
      add :group_id, references(:groups)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
# lib/app/testbeds.ex&lt;br /&gt;
&lt;br /&gt;
defmodule App.Testbed do&lt;br /&gt;
  use Ecto.Schema&lt;br /&gt;
&lt;br /&gt;
  schema &amp;quot;testbedss&amp;quot; do&lt;br /&gt;
    field :name, :string&lt;br /&gt;
    belongs_to :group, App.Group&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_____________________&lt;br /&gt;
&lt;br /&gt;
%App.TestBeds.TestBed{&lt;br /&gt;
  __meta__: #Ecto.Schema.Metadata&amp;lt;:loaded, &amp;quot;testbeds&amp;quot;&amp;gt;,&lt;br /&gt;
  id: 1,&lt;br /&gt;
  developer: &amp;quot;None&amp;quot;,&lt;br /&gt;
  name: &amp;quot;sdfsd&amp;quot;,&lt;br /&gt;
  owner: &amp;quot;sdfsddf&amp;quot;,&lt;br /&gt;
  note: &amp;quot;sdsfsddf&amp;quot;,&lt;br /&gt;
  status: &amp;quot;Available&amp;quot;,&lt;br /&gt;
  url: &amp;quot;sdf&amp;quot;,&lt;br /&gt;
  version: &amp;quot;ddf&amp;quot;,&lt;br /&gt;
  manager: &amp;quot;sf&amp;quot;,&lt;br /&gt;
  inserted_at: ~N[2023-08-21 13:45:39],&lt;br /&gt;
  updated_at: ~N[2023-08-21 13:45:44]&lt;br /&gt;
}&lt;br /&gt;
________________________________________________________________---&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.SendLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  &lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    {:ok, socket}&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  def handle_event(&amp;quot;send&amp;quot;, %{&amp;quot;text&amp;quot; =&amp;gt; text}, socket) do&lt;br /&gt;
&lt;br /&gt;
    AppWeb.Endpoint.broadcast(topic, &amp;quot;message&amp;quot;, text)&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  defp topic do&lt;br /&gt;
    &amp;quot;chat&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def render(assigns)do   &lt;br /&gt;
   ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
  &amp;lt;h1&amp;gt;Send Message&amp;lt;/h1&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;form phx-submit=&amp;quot;send&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;text&amp;quot; /&amp;gt;&lt;br /&gt;
    &amp;lt;button type=&amp;quot;submit&amp;quot;&amp;gt;Send&amp;lt;/button&amp;gt;&lt;br /&gt;
  &amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
______________________________________________________________&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.ReceiveLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  &lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    if connected?(socket) do&lt;br /&gt;
      AppWeb.Endpoint.subscribe(topic)&lt;br /&gt;
    end&lt;br /&gt;
    {:ok, assign(socket, messages: &amp;quot;&amp;quot;)}&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def handle_info(%{event: &amp;quot;message&amp;quot;, payload: message}, socket) do&lt;br /&gt;
    IO.inspect message&lt;br /&gt;
    {:noreply, assign(socket, messages: message)}&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  defp topic do&lt;br /&gt;
    &amp;quot;chat&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns)do   &lt;br /&gt;
   ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
  &amp;lt;h1&amp;gt;ChatLive&amp;lt;/h1&amp;gt;&lt;br /&gt;
  &amp;lt;%= @messages %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
______________________________________________________________&lt;br /&gt;
When you hover over a list of items this hook finds items with the same name and sets the opacity of all others to 0. You see all the items similar to the one you are hovering over.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
TestbedVersionHover: {&lt;br /&gt;
			// https://jsfiddle.net/IrvinDominin/7K2Z3/&lt;br /&gt;
            mounted() {&lt;br /&gt;
&lt;br /&gt;
                let rows = document.getElementsByClassName(&amp;quot;testbed-version&amp;quot;)&lt;br /&gt;
                // this.ele = element&lt;br /&gt;
				// rows = this.ele;&lt;br /&gt;
                &lt;br /&gt;
				for (var i = 0; i &amp;lt; rows.length; i++) {&lt;br /&gt;
					rows[i].onmouseenter = function (event) {&lt;br /&gt;
						for (var j = 0; j &amp;lt; rows.length; j++) {&lt;br /&gt;
							let preversion = this.textContent;&lt;br /&gt;
							let version = preversion.slice(0,5)&lt;br /&gt;
							let compareVersion = rows[j].textContent.slice(0,5)&lt;br /&gt;
							if (compareVersion === version) continue&lt;br /&gt;
							rows[j].className += &amp;quot; other&amp;quot;;&lt;br /&gt;
						}&lt;br /&gt;
					};&lt;br /&gt;
				&lt;br /&gt;
					rows[i].onmouseleave = function (event) {&lt;br /&gt;
						var hovers = document.getElementsByClassName('other');&lt;br /&gt;
						var len = hovers.length;&lt;br /&gt;
						for (var j = 0; j &amp;lt; len; j++) {&lt;br /&gt;
							hovers[0].className = hovers[0].className.replace(/\sother(\s|$)/, '');&lt;br /&gt;
						}&lt;br /&gt;
					};&lt;br /&gt;
				}&lt;br /&gt;
&lt;br /&gt;
                // this.ele.addEventListener(&amp;quot;click&amp;quot;, (e) =&amp;gt; {&lt;br /&gt;
                //     console.log(e.target)&lt;br /&gt;
                    &lt;br /&gt;
                // });&lt;br /&gt;
&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* How to Create Database Seed Data.&lt;br /&gt;
* How to structure code so controller code is in one file and HTML Heex is in another&lt;br /&gt;
* How to Use Generators in a Real World Project&lt;br /&gt;
* How to Work with Database Data via Basic Commands and Custom Change sets.&lt;br /&gt;
* How to Render Database Data to LiveView (via Context Commands).&lt;br /&gt;
* How to Create a Chat using PubSub.&lt;br /&gt;
* How to Create Event Handlers in LiveView&lt;br /&gt;
* How to Create a Dynamic Route from Scratch.&lt;br /&gt;
* How to Use Elixirs Template language&lt;br /&gt;
* How to Work with Modal&lt;br /&gt;
* How to Use CSS From Scratch (Without bundler)&lt;br /&gt;
* How to use JS hooks&lt;br /&gt;
* Dissect Table Component and Update it to Order List in Reverse.&lt;br /&gt;
&lt;br /&gt;
Selenium&lt;br /&gt;
https://www.builder.io/blog/debug-nodejs&lt;br /&gt;
&lt;br /&gt;
https://marketplace.visualstudio.com/items?itemName=ms-vscode.live-server#running-the-extension&lt;br /&gt;
&lt;br /&gt;
This was added recently (see microsoft/vscode#109276).&lt;br /&gt;
    1. Open the palette (Ctrl + Shift + P)&lt;br /&gt;
    2. Select &amp;quot;Simple Browser: Preview&amp;quot;&lt;br /&gt;
    3. Enter web address&lt;br /&gt;
&lt;br /&gt;
_______________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
const {By, Key, Builder} = require(&amp;quot;selenium-webdriver&amp;quot;);&lt;br /&gt;
const assert = require(&amp;quot;assert&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
require(&amp;quot;chromedriver&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
async function test_case(){&lt;br /&gt;
  let driver = await new Builder().forBrowser(&amp;quot;chrome&amp;quot;).build();&lt;br /&gt;
  await driver.get(&amp;quot;sie&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  await driver.findElement(By.name('password')).clear();&lt;br /&gt;
  await driver.findElement(By.name('identification')).clear();&lt;br /&gt;
  await driver.findElement(By.name('identification')).sendKeys(&amp;quot;bill&amp;quot;);&lt;br /&gt;
  await driver.findElement(By.name('password')).sendKeys(&amp;quot;password&amp;quot;, Key.RETURN);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 setTimeout(()=&amp;gt;{&lt;br /&gt;
   driver.findElement(By.className(&amp;quot;req_lan_license&amp;quot;)).click();&lt;br /&gt;
 },5000)&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageLive do &lt;br /&gt;
&lt;br /&gt;
  use AppWeb, :live_view  &lt;br /&gt;
  alias App.Testbeds &lt;br /&gt;
  def mount(_params, _session, socket)do   &lt;br /&gt;
     {:ok, assign(socket, testbeds: Testbeds.list_testbeds())}   &lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
    def button_event(&amp;quot;invoke_editing&amp;quot;) do&lt;br /&gt;
    %JS{}&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;active&amp;quot;, to: &amp;quot;#editing_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#editing_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#preview_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;active&amp;quot;, to: &amp;quot;#preview_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;active&amp;quot;, to: &amp;quot;#preview&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#preview&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#editing&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;active&amp;quot;, to: &amp;quot;#editing&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def button_event(&amp;quot;invoke_preview&amp;quot;) do&lt;br /&gt;
    %JS{}&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;active&amp;quot;, to: &amp;quot;#preview_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#preview_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#editing_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;active&amp;quot;, to: &amp;quot;#editing_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;active&amp;quot;, to: &amp;quot;#editing&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#editing&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#preview&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;active&amp;quot;, to: &amp;quot;#preview&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;send&amp;quot;, params, socket) do&lt;br /&gt;
    hide_modal(&amp;quot;notes-modal-0&amp;quot;)&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do  &lt;br /&gt;
     ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
		&amp;lt;.modal id={&amp;quot;notes-modal-#{testbed.id}&amp;quot;}&amp;gt;&lt;br /&gt;
		    &amp;lt;.button phx-click={button_event(&amp;quot;invoke_editing&amp;quot;)} id=&amp;quot;editing_button&amp;quot; class=&amp;quot;hidden&amp;quot;&amp;gt;&lt;br /&gt;
		      Preview&lt;br /&gt;
		    &amp;lt;/.button&amp;gt;&lt;br /&gt;
		    &amp;lt;.button phx-click={button_event(&amp;quot;invoke_preview&amp;quot;)} id=&amp;quot;preview_button&amp;quot;&amp;gt;&lt;br /&gt;
		      Edit Me&lt;br /&gt;
		    &amp;lt;/.button&amp;gt;&lt;br /&gt;
		    &amp;lt;div id=&amp;quot;editing&amp;quot;&amp;gt; PREVIEWING THE WORK&amp;lt;/div&amp;gt;&lt;br /&gt;
		    &amp;lt;form phx-submit = &amp;quot;send&amp;quot;   id=&amp;quot;preview&amp;quot; class=&amp;quot;hidden&amp;quot;&amp;gt;&lt;br /&gt;
		      &amp;lt;textarea value = {testbed.note}&amp;gt;&amp;lt;/textarea&amp;gt;&lt;br /&gt;
		      &amp;lt;.button type=&amp;quot;submit&amp;quot; phx-click={hide_modal(&amp;quot;notes-modal-#{testbed.id}&amp;quot;)}&amp;gt;SAVE WORK&amp;lt;/.button&amp;gt;&lt;br /&gt;
		    &amp;lt;/form&amp;gt;&lt;br /&gt;
		&amp;lt;/.modal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;%= if testbed.note do %&amp;gt;&lt;br /&gt;
      &amp;lt;div phx-click={show_modal(&amp;quot;notes-modal-#{testbed.id}&amp;quot;)}&amp;gt;READ ME  ...&amp;lt;%= testbed.note %&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
	   &lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
       &lt;br /&gt;
      &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
import {HfInference} from &amp;quot;@huggingface/inference&amp;quot;;&lt;br /&gt;
import dotenv from &amp;quot;dotenv&amp;quot;;&lt;br /&gt;
dotenv.config()&lt;br /&gt;
&lt;br /&gt;
const HF_ACCESS_TOKEN = process.env.HF_ACCESS_TOKEN&lt;br /&gt;
&lt;br /&gt;
const hf = new HfInference(HF_ACCESS_TOKEN);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*______Uncomment for this example______________________&lt;br /&gt;
&lt;br /&gt;
const model = &amp;quot;nlpconnect/vit-gpt2-image-captioning&amp;quot;;&lt;br /&gt;
const imageURL = &amp;quot;https://i.imgur.com/lTvb7Et.png&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
const response = await fetch(imageURL);&lt;br /&gt;
const imageBlob = await response.blob();&lt;br /&gt;
&lt;br /&gt;
const result  = await hf.imageToText({&lt;br /&gt;
	data: imageBlob,&lt;br /&gt;
	model: model,&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
_______________________________________________________*/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*________Another example ___________________*/&lt;br /&gt;
&lt;br /&gt;
const result = await hf.summarization({&lt;br /&gt;
	model: 'facebook/bart-large-cnn',&lt;br /&gt;
	inputs: &amp;quot;The role of a dumb man is to get smarter oogy bookie boo&amp;quot;,&lt;br /&gt;
	parameters:{&lt;br /&gt;
		max_length: 100&lt;br /&gt;
	}&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
console.log(result);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
________________________________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://fly.io/phoenix-files/sdeb-toggling-element/&lt;br /&gt;
https://www.youtube.com/watch?v=vBgZvQapqhs&lt;br /&gt;
&lt;br /&gt;
https://blog.testdouble.com/posts/2022-11-28-how-to-use-javascript-with-phoenix-liveview/&lt;br /&gt;
&lt;br /&gt;
https://hexdocs.pm/phoenix_live_view/0.19.3/Phoenix.Component.html&lt;br /&gt;
_______________________________________&lt;br /&gt;
https://www.smashingmagazine.com/2011/10/quick-look-math-animations-javascript/&lt;br /&gt;
* Depth first traversal&lt;br /&gt;
* Breadth first traversal&lt;br /&gt;
&lt;br /&gt;
https://dev.to/codesphere/10-algorithms-every-developer-should-learn-3lnm&lt;br /&gt;
&lt;br /&gt;
https://www.youtube.com/watch?v=fPz40W9mfCg&lt;br /&gt;
&lt;br /&gt;
__________________________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.GroupLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  alias App.TestBeds&lt;br /&gt;
  alias App.Groups&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    {:ok, assign(socket, testbeds: TestBeds.list_testbeds(), groups: Groups.list_groups())}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;select-group&amp;quot;, params, socket)  do  &lt;br /&gt;
         &lt;br /&gt;
       IO.inspect params&lt;br /&gt;
       {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div class=&amp;quot;grid grid-columns-2 grid-flow-col gap-4&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;column-1&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;%= testbed.name %&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;column-2&amp;quot;&amp;gt;    &lt;br /&gt;
            &amp;lt;form phx-change=&amp;quot;select-group&amp;quot;  &amp;gt;&lt;br /&gt;
               &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;testbed_id&amp;quot; value={testbed.id}/&amp;gt;&lt;br /&gt;
               &amp;lt;select id=&amp;quot;group-selection&amp;quot;  name=&amp;quot;group-id&amp;quot; &amp;gt;&lt;br /&gt;
                &amp;lt;%= for group &amp;lt;- @groups do %&amp;gt;&lt;br /&gt;
                  &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}  &amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
               &amp;lt;/select&amp;gt;&lt;br /&gt;
            &amp;lt;/form&amp;gt;&lt;br /&gt;
         &amp;lt;/div&amp;gt;&lt;br /&gt;
       &amp;lt;% end %&amp;gt;&lt;br /&gt;
   &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
____________________________&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.GroupLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  alias App.TestBeds&lt;br /&gt;
  alias App.Groups&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
&lt;br /&gt;
    {:ok, assign(socket, testbeds: TestBeds.list_testbeds(), groups: Groups.list_groups(), messages: [])}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;select-group&amp;quot;, params, socket)  do  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
      group = App.Groups.get_group!(params[&amp;quot;group-id&amp;quot;])&lt;br /&gt;
       # IO.inspect group&lt;br /&gt;
       testbed = App.TestBeds.get_test_bed!(params[&amp;quot;testbed_id&amp;quot;])&lt;br /&gt;
     &lt;br /&gt;
       App.TestBeds.update_test_bed(testbed, %{group_id: group.id})&lt;br /&gt;
         &lt;br /&gt;
    &lt;br /&gt;
       {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def updated_groups(testbed_id)  do  &lt;br /&gt;
       groups = App.Groups.list_groups&lt;br /&gt;
       tail = Enum.filter(groups, fn(item)-&amp;gt; item.id !== testbed_id end)&lt;br /&gt;
       head = Enum.filter(groups, fn(item)-&amp;gt; item.id == testbed_id end)&lt;br /&gt;
              |&amp;gt;Enum.at(0)&lt;br /&gt;
     [head | tail]&lt;br /&gt;
         &lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
 # def handle_event(&amp;quot;groups&amp;quot;, params, socket)do  &lt;br /&gt;
 #       selected_testbed = %{name: &amp;quot;my testbed name&amp;quot;, id: 3}&lt;br /&gt;
 #       groups = App.Groups.list_groups&lt;br /&gt;
 #       tail = Enum.filter(groups, fn(item)-&amp;gt; item.id !== selected_testbed.id end)&lt;br /&gt;
 #       head = Enum.filter(groups, fn(item)-&amp;gt; item.id == selected_testbed.id end)&lt;br /&gt;
 #              |&amp;gt;Enum.at(0)&lt;br /&gt;
         &lt;br /&gt;
 &lt;br /&gt;
 #       # result = Enum.filter([1, 2, 3], fn x -&amp;gt; x.id !== 1 end)&lt;br /&gt;
 #      IO.inspect [head | tail]&lt;br /&gt;
         &lt;br /&gt;
 #      #&lt;br /&gt;
 #      {:noreply, socket, assigns.message:}&lt;br /&gt;
 #  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    &lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
       &amp;lt;%!-- &amp;lt;div phx-click = &amp;quot;groups&amp;quot;&amp;gt;CLICK ME&amp;lt;/div&amp;gt; --%&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;grid grid-cols-4 gap-4 p-8 rounded shadow bg-white&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;h2&amp;gt; Name&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;%= testbed.name %&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;h2&amp;gt; Group&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;form phx-change=&amp;quot;select-group&amp;quot; name=&amp;quot;testbed_id&amp;quot;  &amp;gt;&lt;br /&gt;
               &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;testbed_id&amp;quot; value={testbed.id}/&amp;gt;&lt;br /&gt;
               &amp;lt;select id=&amp;quot;group-selection&amp;quot;  name=&amp;quot;group-id&amp;quot; class=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
                &amp;lt;%= for group &amp;lt;- updated_groups(testbed.id) do %&amp;gt;&lt;br /&gt;
                  &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}  &amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
                  &amp;lt;!-- Write code to reorder with testbed.group_id matching group_id --&amp;gt;&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
               &amp;lt;/select&amp;gt;&lt;br /&gt;
            &amp;lt;/form&amp;gt;&lt;br /&gt;
          &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
       &amp;lt;% end %&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_____________________________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
   use AppWeb, :live_view  &lt;br /&gt;
     alias App.Testbeds&lt;br /&gt;
  alias App.Groups&lt;br /&gt;
   def mount(_params, _session, socket)  do&lt;br /&gt;
	     {:ok, assign(socket, testbeds: Testbeds.list_testbeds(), groups: Groups.list_groups())}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
   def handle_event(&amp;quot;select-group&amp;quot;, params, socket)  do  &lt;br /&gt;
       group = App.Groups.get_group!(params[&amp;quot;group-id&amp;quot;])&lt;br /&gt;
       testbed = App.Testbeds.get_testbed!(params[&amp;quot;testbed_id&amp;quot;])&lt;br /&gt;
       result = App.Testbeds.update_testbed(testbed, %{group_id: group.id})&lt;br /&gt;
       IO.inspect result&lt;br /&gt;
      &lt;br /&gt;
       {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
    def updated_groups(testbed_id)  do  &lt;br /&gt;
       testbed = App.Testbeds.get_testbed!(testbed_id)&lt;br /&gt;
       groups = App.Groups.list_groups&lt;br /&gt;
       tail = Enum.filter(groups, fn(item)-&amp;gt; item.id !== testbed.group_id end)&lt;br /&gt;
       head = Enum.filter(groups, fn(item)-&amp;gt; item.id == testbed.group_id end)&lt;br /&gt;
              |&amp;gt;Enum.at(0)&lt;br /&gt;
 &lt;br /&gt;
       [head | tail]&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    &lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;grid grid-cols-4 gap-4 p-8 rounded shadow bg-white&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;h2&amp;gt; Name&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;%= testbed.name %&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;h2&amp;gt; Group&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;form phx-change=&amp;quot;select-group&amp;quot; name=&amp;quot;testbed_id&amp;quot;  &amp;gt;&lt;br /&gt;
               &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;testbed_id&amp;quot; value={testbed.id}/&amp;gt;&lt;br /&gt;
               &amp;lt;select id=&amp;quot;group-selection&amp;quot;  name=&amp;quot;group-id&amp;quot; class=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
                &amp;lt;%= for group &amp;lt;- updated_groups(testbed.id) do %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
                  &amp;lt;%!-- &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}&amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt; --%&amp;gt;&lt;br /&gt;
                  &amp;lt;!-- Write code to reorder with testbed.group_id matching group_id --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
                  &amp;lt;%= if group !== nil do %&amp;gt;&lt;br /&gt;
                      &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}&amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
       &lt;br /&gt;
                  &amp;lt;% end %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
               &amp;lt;/select&amp;gt;&lt;br /&gt;
            &amp;lt;/form&amp;gt;&lt;br /&gt;
          &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
       &amp;lt;% end %&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  has_many :testbeds, TestBed, on_delete: :restrict   # Has many&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://elixirforum.com/t/ecto-has-many-on-delete-protect/49550&lt;br /&gt;
&lt;br /&gt;
https://hexdocs.pm/ecto/Ecto.Changeset.html#unique_constraint/3&lt;br /&gt;
&lt;br /&gt;
____________________________________________________________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== How to Create a Mix Project and Use It in Another Mix Project ==&lt;br /&gt;
&lt;br /&gt;
To create and use a **Mix project** inside another **Mix project** in Elixir, follow the steps below:&lt;br /&gt;
&lt;br /&gt;
=== 1. Create a New Mix Project ===&lt;br /&gt;
&lt;br /&gt;
First, you need to create a new Mix project. Let's call this project `library_project`. Run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mix new library_project --module LibraryProject&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will create a new Elixir Mix project named `library_project`. The `--module` flag specifies the name of the module that will be created (in this case `LibraryProject`).&lt;br /&gt;
&lt;br /&gt;
The directory structure of `library_project` will look like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
library_project/&lt;br /&gt;
  |_ lib/&lt;br /&gt;
      |_ library_project.ex&lt;br /&gt;
  |_ mix.exs&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can then add some basic functionality inside the `library_project/lib/library_project.ex` file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule LibraryProject do&lt;br /&gt;
  def hello do&lt;br /&gt;
    IO.puts &amp;quot;Hello from LibraryProject!&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now, `library_project` is ready to be used by another Mix project.&lt;br /&gt;
&lt;br /&gt;
=== 2. Create a Second Mix Project ===&lt;br /&gt;
&lt;br /&gt;
Next, create the second Mix project where you want to use `library_project`. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mix new app_project --module AppProject&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will create another Elixir project called `app_project`.&lt;br /&gt;
&lt;br /&gt;
The directory structure for this project will look like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
app_project/&lt;br /&gt;
  |_ lib/&lt;br /&gt;
      |_ app_project.ex&lt;br /&gt;
  |_ mix.exs&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 3. Add `library_project` as a Dependency in `app_project` ===&lt;br /&gt;
&lt;br /&gt;
Now, you want to make `library_project` available in `app_project`. There are two main ways to do this:&lt;br /&gt;
&lt;br /&gt;
==== Option 1: Local Dependency (via `path`) ====&lt;br /&gt;
&lt;br /&gt;
If `library_project` is a local project (i.e., it's stored in a different directory), you can add it to the `mix.exs` of `app_project` as a local dependency by specifying the path to `library_project`.&lt;br /&gt;
&lt;br /&gt;
Edit the `mix.exs` of `app_project`:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule AppProject.MixProject do&lt;br /&gt;
  use Mix.Project&lt;br /&gt;
&lt;br /&gt;
  def project do&lt;br /&gt;
    [&lt;br /&gt;
      app: :app_project,&lt;br /&gt;
      version: &amp;quot;0.1.0&amp;quot;,&lt;br /&gt;
      elixir: &amp;quot;~&amp;gt; 1.14&amp;quot;,&lt;br /&gt;
      start_permanent: Mix.env() == :prod,&lt;br /&gt;
      deps: deps()&lt;br /&gt;
    ]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  defp deps do&lt;br /&gt;
    [&lt;br /&gt;
      {:library_project, path: &amp;quot;../library_project&amp;quot;}  # Add the local dependency&lt;br /&gt;
    ]&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here, `{:library_project, path: &amp;quot;../library_project&amp;quot;}` tells Mix to use the local `library_project` located in the `../library_project` directory (relative to `app_project`).&lt;br /&gt;
&lt;br /&gt;
After updating the `mix.exs`, run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd app_project&lt;br /&gt;
mix deps.get&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will fetch the dependency and compile `library_project`.&lt;br /&gt;
&lt;br /&gt;
==== Option 2: Publish and Fetch as a Hex Package ====&lt;br /&gt;
&lt;br /&gt;
If you want to use `library_project` as a package in another project (for example, by publishing it to **Hex.pm**, Elixir’s package manager), you need to publish it to Hex and then add it as a dependency.&lt;br /&gt;
&lt;br /&gt;
1. Publish `library_project` to Hex (if it's public or for your private use).&lt;br /&gt;
2. Add `library_project` to your `app_project`’s `mix.exs` dependencies:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defp deps do&lt;br /&gt;
  [&lt;br /&gt;
    {:library_project, &amp;quot;~&amp;gt; 0.1.0&amp;quot;}  # Specify the published version from Hex&lt;br /&gt;
  ]&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Run `mix deps.get` to fetch the package from Hex.&lt;br /&gt;
&lt;br /&gt;
=== 4. Use `library_project` in `app_project` ===&lt;br /&gt;
&lt;br /&gt;
Now, you can use the functionality from `library_project` inside your `app_project`. For example, in `app_project/lib/app_project.ex`, you can call the function from `library_project`:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule AppProject do&lt;br /&gt;
  def start do&lt;br /&gt;
    IO.puts &amp;quot;Starting app_project!&amp;quot;&lt;br /&gt;
    LibraryProject.hello()  # Call the function from the library_project&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 5. Run the App ===&lt;br /&gt;
&lt;br /&gt;
Finally, you can run your `app_project`:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd app_project&lt;br /&gt;
mix run -e &amp;quot;AppProject.start()&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will print:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Starting app_project!&lt;br /&gt;
Hello from LibraryProject!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Recap of the Process ==&lt;br /&gt;
1. **Create the `library_project`**: Use `mix new` to generate a library project.&lt;br /&gt;
2. **Create the `app_project`**: Create the second project where you will use the library.&lt;br /&gt;
3. **Add the `library_project` as a dependency**:&lt;br /&gt;
   - Use the `path` option to point to the local project or publish it to Hex for public access.&lt;br /&gt;
4. **Use the `library_project` in the `app_project`**: Call functions or use modules from the library inside the second project.&lt;br /&gt;
5. **Run the app**: Use `mix run` to execute the project.&lt;br /&gt;
&lt;br /&gt;
This way, you can reuse code from one Mix project in another by adding it as a dependency.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==z==&lt;br /&gt;
Overloaded functions are extremely common in Elixir applications. They are&lt;br /&gt;
regularly used for recursive functions and for changing behavior based on&lt;br /&gt;
configuration.&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>http://elixirblocks.com/index.php?title=User:Admin&amp;diff=1871</id>
		<title>User:Admin</title>
		<link rel="alternate" type="text/html" href="http://elixirblocks.com/index.php?title=User:Admin&amp;diff=1871"/>
		<updated>2024-12-23T01:09:08Z</updated>

		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;________________________________________________________&lt;br /&gt;
&lt;br /&gt;
# CRUD Forms&lt;br /&gt;
&lt;br /&gt;
To understand CRUD forms you will need to understand the following concepts. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Ecto Schema&lt;br /&gt;
* Ecto Context&lt;br /&gt;
* Form Basics&lt;br /&gt;
* form/1&lt;br /&gt;
* simple_form/1&lt;br /&gt;
* changesets&lt;br /&gt;
&lt;br /&gt;
We are not going to go in order. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The Context provides CRUD functions for the chosen data schema. Phoenix contexts define the interface through which other parts of the codebase can interact with the app layer.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_______________________________________________________&lt;br /&gt;
In that case, you really should switch it to prod mode. Instead of doing all that above with the &amp;quot;config/secret.exs&amp;quot; file, create the &amp;quot;.env&amp;quot; in the project root, then add DotenvParser.load_file(&amp;quot;.env&amp;quot;) to &amp;quot;config/runtime.exs&amp;quot; as the first line inside the if config_env() == :prod do. In the .env file, set the DATABASE_URL and SECRET_KEY_BASE. Then run it as MIX_ENV=prod mix phx.server.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def get_titles do&lt;br /&gt;
    urls = [&lt;br /&gt;
      &amp;quot;https://cointelegraph.com/rss&amp;quot;,&lt;br /&gt;
      &amp;quot;https://chaski.huffpost.com/us/auto/vertical/us-news&amp;quot;&lt;br /&gt;
      # Add more RSS feed URLs here&lt;br /&gt;
    ]&lt;br /&gt;
&lt;br /&gt;
    urls&lt;br /&gt;
    |&amp;gt; Enum.map(fn url -&amp;gt;&lt;br /&gt;
      with {:ok, feed} &amp;lt;- ElixirRss.fetch_and_parse(url) do&lt;br /&gt;
        Enum.map(feed.entries, &amp;amp; &amp;amp;1.title)&lt;br /&gt;
      else&lt;br /&gt;
        {:error, reason} -&amp;gt; {:error, reason}&lt;br /&gt;
      end&lt;br /&gt;
    end)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule App do&lt;br /&gt;
&lt;br /&gt;
  def get_titles() do&lt;br /&gt;
    data = [&lt;br /&gt;
      &amp;quot;https://cointelegraph.com/rss&amp;quot;,&lt;br /&gt;
      &amp;quot;https://chaski.huffpost.com/us/auto/vertical/us-news&amp;quot;&lt;br /&gt;
      # Add more RSS feed URLs here&lt;br /&gt;
    ]&lt;br /&gt;
&lt;br /&gt;
    data&lt;br /&gt;
    |&amp;gt; Enum.map(fn url -&amp;gt;&lt;br /&gt;
      case ElixirRss.fetch_and_parse(url) do&lt;br /&gt;
        {:ok, feed} -&amp;gt; feed.entries |&amp;gt; Enum.map(fn entry -&amp;gt; entry end)&lt;br /&gt;
        {:error, reason} -&amp;gt; {:error, reason}&lt;br /&gt;
      end&lt;br /&gt;
    end)&lt;br /&gt;
    |&amp;gt; Enum.map(fn entry_list -&amp;gt;&lt;br /&gt;
      entry_list&lt;br /&gt;
      |&amp;gt; Enum.map(fn entry -&amp;gt; entry.title end)&lt;br /&gt;
    end)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def hello do&lt;br /&gt;
    rss_feeds = [&lt;br /&gt;
      &amp;quot;https://cointelegraph.com/rss&amp;quot;,&lt;br /&gt;
      &amp;quot;https://chaski.huffpost.com/us/auto/vertical/us-news&amp;quot;&lt;br /&gt;
      # Add more RSS feed URLs here&lt;br /&gt;
    ]&lt;br /&gt;
&lt;br /&gt;
    rss_feeds&lt;br /&gt;
    |&amp;gt; Enum.map(fn url -&amp;gt;&lt;br /&gt;
      case ElixirRss.fetch_and_parse(url) do&lt;br /&gt;
        {:ok, feed} -&amp;gt; feed.entries |&amp;gt; Enum.map(fn entry -&amp;gt; entry end)&lt;br /&gt;
        {:error, reason} -&amp;gt; {:error, reason}&lt;br /&gt;
      end&lt;br /&gt;
    end)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    if connected?(socket) do&lt;br /&gt;
      Phoenix.PubSub.subscribe(App.PubSub, &amp;quot;message&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
    {:ok, assign(socket, message_item: &amp;quot;different&amp;quot;)}&lt;br /&gt;
  end&lt;br /&gt;
  def handle_info({:pubsub_transmission, text}, socket) do&lt;br /&gt;
    IO.inspect &amp;quot;pub sub working&amp;quot;&lt;br /&gt;
    {:noreply, assign(socket, message_item: text)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def loop(data) do&lt;br /&gt;
     IO.inspect data&lt;br /&gt;
     if data &amp;gt; 0 do&lt;br /&gt;
      IO.inspect &amp;quot;notify&amp;quot;&lt;br /&gt;
      # run code to compare files, loop. If different run pubsub code below&lt;br /&gt;
      :timer.sleep(2000)&lt;br /&gt;
      loop(data-1)&lt;br /&gt;
&lt;br /&gt;
     end&lt;br /&gt;
     if data &amp;lt;= 0 do&lt;br /&gt;
&lt;br /&gt;
      Phoenix.PubSub.broadcast(App.PubSub, &amp;quot;message&amp;quot;, {:pubsub_transmission, &amp;quot;data&amp;quot;})&lt;br /&gt;
      &amp;quot;done&amp;quot;&lt;br /&gt;
     end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;change-text&amp;quot;, _params, socket) do&lt;br /&gt;
    spawn(fn -&amp;gt; loop(3) end)&lt;br /&gt;
    {:noreply, assign(socket, message_item: &amp;quot;START&amp;quot; )}&lt;br /&gt;
  end&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
&lt;br /&gt;
    # AppWeb.PageLive.loop(&amp;quot;xxx&amp;quot;)&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    SANDBOX&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;.button phx-click=&amp;quot;change-text&amp;quot; value={@message_item}&amp;gt;CLICK ME&amp;lt;/.button&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;%= @message_item %&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
elixir :   1.16.2&lt;br /&gt;
&lt;br /&gt;
Erl:   20&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# PostGres&lt;br /&gt;
Created Saturday 18 February 2023&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Launch [PostGres](#PostGres) from Terminal&lt;br /&gt;
------------------------------------------&lt;br /&gt;
sudo -u postgres psql&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Set User Permission&lt;br /&gt;
-------------------&lt;br /&gt;
&amp;lt;https://commandprompt.com/education/how-to-create-a-superuser-in-postgresql/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ALTER USER user_name WITH PASSWORD 'new_password';&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Run Post Gres Commands&lt;br /&gt;
----------------------&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
sudo -i -u postgres&lt;br /&gt;
psql&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Create and Delete Database&lt;br /&gt;
&lt;br /&gt;
CREATE DATABASE name;&lt;br /&gt;
DROP DATABASE name;&lt;br /&gt;
## View user list&lt;br /&gt;
&lt;br /&gt;
\du&lt;br /&gt;
&lt;br /&gt;
 View all databases&lt;br /&gt;
&lt;br /&gt;
postgres=# \l&lt;br /&gt;
&lt;br /&gt;
 Change databases&lt;br /&gt;
&lt;br /&gt;
postgres=# \c    name-of-database&lt;br /&gt;
&lt;br /&gt;
View Tables&lt;br /&gt;
&lt;br /&gt;
After you change databases and are selected on one of them do this:&lt;br /&gt;
&lt;br /&gt;
\dt&lt;br /&gt;
&lt;br /&gt;
SELECT * FROM mytablename;&lt;br /&gt;
&lt;br /&gt;
EMPTY TABLE&lt;br /&gt;
DELETE FROM name-of-table&lt;br /&gt;
&lt;br /&gt;
CREATE TABLE&lt;br /&gt;
&lt;br /&gt;
CREATE TABLE table_name(&lt;br /&gt;
   column1 datatype,&lt;br /&gt;
   column2 datatype,&lt;br /&gt;
   column3 datatype,&lt;br /&gt;
   .....&lt;br /&gt;
   columnN datatype,&lt;br /&gt;
   PRIMARY KEY( one or more columns )&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
INSERT&lt;br /&gt;
&lt;br /&gt;
INSERT INTO ITEMS(id, name) VALUES(1,'htvjbjbgni');     Strings are single quote&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Roadmap==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.ItemsLive do&lt;br /&gt;
    use AppWeb, :live_view  &lt;br /&gt;
    def mount(_params, _session, socket)  do&lt;br /&gt;
      {:ok, assign(socket, switches: [&amp;quot;grindy&amp;quot;,&amp;quot;sonic&amp;quot;,&amp;quot;ogre&amp;quot;])}  &lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    def handle_event(&amp;quot;run&amp;quot;,_params,socket) do  &lt;br /&gt;
        &lt;br /&gt;
        IO.inspect &amp;quot;DOWNLOAD VIA SSH&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        {:noreply, redirect(socket, to: &amp;quot;/download&amp;quot;)}&lt;br /&gt;
&lt;br /&gt;
    end&lt;br /&gt;
   &lt;br /&gt;
&lt;br /&gt;
    def render(assigns) do&lt;br /&gt;
        &lt;br /&gt;
        ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        &amp;lt;ul&amp;gt;&lt;br /&gt;
        &amp;lt;%= for switch &amp;lt;- @switches do %&amp;gt;&lt;br /&gt;
         &amp;lt;a phx-submit=&amp;quot;click&amp;quot; href=&amp;quot;/download&amp;quot;&amp;gt;  &amp;lt;li&amp;gt; &amp;lt;%= switch %&amp;gt;  &amp;lt;/li&amp;gt; &amp;lt;/a&amp;gt;&lt;br /&gt;
&lt;br /&gt;
        &amp;lt;%end%&amp;gt;&lt;br /&gt;
        &amp;lt;/ul&amp;gt;&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot; &lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Notes==&lt;br /&gt;
List of Switches and the option to select the one needed.&lt;br /&gt;
Button to download JSON file.&lt;br /&gt;
Drag and Drop Palette to upload JSON file.&lt;br /&gt;
&lt;br /&gt;
After JSON file is uploaded a button titled &amp;quot;Make Active&amp;quot; is available.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://medium.com/@fraiha26/pushing-events-to-livecomponents-from-js-hooks-w-phoenix-elixir-d5544d4c3dfa&lt;br /&gt;
&lt;br /&gt;
Changeset notes and forms&lt;br /&gt;
&lt;br /&gt;
NOTE: Use case statements for pattern matching&lt;br /&gt;
____________________________________________&lt;br /&gt;
&lt;br /&gt;
Create a basic &amp;lt;.form&amp;gt;&amp;lt;/form&amp;gt; without error handling&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&amp;lt;.form :let={f} for={@changeset}  action={~p&amp;quot;/items&amp;quot;} &amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;.input field={f[:title]} type=&amp;quot;text&amp;quot; label=&amp;quot;Title&amp;quot; /&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
  &amp;lt;.button&amp;gt;Save Item&amp;lt;/.button&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;/.form&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With error handling looks like this:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;.form :let={f} for={@changeset}  action={~p&amp;quot;/items&amp;quot;} &amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;.error :if={@changeset.action}&amp;gt;&lt;br /&gt;
    Oops, something went wrong! Please check the errors below.&lt;br /&gt;
  &amp;lt;/.error&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;.input field={f[:title]} type=&amp;quot;text&amp;quot; label=&amp;quot;Title&amp;quot; /&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
  &amp;lt;.button&amp;gt;Save Item&amp;lt;/.button&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;/.form&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Create the routes for render and post to endpoint.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The controller for the page render needs to pass in the changeset via ```Items.change_item(%Item{})```&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  def new(conn, _params) do&lt;br /&gt;
    changeset = Items.change_item(%Item{})&lt;br /&gt;
    render(conn, :new, changeset: changeset)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Post route without error handling&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  def create(conn, %{&amp;quot;item&amp;quot; =&amp;gt; item_params}) do&lt;br /&gt;
    case Items.create_item(item_params) do&lt;br /&gt;
      {:ok, item} -&amp;gt;&lt;br /&gt;
        conn&lt;br /&gt;
        |&amp;gt; put_flash(:info, &amp;quot;Item created successfully.&amp;quot;)&lt;br /&gt;
        |&amp;gt; redirect(to: ~p&amp;quot;/items/#{item}&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With error handling&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  def create(conn, %{&amp;quot;item&amp;quot; =&amp;gt; item_params}) do&lt;br /&gt;
    case Items.create_item(item_params) do&lt;br /&gt;
      {:ok, item} -&amp;gt;&lt;br /&gt;
        conn&lt;br /&gt;
        |&amp;gt; put_flash(:info, &amp;quot;Item created successfully.&amp;quot;)&lt;br /&gt;
        |&amp;gt; redirect(to: ~p&amp;quot;/items/#{item}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
      {:error, %Ecto.Changeset{} = changeset} -&amp;gt;&lt;br /&gt;
        render(conn, :new, changeset: changeset)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_____________________________________________&lt;br /&gt;
https://medium.com/@vincentlin/phoenix-very-simple-form-c4b121697fcb&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''home.html.heex'''&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&amp;lt;form action=&amp;quot;/submit&amp;quot; method=&amp;quot;post&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;label for=&amp;quot;name&amp;quot;&amp;gt;Name:&amp;lt;/label&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;input type=&amp;quot;text&amp;quot; id=&amp;quot;name&amp;quot; name=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;_csrf_token&amp;quot; value={@csrf_token} /&amp;gt;&lt;br /&gt;
  &amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Submit&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
page_controller.ex&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.PageController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  def home(conn, _params) do&lt;br /&gt;
    # The home page is often custom made,&lt;br /&gt;
&lt;br /&gt;
    csrf_token = Plug.CSRFProtection.get_csrf_token()&lt;br /&gt;
    render(conn, :home, csrf_token: csrf_token)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def submit(conn, _params) do&lt;br /&gt;
    # The home page is often custom made,&lt;br /&gt;
     IO.inspect(_params)&lt;br /&gt;
     IO.inspect &amp;quot;___________________________&amp;quot;&lt;br /&gt;
    csrf_token = Plug.CSRFProtection.get_csrf_token()&lt;br /&gt;
    render(conn, :home, csrf_token: csrf_token)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
router.ex&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  scope &amp;quot;/&amp;quot;, AppWeb do&lt;br /&gt;
    pipe_through :browser&lt;br /&gt;
    post &amp;quot;/submit&amp;quot;, PageController, :submit&lt;br /&gt;
    get &amp;quot;/&amp;quot;, PageController, :home&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ecto.Adapters.SQL.query(Repo, &amp;quot;select * from artists where id=1&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ecto cheatsheet:  https://hexdocs.pm/ecto/crud.html&lt;br /&gt;
__________________________________________________________________&lt;br /&gt;
Most programming languages give you the ability to set global state by creating globally scoped variables. Elixir does not do this. Instead, Elixir provides a tool called a &amp;quot;processes&amp;quot; to persist  state. Elixir applications are composed of these &amp;quot;processes&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
Processes by themselves are complicated to use, thus Elixir provides abstractions to make working with processes easier. One of these abstractions is called a GenServer.&lt;br /&gt;
&lt;br /&gt;
GenServers are not only used to store state, they are also used to invoke work independent of the main application process. &lt;br /&gt;
&lt;br /&gt;
==Creating a GenServer to Store State==&lt;br /&gt;
&lt;br /&gt;
To Create a GenServer, start by creating a basic Module that ''uses'' the GenServer module (image below)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule App do  &lt;br /&gt;
  use GenServer&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We now need to describe the actions we want to perform. Being that this is used to store state, we will use basic CRUD actions: Create, Read, Update, Delete. To begins, empty functions describing each action is created.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule App do&lt;br /&gt;
   def create do &lt;br /&gt;
&lt;br /&gt;
   end&lt;br /&gt;
   def read do &lt;br /&gt;
&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
   def update do  &lt;br /&gt;
&lt;br /&gt;
   end &lt;br /&gt;
&lt;br /&gt;
   def delete do &lt;br /&gt;
&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==What now?==&lt;br /&gt;
&lt;br /&gt;
To fill in the functions with the appropriate code we must first have a basic understanding of how GenServers are structured.&lt;br /&gt;
&lt;br /&gt;
GenServers are composed of the GenServer module invoking callbacks. The callbacks have built in names that you, as a developer have to use.&lt;br /&gt;
&lt;br /&gt;
These callbacks are named:&lt;br /&gt;
&lt;br /&gt;
* init&lt;br /&gt;
* handle_cast&lt;br /&gt;
* handle_call&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To demonstrate, here is an example :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{:ok, pid} = GenServer.start(ModuleNameOfGenServer, %{})&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above function named &amp;quot;start&amp;quot; calls the function named init in the Module below.&lt;br /&gt;
In GenServer syntax the name of the GenServer functions always invoke callbacks that are determined by the language. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule ModuleNameOfGenServer do&lt;br /&gt;
  # 1&lt;br /&gt;
  def init(state \\ %{}) do&lt;br /&gt;
    {:ok, state}&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is a list of the GenServer functions and their corresponding callbacks.&lt;br /&gt;
&lt;br /&gt;
* GenServer.start/1  --&amp;gt;       init/1&lt;br /&gt;
* GenServer.call/3   --&amp;gt;       def handle_call/3&lt;br /&gt;
* GenServer.cast/2   --&amp;gt;       handle_cast/2&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Start and Call ==&lt;br /&gt;
&lt;br /&gt;
Call and Cast can be used to perform the same operations. The &lt;br /&gt;
&lt;br /&gt;
__________________________________________________________&lt;br /&gt;
Genserver timed events&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule Go do&lt;br /&gt;
  use GenServer&lt;br /&gt;
&lt;br /&gt;
  def go() do&lt;br /&gt;
    GenServer.start_link(__MODULE__, [])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def init(list) do&lt;br /&gt;
    :timer.apply_interval(1000, __MODULE__, :add, [self(), &amp;quot;weeeee&amp;quot;])&lt;br /&gt;
    {:ok, list}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def view(pid) do&lt;br /&gt;
    GenServer.call(pid, :view)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_call(:view, _from, list) do&lt;br /&gt;
    {:reply, list, list}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def add(pid, new_item) do&lt;br /&gt;
    GenServer.call(pid, {:item, new_item})&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_call({:item, new_item}, _from, state) do&lt;br /&gt;
    result = [new_item] ++ state&lt;br /&gt;
    {:reply, result, result}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule ShoppingList do&lt;br /&gt;
  use GenServer&lt;br /&gt;
&lt;br /&gt;
  def start_link() do&lt;br /&gt;
    GenServer.start_link(ShoppingList, [])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def init(list) do&lt;br /&gt;
    {:ok, list}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def view(pid) do&lt;br /&gt;
    GenServer.call(pid, :view)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_call(:view, _from, list) do&lt;br /&gt;
    {:reply, list, list}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def add(pid, new_item) do&lt;br /&gt;
    GenServer.call(pid, {:item, new_item})&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_call({:item, new_item}, _from, state) do&lt;br /&gt;
    result = [new_item] ++ state&lt;br /&gt;
    {:reply, result, result}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://blog.appsignal.com/2018/06/12/elixir-alchemy-deconstructing-genservers.html&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule KeyValue do&lt;br /&gt;
  # 1&lt;br /&gt;
  def init(state \\ %{}) do&lt;br /&gt;
    {:ok, state}&lt;br /&gt;
  end&lt;br /&gt;
 &lt;br /&gt;
  # 2&lt;br /&gt;
  def handle_cast({:put, key, value}, state) do&lt;br /&gt;
    {:noreply, Map.put(state, key, value)}&lt;br /&gt;
  end&lt;br /&gt;
 &lt;br /&gt;
  # 3&lt;br /&gt;
  def handle_call({:get, key}, _from, state) do&lt;br /&gt;
    {:reply, Map.fetch!(state, key), state}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
# {:ok, pid} = GenServer.start(KeyValue, %{})&lt;br /&gt;
# GenServer.cast(pid, {:put, :foo, &amp;quot;bar&amp;quot;})&lt;br /&gt;
# GenServer.call(pid, {:get, :foo})&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Send messages via these functions wrapped in module functions .You can look at these are functions used to fire &amp;quot;GenServer Events&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
* start_link&lt;br /&gt;
* GenServer.call&lt;br /&gt;
* GenServer.cast&lt;br /&gt;
&lt;br /&gt;
The corresponding server functions that reply are:&lt;br /&gt;
&lt;br /&gt;
* init&lt;br /&gt;
* handle__call&lt;br /&gt;
* handle_cast&lt;br /&gt;
* &lt;br /&gt;
&lt;br /&gt;
These can be looked at as &amp;quot;listeners&amp;quot; - in JavaScript parlance. &lt;br /&gt;
__________________________________________&lt;br /&gt;
&lt;br /&gt;
If you have experience with programming languages other than Elixir the idea of GenServers may be very foreign and require a strong context shift to learn. This document is intended to simplify the concept.&lt;br /&gt;
&lt;br /&gt;
* What: GenServers are simply a way to hold state and/or invoke actions based on incoming events. &lt;br /&gt;
* when &lt;br /&gt;
* where&lt;br /&gt;
* why&lt;br /&gt;
* how&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
___________________________________________&lt;br /&gt;
GenServer timer example&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule Timer do&lt;br /&gt;
  use GenServer&lt;br /&gt;
&lt;br /&gt;
  def init(_) do&lt;br /&gt;
    :timer.send_interval(1000, :xyz)&lt;br /&gt;
    {:ok, 0}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_info(:xyz, state) do&lt;br /&gt;
    IO.inspect(state)&lt;br /&gt;
    {:noreply, state + 1}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
[&lt;br /&gt;
   {&lt;br /&gt;
     data:{&lt;br /&gt;
        creationTime,&lt;br /&gt;
        publishDate,&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
     featured:{&lt;br /&gt;
        setAmount,&lt;br /&gt;
        items:[]&lt;br /&gt;
     },&lt;br /&gt;
&lt;br /&gt;
     children:{&lt;br /&gt;
        setAmount,&lt;br /&gt;
        items:[]&lt;br /&gt;
     },&lt;br /&gt;
     links:{&lt;br /&gt;
        setAmount,&lt;br /&gt;
        items:[]&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
jason.encode / jason.decode&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  def run(num) do&lt;br /&gt;
&lt;br /&gt;
    Enum.each(0..99999, fn(_x) -&amp;gt;&lt;br /&gt;
      task = Task.async(fn -&amp;gt; num + _x end)&lt;br /&gt;
    IO.inspect Task.await(task)&lt;br /&gt;
  end)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enum.map(feed.entries, fn x -&amp;gt; %{url: x.url, title: x.title} end)&lt;br /&gt;
&lt;br /&gt;
App is split:&lt;br /&gt;
&lt;br /&gt;
App that captures RSS in UI and lets admin select stories. THere are settings to determine the number of FEATURED,CHILD and LINK stories.&lt;br /&gt;
News categories are horizontal and scrollable.&lt;br /&gt;
This exports a json doc with all RSS data for each story.&lt;br /&gt;
The &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
App that reads the json data. This app creates tables and is the front end.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://stephenbussey.com/tags/elixir.html&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule AppWeb.GroupLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  alias App.TestBeds&lt;br /&gt;
  alias App.Groups&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    {:ok, assign(socket, testbeds: TestBeds.list_testbeds(), groups: Groups.list_groups())}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;select-group&amp;quot;, params, socket)  do  &lt;br /&gt;
     group = App.Groups.get_group!(params[&amp;quot;group-id&amp;quot;])&lt;br /&gt;
     testbed = App.TestBeds.get_test_bed!(params[&amp;quot;testbed_id&amp;quot;])&lt;br /&gt;
     App.TestBeds.update_test_bed(testbed, %{group_id: group.id})&lt;br /&gt;
     {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def updated_groups(testbed_id)  do  &lt;br /&gt;
     testbed = App.TestBeds.get_test_bed!(testbed_id)&lt;br /&gt;
     groups = App.Groups.list_groups&lt;br /&gt;
     tail = Enum.filter(groups, fn(item)-&amp;gt; item.id !== testbed.group_id end)&lt;br /&gt;
     head = Enum.filter(groups, fn(item)-&amp;gt; item.id == testbed.group_id end)&lt;br /&gt;
            |&amp;gt;Enum.at(0)&lt;br /&gt;
    [head | tail]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        &amp;lt;%= for testbed &amp;lt;- Enum.sort_by(@testbeds , &amp;amp;(&amp;quot;#{&amp;amp;1.name}&amp;quot;), :asc)do %&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;grid grid-cols-4 gap-4 p-8 rounded shadow bg-white&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;h2&amp;gt; Name&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;%= testbed.name %&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;h2&amp;gt; Group&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div&amp;gt;&lt;br /&gt;
            &amp;lt;form phx-change=&amp;quot;select-group&amp;quot; name=&amp;quot;testbed_id&amp;quot;  &amp;gt;&lt;br /&gt;
               &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;testbed_id&amp;quot; value={testbed.id}/&amp;gt;&lt;br /&gt;
               &amp;lt;select id=&amp;quot;group-selection&amp;quot;  name=&amp;quot;group-id&amp;quot; class=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;%= for group &amp;lt;- updated_groups(testbed.id) do %&amp;gt;&lt;br /&gt;
                  &amp;lt;%= if group !== nil do %&amp;gt;&lt;br /&gt;
                      &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}&amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
                      &amp;lt;%else%&amp;gt;&lt;br /&gt;
                      &amp;lt;option value= {&amp;quot;Unassigned&amp;quot;}&amp;gt;NONE&amp;lt;/option&amp;gt;&lt;br /&gt;
                  &amp;lt;% end %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
               &amp;lt;/select&amp;gt;&lt;br /&gt;
            &amp;lt;/form&amp;gt;&lt;br /&gt;
          &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
       &amp;lt;% end %&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Developer Notes ==&lt;br /&gt;
===Groups Feature ===&lt;br /&gt;
To complete this feature do these things.&lt;br /&gt;
* Run through the steps in [http://elixirblocks.com/index.php?title=Create_Foreign_Key_Relationship_Between_Ecto_Tables  | this document] to create Group table.&lt;br /&gt;
* Groups have these fields  '''name: string''', '''description: string''' and '''color: string'''  &lt;br /&gt;
* Add unique constraint in migration file: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def change do&lt;br /&gt;
     create unique_index(:groups, [:name])&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Port over Group LiveView code (temporarily placed at discussion page).&lt;br /&gt;
* On completion '''possibly''', create a Group named '''No Group''' and set all Testbeds to it.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
________&lt;br /&gt;
https://blog.appsignal.com/2022/10/11/phoenix-liveview-018-new-special-html-attributes.html&lt;br /&gt;
https://blixtdev.com/whats-new-phoenix-1-7/&lt;br /&gt;
https://github.com/devato/inertia_phoenix&lt;br /&gt;
https://phoenixonrails.com/blog/you-can-stop-using-form-for-in-phoenix&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://samuelmullen.com/articles/phoenix_templates_rendering_and_layouts&lt;br /&gt;
&lt;br /&gt;
WorkFlow of Todo App in Both LiveView and DeadView.&lt;br /&gt;
&lt;br /&gt;
Note:&lt;br /&gt;
&lt;br /&gt;
Create foreign key data.&lt;br /&gt;
Create live view. List all testbeds and form to assign each a group by group-name.&lt;br /&gt;
&lt;br /&gt;
Repeat in dead view&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Mental model and data flows&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
home.html.heex&lt;br /&gt;
&amp;lt;a href=&amp;quot;/data&amp;quot; name=&amp;quot;we are the world&amp;quot; &amp;gt;  click me&amp;lt;/a&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;%= @message %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
page controller&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  def home(conn, _params) do&lt;br /&gt;
    IO.inspect _params&lt;br /&gt;
    render(conn, :home, message: &amp;quot;Hello&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
get &amp;quot;/:yay&amp;quot;, PageController, :index&lt;br /&gt;
&lt;br /&gt;
get &amp;quot;/&amp;quot;, PageController, :index&lt;br /&gt;
&lt;br /&gt;
* Explain control flow of &amp;quot;Dead Views&amp;quot; and the Generator HTML Control flow.&lt;br /&gt;
* Proper Way to use Modal&lt;br /&gt;
* How to give Focus to Fields in Modal (or other forms fields)&lt;br /&gt;
* &lt;br /&gt;
* &lt;br /&gt;
* How to Create Database Seed Data.&lt;br /&gt;
* How to structure code so controller code is in one file and HTML Heex is in another&lt;br /&gt;
* How to Use Generators in a Real World Project&lt;br /&gt;
* How to Work with Database Data via Basic Commands and Custom Change sets.&lt;br /&gt;
* How to Render Database Data to LiveView (via Context Commands).&lt;br /&gt;
* How to Create a Chat using PubSub.&lt;br /&gt;
* How to Create Event Handlers in LiveView&lt;br /&gt;
* How to Create a Dynamic Route from Scratch.&lt;br /&gt;
* How to Use Elixirs Template language&lt;br /&gt;
* How to Work with Modal&lt;br /&gt;
* How to Use CSS From Scratch (Without bundler)&lt;br /&gt;
* How to use JS hooks&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
______________________&lt;br /&gt;
https://studioindie.co/blog/heex-guide/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
get &amp;quot;/&amp;quot;, PageController, :some-atom    #This is the route. some-atom is the controller name&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  def some-atom(conn, _params) do                 # controller name&lt;br /&gt;
    # The home page is often custom made,&lt;br /&gt;
    # so skip the default app layout.&lt;br /&gt;
    render(conn, :some-atom, layout: false)      # :some-atom is template name&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Controllers page_html.ex contains &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageHTML do&lt;br /&gt;
  use AppWeb, :html&lt;br /&gt;
&lt;br /&gt;
  embed_templates &amp;quot;page_html/*&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''page_html''' is the name of the folder in '''Controllers/page_html'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Controllers/page_html/some-atom.html.heex  (this is the template) &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__________________________________________&lt;br /&gt;
Set all association with preload:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  def list_groups do&lt;br /&gt;
    Repo.all(Group)&lt;br /&gt;
     |&amp;gt; Repo.preload([:testbeds])&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Insert Child into Parent ===&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
App.get_group!(2) # arg is id&lt;br /&gt;
|&amp;gt; Ecto.build_assoc(:testbeds)&lt;br /&gt;
|&amp;gt; Repo.insert()&lt;br /&gt;
&lt;br /&gt;
Or&lt;br /&gt;
&lt;br /&gt;
group = App.get_group!(2) # arg is id&lt;br /&gt;
&lt;br /&gt;
testbeds = Ecto.build_assoc(group, :testbeds)&lt;br /&gt;
&lt;br /&gt;
App.Group.create_group(testbeds)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
group = App.Groups.get_group!(1)&lt;br /&gt;
thing = Ecto.build_assoc(group, :testbeds, name: &amp;quot;DUMB&amp;quot;)&lt;br /&gt;
alias App.{Repo}&lt;br /&gt;
Repo.insert(thing)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
avatar = %Avatar{nick_name: &amp;quot;Elixir&amp;quot;, pic_url: &amp;quot;http://elixir-lang.org/images/logo.png&amp;quot;}&lt;br /&gt;
user = %User{name: &amp;quot;John Doe&amp;quot;, email: &amp;quot;john.doe@example.com&amp;quot;, avatar: avatar}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://www.reddit.com/r/elixir/comments/oh318k/is_there_a_way_to_avoid_ectoassociationnotloaded/h4mmcfi/?utm_source=share&amp;amp;utm_medium=web3x&amp;amp;utm_name=web3xcss&amp;amp;utm_term=1&amp;amp;utm_content=share_button&lt;br /&gt;
&lt;br /&gt;
# Create Group Table&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
mix phx.gen.html Groups Group groups name:string  &lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Set the resources / &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
mix ecto.migrate&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For testbeds create a migration file and add this field:   group_id:references:groups&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
def change do&lt;br /&gt;
    alter table(:testbeds) do    # customize to your code&lt;br /&gt;
      add :group_id, references(:groups)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Update Groups Schema (Don't forget alias / has_many)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule App.Groups.Group do&lt;br /&gt;
	use Ecto.Schema&lt;br /&gt;
	import Ecto.Changeset&lt;br /&gt;
	alias App.Testbeds.Testbed   # Alias!&lt;br /&gt;
&lt;br /&gt;
	schema &amp;quot;posts&amp;quot; do&lt;br /&gt;
		field :body, :string&lt;br /&gt;
		field :title, :string&lt;br /&gt;
		has_many :testbeds, Testbed    # Has many&lt;br /&gt;
&lt;br /&gt;
		timestamps()&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	@doc false&lt;br /&gt;
	def changeset(post, attrs) do&lt;br /&gt;
		post&lt;br /&gt;
		|&amp;gt; cast(attrs, [:title, :body])&lt;br /&gt;
		|&amp;gt; validate_required([:title, :body])&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
TESTBEDS Schema&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule App.Testbeds.Testbed do&lt;br /&gt;
  use Ecto.Schema&lt;br /&gt;
  import Ecto.Changeset&lt;br /&gt;
  alias App.Groups.Group      # Alias&lt;br /&gt;
  schema &amp;quot;testbeds&amp;quot; do&lt;br /&gt;
    field :name, :string&lt;br /&gt;
    belongs_to :group, Group    # Belongs to&lt;br /&gt;
    timestamps()&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  @doc false&lt;br /&gt;
  def changeset(testbed, attrs) do&lt;br /&gt;
    testbed&lt;br /&gt;
    |&amp;gt; cast(attrs, [:name])&lt;br /&gt;
    |&amp;gt; validate_required([:name])&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
_____________________________________&lt;br /&gt;
Side notes.&lt;br /&gt;
&lt;br /&gt;
defmodule App.Repo.Migrations.CreateTestbeds do&lt;br /&gt;
  use Ecto.Migration&lt;br /&gt;
&lt;br /&gt;
  def change do&lt;br /&gt;
    create table(:testbeds) do&lt;br /&gt;
      add :name, :string&lt;br /&gt;
      add :group_id, references(:groups, on_delete: :nothing)&lt;br /&gt;
&lt;br /&gt;
      timestamps()&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    create index(:testbeds, [:group_id])&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
________________________________&lt;br /&gt;
&lt;br /&gt;
mix phx.gen.context Comments Comment comments name:string content:text post_id:references:posts&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
mix phx.gen.html Testbeds Testbed testbeds name:string  group_id:references:groups&lt;br /&gt;
&lt;br /&gt;
https://graffino.com/web-development/first-steps-in-elixir-and-phoenix-create-a-blog-prototype&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://blog.logrocket.com/getting-started-ecto-phoenix/&lt;br /&gt;
&lt;br /&gt;
https://serokell.io/blog/ecto-guide-for-beginners&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
mix phx.gen.html Testbeds Testbed testbeds name:string&lt;br /&gt;
&lt;br /&gt;
mix phx.gen.html Groups Group groups name:string&lt;br /&gt;
&lt;br /&gt;
Create migration for &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
mix ecto.gen.migration add_testbed_group_reference&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Migration:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  def change do&lt;br /&gt;
    alter table(:testbeds) do    # customize to your code&lt;br /&gt;
      add :group_id, references(:groups)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Manually Change:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule App.Group do&lt;br /&gt;
  use Ecto.Schema&lt;br /&gt;
&lt;br /&gt;
  schema &amp;quot;groups&amp;quot; do&lt;br /&gt;
    field :title, :string&lt;br /&gt;
    field :tagline, :string&lt;br /&gt;
    has_many :testbeds, App.Testbed&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
testbeds&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule App.Repo.Migrations.AddTextbedGroups do&lt;br /&gt;
  use Ecto.Migration&lt;br /&gt;
&lt;br /&gt;
  def change do&lt;br /&gt;
    create table(:testbeds) do&lt;br /&gt;
      add :name, :string&lt;br /&gt;
      add :group_id, references(:groups)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
# lib/app/testbeds.ex&lt;br /&gt;
&lt;br /&gt;
defmodule App.Testbed do&lt;br /&gt;
  use Ecto.Schema&lt;br /&gt;
&lt;br /&gt;
  schema &amp;quot;testbedss&amp;quot; do&lt;br /&gt;
    field :name, :string&lt;br /&gt;
    belongs_to :group, App.Group&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_____________________&lt;br /&gt;
&lt;br /&gt;
%App.TestBeds.TestBed{&lt;br /&gt;
  __meta__: #Ecto.Schema.Metadata&amp;lt;:loaded, &amp;quot;testbeds&amp;quot;&amp;gt;,&lt;br /&gt;
  id: 1,&lt;br /&gt;
  developer: &amp;quot;None&amp;quot;,&lt;br /&gt;
  name: &amp;quot;sdfsd&amp;quot;,&lt;br /&gt;
  owner: &amp;quot;sdfsddf&amp;quot;,&lt;br /&gt;
  note: &amp;quot;sdsfsddf&amp;quot;,&lt;br /&gt;
  status: &amp;quot;Available&amp;quot;,&lt;br /&gt;
  url: &amp;quot;sdf&amp;quot;,&lt;br /&gt;
  version: &amp;quot;ddf&amp;quot;,&lt;br /&gt;
  manager: &amp;quot;sf&amp;quot;,&lt;br /&gt;
  inserted_at: ~N[2023-08-21 13:45:39],&lt;br /&gt;
  updated_at: ~N[2023-08-21 13:45:44]&lt;br /&gt;
}&lt;br /&gt;
________________________________________________________________---&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.SendLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  &lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    {:ok, socket}&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  def handle_event(&amp;quot;send&amp;quot;, %{&amp;quot;text&amp;quot; =&amp;gt; text}, socket) do&lt;br /&gt;
&lt;br /&gt;
    AppWeb.Endpoint.broadcast(topic, &amp;quot;message&amp;quot;, text)&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  defp topic do&lt;br /&gt;
    &amp;quot;chat&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def render(assigns)do   &lt;br /&gt;
   ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
  &amp;lt;h1&amp;gt;Send Message&amp;lt;/h1&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;form phx-submit=&amp;quot;send&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;text&amp;quot; /&amp;gt;&lt;br /&gt;
    &amp;lt;button type=&amp;quot;submit&amp;quot;&amp;gt;Send&amp;lt;/button&amp;gt;&lt;br /&gt;
  &amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
______________________________________________________________&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.ReceiveLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  &lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    if connected?(socket) do&lt;br /&gt;
      AppWeb.Endpoint.subscribe(topic)&lt;br /&gt;
    end&lt;br /&gt;
    {:ok, assign(socket, messages: &amp;quot;&amp;quot;)}&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def handle_info(%{event: &amp;quot;message&amp;quot;, payload: message}, socket) do&lt;br /&gt;
    IO.inspect message&lt;br /&gt;
    {:noreply, assign(socket, messages: message)}&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  defp topic do&lt;br /&gt;
    &amp;quot;chat&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns)do   &lt;br /&gt;
   ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
  &amp;lt;h1&amp;gt;ChatLive&amp;lt;/h1&amp;gt;&lt;br /&gt;
  &amp;lt;%= @messages %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
______________________________________________________________&lt;br /&gt;
When you hover over a list of items this hook finds items with the same name and sets the opacity of all others to 0. You see all the items similar to the one you are hovering over.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
TestbedVersionHover: {&lt;br /&gt;
			// https://jsfiddle.net/IrvinDominin/7K2Z3/&lt;br /&gt;
            mounted() {&lt;br /&gt;
&lt;br /&gt;
                let rows = document.getElementsByClassName(&amp;quot;testbed-version&amp;quot;)&lt;br /&gt;
                // this.ele = element&lt;br /&gt;
				// rows = this.ele;&lt;br /&gt;
                &lt;br /&gt;
				for (var i = 0; i &amp;lt; rows.length; i++) {&lt;br /&gt;
					rows[i].onmouseenter = function (event) {&lt;br /&gt;
						for (var j = 0; j &amp;lt; rows.length; j++) {&lt;br /&gt;
							let preversion = this.textContent;&lt;br /&gt;
							let version = preversion.slice(0,5)&lt;br /&gt;
							let compareVersion = rows[j].textContent.slice(0,5)&lt;br /&gt;
							if (compareVersion === version) continue&lt;br /&gt;
							rows[j].className += &amp;quot; other&amp;quot;;&lt;br /&gt;
						}&lt;br /&gt;
					};&lt;br /&gt;
				&lt;br /&gt;
					rows[i].onmouseleave = function (event) {&lt;br /&gt;
						var hovers = document.getElementsByClassName('other');&lt;br /&gt;
						var len = hovers.length;&lt;br /&gt;
						for (var j = 0; j &amp;lt; len; j++) {&lt;br /&gt;
							hovers[0].className = hovers[0].className.replace(/\sother(\s|$)/, '');&lt;br /&gt;
						}&lt;br /&gt;
					};&lt;br /&gt;
				}&lt;br /&gt;
&lt;br /&gt;
                // this.ele.addEventListener(&amp;quot;click&amp;quot;, (e) =&amp;gt; {&lt;br /&gt;
                //     console.log(e.target)&lt;br /&gt;
                    &lt;br /&gt;
                // });&lt;br /&gt;
&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* How to Create Database Seed Data.&lt;br /&gt;
* How to structure code so controller code is in one file and HTML Heex is in another&lt;br /&gt;
* How to Use Generators in a Real World Project&lt;br /&gt;
* How to Work with Database Data via Basic Commands and Custom Change sets.&lt;br /&gt;
* How to Render Database Data to LiveView (via Context Commands).&lt;br /&gt;
* How to Create a Chat using PubSub.&lt;br /&gt;
* How to Create Event Handlers in LiveView&lt;br /&gt;
* How to Create a Dynamic Route from Scratch.&lt;br /&gt;
* How to Use Elixirs Template language&lt;br /&gt;
* How to Work with Modal&lt;br /&gt;
* How to Use CSS From Scratch (Without bundler)&lt;br /&gt;
* How to use JS hooks&lt;br /&gt;
* Dissect Table Component and Update it to Order List in Reverse.&lt;br /&gt;
&lt;br /&gt;
Selenium&lt;br /&gt;
https://www.builder.io/blog/debug-nodejs&lt;br /&gt;
&lt;br /&gt;
https://marketplace.visualstudio.com/items?itemName=ms-vscode.live-server#running-the-extension&lt;br /&gt;
&lt;br /&gt;
This was added recently (see microsoft/vscode#109276).&lt;br /&gt;
    1. Open the palette (Ctrl + Shift + P)&lt;br /&gt;
    2. Select &amp;quot;Simple Browser: Preview&amp;quot;&lt;br /&gt;
    3. Enter web address&lt;br /&gt;
&lt;br /&gt;
_______________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
const {By, Key, Builder} = require(&amp;quot;selenium-webdriver&amp;quot;);&lt;br /&gt;
const assert = require(&amp;quot;assert&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
require(&amp;quot;chromedriver&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
async function test_case(){&lt;br /&gt;
  let driver = await new Builder().forBrowser(&amp;quot;chrome&amp;quot;).build();&lt;br /&gt;
  await driver.get(&amp;quot;sie&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  await driver.findElement(By.name('password')).clear();&lt;br /&gt;
  await driver.findElement(By.name('identification')).clear();&lt;br /&gt;
  await driver.findElement(By.name('identification')).sendKeys(&amp;quot;bill&amp;quot;);&lt;br /&gt;
  await driver.findElement(By.name('password')).sendKeys(&amp;quot;password&amp;quot;, Key.RETURN);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 setTimeout(()=&amp;gt;{&lt;br /&gt;
   driver.findElement(By.className(&amp;quot;req_lan_license&amp;quot;)).click();&lt;br /&gt;
 },5000)&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageLive do &lt;br /&gt;
&lt;br /&gt;
  use AppWeb, :live_view  &lt;br /&gt;
  alias App.Testbeds &lt;br /&gt;
  def mount(_params, _session, socket)do   &lt;br /&gt;
     {:ok, assign(socket, testbeds: Testbeds.list_testbeds())}   &lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
    def button_event(&amp;quot;invoke_editing&amp;quot;) do&lt;br /&gt;
    %JS{}&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;active&amp;quot;, to: &amp;quot;#editing_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#editing_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#preview_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;active&amp;quot;, to: &amp;quot;#preview_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;active&amp;quot;, to: &amp;quot;#preview&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#preview&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#editing&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;active&amp;quot;, to: &amp;quot;#editing&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def button_event(&amp;quot;invoke_preview&amp;quot;) do&lt;br /&gt;
    %JS{}&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;active&amp;quot;, to: &amp;quot;#preview_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#preview_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#editing_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;active&amp;quot;, to: &amp;quot;#editing_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;active&amp;quot;, to: &amp;quot;#editing&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#editing&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#preview&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;active&amp;quot;, to: &amp;quot;#preview&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;send&amp;quot;, params, socket) do&lt;br /&gt;
    hide_modal(&amp;quot;notes-modal-0&amp;quot;)&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do  &lt;br /&gt;
     ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
		&amp;lt;.modal id={&amp;quot;notes-modal-#{testbed.id}&amp;quot;}&amp;gt;&lt;br /&gt;
		    &amp;lt;.button phx-click={button_event(&amp;quot;invoke_editing&amp;quot;)} id=&amp;quot;editing_button&amp;quot; class=&amp;quot;hidden&amp;quot;&amp;gt;&lt;br /&gt;
		      Preview&lt;br /&gt;
		    &amp;lt;/.button&amp;gt;&lt;br /&gt;
		    &amp;lt;.button phx-click={button_event(&amp;quot;invoke_preview&amp;quot;)} id=&amp;quot;preview_button&amp;quot;&amp;gt;&lt;br /&gt;
		      Edit Me&lt;br /&gt;
		    &amp;lt;/.button&amp;gt;&lt;br /&gt;
		    &amp;lt;div id=&amp;quot;editing&amp;quot;&amp;gt; PREVIEWING THE WORK&amp;lt;/div&amp;gt;&lt;br /&gt;
		    &amp;lt;form phx-submit = &amp;quot;send&amp;quot;   id=&amp;quot;preview&amp;quot; class=&amp;quot;hidden&amp;quot;&amp;gt;&lt;br /&gt;
		      &amp;lt;textarea value = {testbed.note}&amp;gt;&amp;lt;/textarea&amp;gt;&lt;br /&gt;
		      &amp;lt;.button type=&amp;quot;submit&amp;quot; phx-click={hide_modal(&amp;quot;notes-modal-#{testbed.id}&amp;quot;)}&amp;gt;SAVE WORK&amp;lt;/.button&amp;gt;&lt;br /&gt;
		    &amp;lt;/form&amp;gt;&lt;br /&gt;
		&amp;lt;/.modal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;%= if testbed.note do %&amp;gt;&lt;br /&gt;
      &amp;lt;div phx-click={show_modal(&amp;quot;notes-modal-#{testbed.id}&amp;quot;)}&amp;gt;READ ME  ...&amp;lt;%= testbed.note %&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
	   &lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
       &lt;br /&gt;
      &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
import {HfInference} from &amp;quot;@huggingface/inference&amp;quot;;&lt;br /&gt;
import dotenv from &amp;quot;dotenv&amp;quot;;&lt;br /&gt;
dotenv.config()&lt;br /&gt;
&lt;br /&gt;
const HF_ACCESS_TOKEN = process.env.HF_ACCESS_TOKEN&lt;br /&gt;
&lt;br /&gt;
const hf = new HfInference(HF_ACCESS_TOKEN);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*______Uncomment for this example______________________&lt;br /&gt;
&lt;br /&gt;
const model = &amp;quot;nlpconnect/vit-gpt2-image-captioning&amp;quot;;&lt;br /&gt;
const imageURL = &amp;quot;https://i.imgur.com/lTvb7Et.png&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
const response = await fetch(imageURL);&lt;br /&gt;
const imageBlob = await response.blob();&lt;br /&gt;
&lt;br /&gt;
const result  = await hf.imageToText({&lt;br /&gt;
	data: imageBlob,&lt;br /&gt;
	model: model,&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
_______________________________________________________*/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*________Another example ___________________*/&lt;br /&gt;
&lt;br /&gt;
const result = await hf.summarization({&lt;br /&gt;
	model: 'facebook/bart-large-cnn',&lt;br /&gt;
	inputs: &amp;quot;The role of a dumb man is to get smarter oogy bookie boo&amp;quot;,&lt;br /&gt;
	parameters:{&lt;br /&gt;
		max_length: 100&lt;br /&gt;
	}&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
console.log(result);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
________________________________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://fly.io/phoenix-files/sdeb-toggling-element/&lt;br /&gt;
https://www.youtube.com/watch?v=vBgZvQapqhs&lt;br /&gt;
&lt;br /&gt;
https://blog.testdouble.com/posts/2022-11-28-how-to-use-javascript-with-phoenix-liveview/&lt;br /&gt;
&lt;br /&gt;
https://hexdocs.pm/phoenix_live_view/0.19.3/Phoenix.Component.html&lt;br /&gt;
_______________________________________&lt;br /&gt;
https://www.smashingmagazine.com/2011/10/quick-look-math-animations-javascript/&lt;br /&gt;
* Depth first traversal&lt;br /&gt;
* Breadth first traversal&lt;br /&gt;
&lt;br /&gt;
https://dev.to/codesphere/10-algorithms-every-developer-should-learn-3lnm&lt;br /&gt;
&lt;br /&gt;
https://www.youtube.com/watch?v=fPz40W9mfCg&lt;br /&gt;
&lt;br /&gt;
__________________________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.GroupLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  alias App.TestBeds&lt;br /&gt;
  alias App.Groups&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    {:ok, assign(socket, testbeds: TestBeds.list_testbeds(), groups: Groups.list_groups())}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;select-group&amp;quot;, params, socket)  do  &lt;br /&gt;
         &lt;br /&gt;
       IO.inspect params&lt;br /&gt;
       {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div class=&amp;quot;grid grid-columns-2 grid-flow-col gap-4&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;column-1&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;%= testbed.name %&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;column-2&amp;quot;&amp;gt;    &lt;br /&gt;
            &amp;lt;form phx-change=&amp;quot;select-group&amp;quot;  &amp;gt;&lt;br /&gt;
               &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;testbed_id&amp;quot; value={testbed.id}/&amp;gt;&lt;br /&gt;
               &amp;lt;select id=&amp;quot;group-selection&amp;quot;  name=&amp;quot;group-id&amp;quot; &amp;gt;&lt;br /&gt;
                &amp;lt;%= for group &amp;lt;- @groups do %&amp;gt;&lt;br /&gt;
                  &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}  &amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
               &amp;lt;/select&amp;gt;&lt;br /&gt;
            &amp;lt;/form&amp;gt;&lt;br /&gt;
         &amp;lt;/div&amp;gt;&lt;br /&gt;
       &amp;lt;% end %&amp;gt;&lt;br /&gt;
   &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
____________________________&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.GroupLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  alias App.TestBeds&lt;br /&gt;
  alias App.Groups&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
&lt;br /&gt;
    {:ok, assign(socket, testbeds: TestBeds.list_testbeds(), groups: Groups.list_groups(), messages: [])}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;select-group&amp;quot;, params, socket)  do  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
      group = App.Groups.get_group!(params[&amp;quot;group-id&amp;quot;])&lt;br /&gt;
       # IO.inspect group&lt;br /&gt;
       testbed = App.TestBeds.get_test_bed!(params[&amp;quot;testbed_id&amp;quot;])&lt;br /&gt;
     &lt;br /&gt;
       App.TestBeds.update_test_bed(testbed, %{group_id: group.id})&lt;br /&gt;
         &lt;br /&gt;
    &lt;br /&gt;
       {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def updated_groups(testbed_id)  do  &lt;br /&gt;
       groups = App.Groups.list_groups&lt;br /&gt;
       tail = Enum.filter(groups, fn(item)-&amp;gt; item.id !== testbed_id end)&lt;br /&gt;
       head = Enum.filter(groups, fn(item)-&amp;gt; item.id == testbed_id end)&lt;br /&gt;
              |&amp;gt;Enum.at(0)&lt;br /&gt;
     [head | tail]&lt;br /&gt;
         &lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
 # def handle_event(&amp;quot;groups&amp;quot;, params, socket)do  &lt;br /&gt;
 #       selected_testbed = %{name: &amp;quot;my testbed name&amp;quot;, id: 3}&lt;br /&gt;
 #       groups = App.Groups.list_groups&lt;br /&gt;
 #       tail = Enum.filter(groups, fn(item)-&amp;gt; item.id !== selected_testbed.id end)&lt;br /&gt;
 #       head = Enum.filter(groups, fn(item)-&amp;gt; item.id == selected_testbed.id end)&lt;br /&gt;
 #              |&amp;gt;Enum.at(0)&lt;br /&gt;
         &lt;br /&gt;
 &lt;br /&gt;
 #       # result = Enum.filter([1, 2, 3], fn x -&amp;gt; x.id !== 1 end)&lt;br /&gt;
 #      IO.inspect [head | tail]&lt;br /&gt;
         &lt;br /&gt;
 #      #&lt;br /&gt;
 #      {:noreply, socket, assigns.message:}&lt;br /&gt;
 #  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    &lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
       &amp;lt;%!-- &amp;lt;div phx-click = &amp;quot;groups&amp;quot;&amp;gt;CLICK ME&amp;lt;/div&amp;gt; --%&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;grid grid-cols-4 gap-4 p-8 rounded shadow bg-white&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;h2&amp;gt; Name&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;%= testbed.name %&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;h2&amp;gt; Group&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;form phx-change=&amp;quot;select-group&amp;quot; name=&amp;quot;testbed_id&amp;quot;  &amp;gt;&lt;br /&gt;
               &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;testbed_id&amp;quot; value={testbed.id}/&amp;gt;&lt;br /&gt;
               &amp;lt;select id=&amp;quot;group-selection&amp;quot;  name=&amp;quot;group-id&amp;quot; class=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
                &amp;lt;%= for group &amp;lt;- updated_groups(testbed.id) do %&amp;gt;&lt;br /&gt;
                  &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}  &amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
                  &amp;lt;!-- Write code to reorder with testbed.group_id matching group_id --&amp;gt;&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
               &amp;lt;/select&amp;gt;&lt;br /&gt;
            &amp;lt;/form&amp;gt;&lt;br /&gt;
          &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
       &amp;lt;% end %&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_____________________________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
   use AppWeb, :live_view  &lt;br /&gt;
     alias App.Testbeds&lt;br /&gt;
  alias App.Groups&lt;br /&gt;
   def mount(_params, _session, socket)  do&lt;br /&gt;
	     {:ok, assign(socket, testbeds: Testbeds.list_testbeds(), groups: Groups.list_groups())}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
   def handle_event(&amp;quot;select-group&amp;quot;, params, socket)  do  &lt;br /&gt;
       group = App.Groups.get_group!(params[&amp;quot;group-id&amp;quot;])&lt;br /&gt;
       testbed = App.Testbeds.get_testbed!(params[&amp;quot;testbed_id&amp;quot;])&lt;br /&gt;
       result = App.Testbeds.update_testbed(testbed, %{group_id: group.id})&lt;br /&gt;
       IO.inspect result&lt;br /&gt;
      &lt;br /&gt;
       {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
    def updated_groups(testbed_id)  do  &lt;br /&gt;
       testbed = App.Testbeds.get_testbed!(testbed_id)&lt;br /&gt;
       groups = App.Groups.list_groups&lt;br /&gt;
       tail = Enum.filter(groups, fn(item)-&amp;gt; item.id !== testbed.group_id end)&lt;br /&gt;
       head = Enum.filter(groups, fn(item)-&amp;gt; item.id == testbed.group_id end)&lt;br /&gt;
              |&amp;gt;Enum.at(0)&lt;br /&gt;
 &lt;br /&gt;
       [head | tail]&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    &lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;grid grid-cols-4 gap-4 p-8 rounded shadow bg-white&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;h2&amp;gt; Name&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;%= testbed.name %&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;h2&amp;gt; Group&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;form phx-change=&amp;quot;select-group&amp;quot; name=&amp;quot;testbed_id&amp;quot;  &amp;gt;&lt;br /&gt;
               &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;testbed_id&amp;quot; value={testbed.id}/&amp;gt;&lt;br /&gt;
               &amp;lt;select id=&amp;quot;group-selection&amp;quot;  name=&amp;quot;group-id&amp;quot; class=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
                &amp;lt;%= for group &amp;lt;- updated_groups(testbed.id) do %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
                  &amp;lt;%!-- &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}&amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt; --%&amp;gt;&lt;br /&gt;
                  &amp;lt;!-- Write code to reorder with testbed.group_id matching group_id --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
                  &amp;lt;%= if group !== nil do %&amp;gt;&lt;br /&gt;
                      &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}&amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
       &lt;br /&gt;
                  &amp;lt;% end %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
               &amp;lt;/select&amp;gt;&lt;br /&gt;
            &amp;lt;/form&amp;gt;&lt;br /&gt;
          &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
       &amp;lt;% end %&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  has_many :testbeds, TestBed, on_delete: :restrict   # Has many&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://elixirforum.com/t/ecto-has-many-on-delete-protect/49550&lt;br /&gt;
&lt;br /&gt;
https://hexdocs.pm/ecto/Ecto.Changeset.html#unique_constraint/3&lt;br /&gt;
&lt;br /&gt;
____________________________________________________________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== How to Create a Mix Project and Use It in Another Mix Project ==&lt;br /&gt;
&lt;br /&gt;
To create and use a **Mix project** inside another **Mix project** in Elixir, follow the steps below:&lt;br /&gt;
&lt;br /&gt;
=== 1. Create a New Mix Project ===&lt;br /&gt;
&lt;br /&gt;
First, you need to create a new Mix project. Let's call this project `library_project`. Run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mix new library_project --module LibraryProject&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will create a new Elixir Mix project named `library_project`. The `--module` flag specifies the name of the module that will be created (in this case `LibraryProject`).&lt;br /&gt;
&lt;br /&gt;
The directory structure of `library_project` will look like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
library_project/&lt;br /&gt;
  |_ lib/&lt;br /&gt;
      |_ library_project.ex&lt;br /&gt;
  |_ mix.exs&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can then add some basic functionality inside the `library_project/lib/library_project.ex` file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule LibraryProject do&lt;br /&gt;
  def hello do&lt;br /&gt;
    IO.puts &amp;quot;Hello from LibraryProject!&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now, `library_project` is ready to be used by another Mix project.&lt;br /&gt;
&lt;br /&gt;
=== 2. Create a Second Mix Project ===&lt;br /&gt;
&lt;br /&gt;
Next, create the second Mix project where you want to use `library_project`. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mix new app_project --module AppProject&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will create another Elixir project called `app_project`.&lt;br /&gt;
&lt;br /&gt;
The directory structure for this project will look like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
app_project/&lt;br /&gt;
  |_ lib/&lt;br /&gt;
      |_ app_project.ex&lt;br /&gt;
  |_ mix.exs&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 3. Add `library_project` as a Dependency in `app_project` ===&lt;br /&gt;
&lt;br /&gt;
Now, you want to make `library_project` available in `app_project`. There are two main ways to do this:&lt;br /&gt;
&lt;br /&gt;
==== Option 1: Local Dependency (via `path`) ====&lt;br /&gt;
&lt;br /&gt;
If `library_project` is a local project (i.e., it's stored in a different directory), you can add it to the `mix.exs` of `app_project` as a local dependency by specifying the path to `library_project`.&lt;br /&gt;
&lt;br /&gt;
Edit the `mix.exs` of `app_project`:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule AppProject.MixProject do&lt;br /&gt;
  use Mix.Project&lt;br /&gt;
&lt;br /&gt;
  def project do&lt;br /&gt;
    [&lt;br /&gt;
      app: :app_project,&lt;br /&gt;
      version: &amp;quot;0.1.0&amp;quot;,&lt;br /&gt;
      elixir: &amp;quot;~&amp;gt; 1.14&amp;quot;,&lt;br /&gt;
      start_permanent: Mix.env() == :prod,&lt;br /&gt;
      deps: deps()&lt;br /&gt;
    ]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  defp deps do&lt;br /&gt;
    [&lt;br /&gt;
      {:library_project, path: &amp;quot;../library_project&amp;quot;}  # Add the local dependency&lt;br /&gt;
    ]&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here, `{:library_project, path: &amp;quot;../library_project&amp;quot;}` tells Mix to use the local `library_project` located in the `../library_project` directory (relative to `app_project`).&lt;br /&gt;
&lt;br /&gt;
After updating the `mix.exs`, run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd app_project&lt;br /&gt;
mix deps.get&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will fetch the dependency and compile `library_project`.&lt;br /&gt;
&lt;br /&gt;
==== Option 2: Publish and Fetch as a Hex Package ====&lt;br /&gt;
&lt;br /&gt;
If you want to use `library_project` as a package in another project (for example, by publishing it to **Hex.pm**, Elixir’s package manager), you need to publish it to Hex and then add it as a dependency.&lt;br /&gt;
&lt;br /&gt;
1. Publish `library_project` to Hex (if it's public or for your private use).&lt;br /&gt;
2. Add `library_project` to your `app_project`’s `mix.exs` dependencies:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defp deps do&lt;br /&gt;
  [&lt;br /&gt;
    {:library_project, &amp;quot;~&amp;gt; 0.1.0&amp;quot;}  # Specify the published version from Hex&lt;br /&gt;
  ]&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Run `mix deps.get` to fetch the package from Hex.&lt;br /&gt;
&lt;br /&gt;
=== 4. Use `library_project` in `app_project` ===&lt;br /&gt;
&lt;br /&gt;
Now, you can use the functionality from `library_project` inside your `app_project`. For example, in `app_project/lib/app_project.ex`, you can call the function from `library_project`:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule AppProject do&lt;br /&gt;
  def start do&lt;br /&gt;
    IO.puts &amp;quot;Starting app_project!&amp;quot;&lt;br /&gt;
    LibraryProject.hello()  # Call the function from the library_project&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 5. Run the App ===&lt;br /&gt;
&lt;br /&gt;
Finally, you can run your `app_project`:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd app_project&lt;br /&gt;
mix run -e &amp;quot;AppProject.start()&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will print:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Starting app_project!&lt;br /&gt;
Hello from LibraryProject!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Recap of the Process ==&lt;br /&gt;
1. **Create the `library_project`**: Use `mix new` to generate a library project.&lt;br /&gt;
2. **Create the `app_project`**: Create the second project where you will use the library.&lt;br /&gt;
3. **Add the `library_project` as a dependency**:&lt;br /&gt;
   - Use the `path` option to point to the local project or publish it to Hex for public access.&lt;br /&gt;
4. **Use the `library_project` in the `app_project`**: Call functions or use modules from the library inside the second project.&lt;br /&gt;
5. **Run the app**: Use `mix run` to execute the project.&lt;br /&gt;
&lt;br /&gt;
This way, you can reuse code from one Mix project in another by adding it as a dependency.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==z==&lt;br /&gt;
Overloaded functions are extremely common in Elixir applications. They are&lt;br /&gt;
regularly used for recursive functions and for changing behavior based on&lt;br /&gt;
configuration.&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>http://elixirblocks.com/index.php?title=User:Admin&amp;diff=1870</id>
		<title>User:Admin</title>
		<link rel="alternate" type="text/html" href="http://elixirblocks.com/index.php?title=User:Admin&amp;diff=1870"/>
		<updated>2024-12-23T01:08:07Z</updated>

		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;________________________________________________________&lt;br /&gt;
&lt;br /&gt;
# CRUD Forms&lt;br /&gt;
&lt;br /&gt;
To understand CRUD forms you will need to understand the following concepts. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Ecto Schema&lt;br /&gt;
* Ecto Context&lt;br /&gt;
* Form Basics&lt;br /&gt;
* form/1&lt;br /&gt;
* simple_form/1&lt;br /&gt;
* changesets&lt;br /&gt;
&lt;br /&gt;
We are not going to go in order. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The Context provides CRUD functions for the chosen data schema&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_______________________________________________________&lt;br /&gt;
In that case, you really should switch it to prod mode. Instead of doing all that above with the &amp;quot;config/secret.exs&amp;quot; file, create the &amp;quot;.env&amp;quot; in the project root, then add DotenvParser.load_file(&amp;quot;.env&amp;quot;) to &amp;quot;config/runtime.exs&amp;quot; as the first line inside the if config_env() == :prod do. In the .env file, set the DATABASE_URL and SECRET_KEY_BASE. Then run it as MIX_ENV=prod mix phx.server.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def get_titles do&lt;br /&gt;
    urls = [&lt;br /&gt;
      &amp;quot;https://cointelegraph.com/rss&amp;quot;,&lt;br /&gt;
      &amp;quot;https://chaski.huffpost.com/us/auto/vertical/us-news&amp;quot;&lt;br /&gt;
      # Add more RSS feed URLs here&lt;br /&gt;
    ]&lt;br /&gt;
&lt;br /&gt;
    urls&lt;br /&gt;
    |&amp;gt; Enum.map(fn url -&amp;gt;&lt;br /&gt;
      with {:ok, feed} &amp;lt;- ElixirRss.fetch_and_parse(url) do&lt;br /&gt;
        Enum.map(feed.entries, &amp;amp; &amp;amp;1.title)&lt;br /&gt;
      else&lt;br /&gt;
        {:error, reason} -&amp;gt; {:error, reason}&lt;br /&gt;
      end&lt;br /&gt;
    end)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule App do&lt;br /&gt;
&lt;br /&gt;
  def get_titles() do&lt;br /&gt;
    data = [&lt;br /&gt;
      &amp;quot;https://cointelegraph.com/rss&amp;quot;,&lt;br /&gt;
      &amp;quot;https://chaski.huffpost.com/us/auto/vertical/us-news&amp;quot;&lt;br /&gt;
      # Add more RSS feed URLs here&lt;br /&gt;
    ]&lt;br /&gt;
&lt;br /&gt;
    data&lt;br /&gt;
    |&amp;gt; Enum.map(fn url -&amp;gt;&lt;br /&gt;
      case ElixirRss.fetch_and_parse(url) do&lt;br /&gt;
        {:ok, feed} -&amp;gt; feed.entries |&amp;gt; Enum.map(fn entry -&amp;gt; entry end)&lt;br /&gt;
        {:error, reason} -&amp;gt; {:error, reason}&lt;br /&gt;
      end&lt;br /&gt;
    end)&lt;br /&gt;
    |&amp;gt; Enum.map(fn entry_list -&amp;gt;&lt;br /&gt;
      entry_list&lt;br /&gt;
      |&amp;gt; Enum.map(fn entry -&amp;gt; entry.title end)&lt;br /&gt;
    end)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def hello do&lt;br /&gt;
    rss_feeds = [&lt;br /&gt;
      &amp;quot;https://cointelegraph.com/rss&amp;quot;,&lt;br /&gt;
      &amp;quot;https://chaski.huffpost.com/us/auto/vertical/us-news&amp;quot;&lt;br /&gt;
      # Add more RSS feed URLs here&lt;br /&gt;
    ]&lt;br /&gt;
&lt;br /&gt;
    rss_feeds&lt;br /&gt;
    |&amp;gt; Enum.map(fn url -&amp;gt;&lt;br /&gt;
      case ElixirRss.fetch_and_parse(url) do&lt;br /&gt;
        {:ok, feed} -&amp;gt; feed.entries |&amp;gt; Enum.map(fn entry -&amp;gt; entry end)&lt;br /&gt;
        {:error, reason} -&amp;gt; {:error, reason}&lt;br /&gt;
      end&lt;br /&gt;
    end)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    if connected?(socket) do&lt;br /&gt;
      Phoenix.PubSub.subscribe(App.PubSub, &amp;quot;message&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
    {:ok, assign(socket, message_item: &amp;quot;different&amp;quot;)}&lt;br /&gt;
  end&lt;br /&gt;
  def handle_info({:pubsub_transmission, text}, socket) do&lt;br /&gt;
    IO.inspect &amp;quot;pub sub working&amp;quot;&lt;br /&gt;
    {:noreply, assign(socket, message_item: text)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def loop(data) do&lt;br /&gt;
     IO.inspect data&lt;br /&gt;
     if data &amp;gt; 0 do&lt;br /&gt;
      IO.inspect &amp;quot;notify&amp;quot;&lt;br /&gt;
      # run code to compare files, loop. If different run pubsub code below&lt;br /&gt;
      :timer.sleep(2000)&lt;br /&gt;
      loop(data-1)&lt;br /&gt;
&lt;br /&gt;
     end&lt;br /&gt;
     if data &amp;lt;= 0 do&lt;br /&gt;
&lt;br /&gt;
      Phoenix.PubSub.broadcast(App.PubSub, &amp;quot;message&amp;quot;, {:pubsub_transmission, &amp;quot;data&amp;quot;})&lt;br /&gt;
      &amp;quot;done&amp;quot;&lt;br /&gt;
     end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;change-text&amp;quot;, _params, socket) do&lt;br /&gt;
    spawn(fn -&amp;gt; loop(3) end)&lt;br /&gt;
    {:noreply, assign(socket, message_item: &amp;quot;START&amp;quot; )}&lt;br /&gt;
  end&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
&lt;br /&gt;
    # AppWeb.PageLive.loop(&amp;quot;xxx&amp;quot;)&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    SANDBOX&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;.button phx-click=&amp;quot;change-text&amp;quot; value={@message_item}&amp;gt;CLICK ME&amp;lt;/.button&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;%= @message_item %&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
elixir :   1.16.2&lt;br /&gt;
&lt;br /&gt;
Erl:   20&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# PostGres&lt;br /&gt;
Created Saturday 18 February 2023&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Launch [PostGres](#PostGres) from Terminal&lt;br /&gt;
------------------------------------------&lt;br /&gt;
sudo -u postgres psql&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Set User Permission&lt;br /&gt;
-------------------&lt;br /&gt;
&amp;lt;https://commandprompt.com/education/how-to-create-a-superuser-in-postgresql/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ALTER USER user_name WITH PASSWORD 'new_password';&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Run Post Gres Commands&lt;br /&gt;
----------------------&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
sudo -i -u postgres&lt;br /&gt;
psql&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Create and Delete Database&lt;br /&gt;
&lt;br /&gt;
CREATE DATABASE name;&lt;br /&gt;
DROP DATABASE name;&lt;br /&gt;
## View user list&lt;br /&gt;
&lt;br /&gt;
\du&lt;br /&gt;
&lt;br /&gt;
 View all databases&lt;br /&gt;
&lt;br /&gt;
postgres=# \l&lt;br /&gt;
&lt;br /&gt;
 Change databases&lt;br /&gt;
&lt;br /&gt;
postgres=# \c    name-of-database&lt;br /&gt;
&lt;br /&gt;
View Tables&lt;br /&gt;
&lt;br /&gt;
After you change databases and are selected on one of them do this:&lt;br /&gt;
&lt;br /&gt;
\dt&lt;br /&gt;
&lt;br /&gt;
SELECT * FROM mytablename;&lt;br /&gt;
&lt;br /&gt;
EMPTY TABLE&lt;br /&gt;
DELETE FROM name-of-table&lt;br /&gt;
&lt;br /&gt;
CREATE TABLE&lt;br /&gt;
&lt;br /&gt;
CREATE TABLE table_name(&lt;br /&gt;
   column1 datatype,&lt;br /&gt;
   column2 datatype,&lt;br /&gt;
   column3 datatype,&lt;br /&gt;
   .....&lt;br /&gt;
   columnN datatype,&lt;br /&gt;
   PRIMARY KEY( one or more columns )&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
INSERT&lt;br /&gt;
&lt;br /&gt;
INSERT INTO ITEMS(id, name) VALUES(1,'htvjbjbgni');     Strings are single quote&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Roadmap==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.ItemsLive do&lt;br /&gt;
    use AppWeb, :live_view  &lt;br /&gt;
    def mount(_params, _session, socket)  do&lt;br /&gt;
      {:ok, assign(socket, switches: [&amp;quot;grindy&amp;quot;,&amp;quot;sonic&amp;quot;,&amp;quot;ogre&amp;quot;])}  &lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    def handle_event(&amp;quot;run&amp;quot;,_params,socket) do  &lt;br /&gt;
        &lt;br /&gt;
        IO.inspect &amp;quot;DOWNLOAD VIA SSH&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        {:noreply, redirect(socket, to: &amp;quot;/download&amp;quot;)}&lt;br /&gt;
&lt;br /&gt;
    end&lt;br /&gt;
   &lt;br /&gt;
&lt;br /&gt;
    def render(assigns) do&lt;br /&gt;
        &lt;br /&gt;
        ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        &amp;lt;ul&amp;gt;&lt;br /&gt;
        &amp;lt;%= for switch &amp;lt;- @switches do %&amp;gt;&lt;br /&gt;
         &amp;lt;a phx-submit=&amp;quot;click&amp;quot; href=&amp;quot;/download&amp;quot;&amp;gt;  &amp;lt;li&amp;gt; &amp;lt;%= switch %&amp;gt;  &amp;lt;/li&amp;gt; &amp;lt;/a&amp;gt;&lt;br /&gt;
&lt;br /&gt;
        &amp;lt;%end%&amp;gt;&lt;br /&gt;
        &amp;lt;/ul&amp;gt;&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot; &lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Notes==&lt;br /&gt;
List of Switches and the option to select the one needed.&lt;br /&gt;
Button to download JSON file.&lt;br /&gt;
Drag and Drop Palette to upload JSON file.&lt;br /&gt;
&lt;br /&gt;
After JSON file is uploaded a button titled &amp;quot;Make Active&amp;quot; is available.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://medium.com/@fraiha26/pushing-events-to-livecomponents-from-js-hooks-w-phoenix-elixir-d5544d4c3dfa&lt;br /&gt;
&lt;br /&gt;
Changeset notes and forms&lt;br /&gt;
&lt;br /&gt;
NOTE: Use case statements for pattern matching&lt;br /&gt;
____________________________________________&lt;br /&gt;
&lt;br /&gt;
Create a basic &amp;lt;.form&amp;gt;&amp;lt;/form&amp;gt; without error handling&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&amp;lt;.form :let={f} for={@changeset}  action={~p&amp;quot;/items&amp;quot;} &amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;.input field={f[:title]} type=&amp;quot;text&amp;quot; label=&amp;quot;Title&amp;quot; /&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
  &amp;lt;.button&amp;gt;Save Item&amp;lt;/.button&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;/.form&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With error handling looks like this:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;.form :let={f} for={@changeset}  action={~p&amp;quot;/items&amp;quot;} &amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;.error :if={@changeset.action}&amp;gt;&lt;br /&gt;
    Oops, something went wrong! Please check the errors below.&lt;br /&gt;
  &amp;lt;/.error&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;.input field={f[:title]} type=&amp;quot;text&amp;quot; label=&amp;quot;Title&amp;quot; /&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
  &amp;lt;.button&amp;gt;Save Item&amp;lt;/.button&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;/.form&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Create the routes for render and post to endpoint.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The controller for the page render needs to pass in the changeset via ```Items.change_item(%Item{})```&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  def new(conn, _params) do&lt;br /&gt;
    changeset = Items.change_item(%Item{})&lt;br /&gt;
    render(conn, :new, changeset: changeset)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Post route without error handling&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  def create(conn, %{&amp;quot;item&amp;quot; =&amp;gt; item_params}) do&lt;br /&gt;
    case Items.create_item(item_params) do&lt;br /&gt;
      {:ok, item} -&amp;gt;&lt;br /&gt;
        conn&lt;br /&gt;
        |&amp;gt; put_flash(:info, &amp;quot;Item created successfully.&amp;quot;)&lt;br /&gt;
        |&amp;gt; redirect(to: ~p&amp;quot;/items/#{item}&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With error handling&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  def create(conn, %{&amp;quot;item&amp;quot; =&amp;gt; item_params}) do&lt;br /&gt;
    case Items.create_item(item_params) do&lt;br /&gt;
      {:ok, item} -&amp;gt;&lt;br /&gt;
        conn&lt;br /&gt;
        |&amp;gt; put_flash(:info, &amp;quot;Item created successfully.&amp;quot;)&lt;br /&gt;
        |&amp;gt; redirect(to: ~p&amp;quot;/items/#{item}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
      {:error, %Ecto.Changeset{} = changeset} -&amp;gt;&lt;br /&gt;
        render(conn, :new, changeset: changeset)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_____________________________________________&lt;br /&gt;
https://medium.com/@vincentlin/phoenix-very-simple-form-c4b121697fcb&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''home.html.heex'''&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&amp;lt;form action=&amp;quot;/submit&amp;quot; method=&amp;quot;post&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;label for=&amp;quot;name&amp;quot;&amp;gt;Name:&amp;lt;/label&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;input type=&amp;quot;text&amp;quot; id=&amp;quot;name&amp;quot; name=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;_csrf_token&amp;quot; value={@csrf_token} /&amp;gt;&lt;br /&gt;
  &amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Submit&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
page_controller.ex&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.PageController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  def home(conn, _params) do&lt;br /&gt;
    # The home page is often custom made,&lt;br /&gt;
&lt;br /&gt;
    csrf_token = Plug.CSRFProtection.get_csrf_token()&lt;br /&gt;
    render(conn, :home, csrf_token: csrf_token)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def submit(conn, _params) do&lt;br /&gt;
    # The home page is often custom made,&lt;br /&gt;
     IO.inspect(_params)&lt;br /&gt;
     IO.inspect &amp;quot;___________________________&amp;quot;&lt;br /&gt;
    csrf_token = Plug.CSRFProtection.get_csrf_token()&lt;br /&gt;
    render(conn, :home, csrf_token: csrf_token)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
router.ex&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  scope &amp;quot;/&amp;quot;, AppWeb do&lt;br /&gt;
    pipe_through :browser&lt;br /&gt;
    post &amp;quot;/submit&amp;quot;, PageController, :submit&lt;br /&gt;
    get &amp;quot;/&amp;quot;, PageController, :home&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ecto.Adapters.SQL.query(Repo, &amp;quot;select * from artists where id=1&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ecto cheatsheet:  https://hexdocs.pm/ecto/crud.html&lt;br /&gt;
__________________________________________________________________&lt;br /&gt;
Most programming languages give you the ability to set global state by creating globally scoped variables. Elixir does not do this. Instead, Elixir provides a tool called a &amp;quot;processes&amp;quot; to persist  state. Elixir applications are composed of these &amp;quot;processes&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
Processes by themselves are complicated to use, thus Elixir provides abstractions to make working with processes easier. One of these abstractions is called a GenServer.&lt;br /&gt;
&lt;br /&gt;
GenServers are not only used to store state, they are also used to invoke work independent of the main application process. &lt;br /&gt;
&lt;br /&gt;
==Creating a GenServer to Store State==&lt;br /&gt;
&lt;br /&gt;
To Create a GenServer, start by creating a basic Module that ''uses'' the GenServer module (image below)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule App do  &lt;br /&gt;
  use GenServer&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We now need to describe the actions we want to perform. Being that this is used to store state, we will use basic CRUD actions: Create, Read, Update, Delete. To begins, empty functions describing each action is created.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule App do&lt;br /&gt;
   def create do &lt;br /&gt;
&lt;br /&gt;
   end&lt;br /&gt;
   def read do &lt;br /&gt;
&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
   def update do  &lt;br /&gt;
&lt;br /&gt;
   end &lt;br /&gt;
&lt;br /&gt;
   def delete do &lt;br /&gt;
&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==What now?==&lt;br /&gt;
&lt;br /&gt;
To fill in the functions with the appropriate code we must first have a basic understanding of how GenServers are structured.&lt;br /&gt;
&lt;br /&gt;
GenServers are composed of the GenServer module invoking callbacks. The callbacks have built in names that you, as a developer have to use.&lt;br /&gt;
&lt;br /&gt;
These callbacks are named:&lt;br /&gt;
&lt;br /&gt;
* init&lt;br /&gt;
* handle_cast&lt;br /&gt;
* handle_call&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To demonstrate, here is an example :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{:ok, pid} = GenServer.start(ModuleNameOfGenServer, %{})&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above function named &amp;quot;start&amp;quot; calls the function named init in the Module below.&lt;br /&gt;
In GenServer syntax the name of the GenServer functions always invoke callbacks that are determined by the language. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule ModuleNameOfGenServer do&lt;br /&gt;
  # 1&lt;br /&gt;
  def init(state \\ %{}) do&lt;br /&gt;
    {:ok, state}&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is a list of the GenServer functions and their corresponding callbacks.&lt;br /&gt;
&lt;br /&gt;
* GenServer.start/1  --&amp;gt;       init/1&lt;br /&gt;
* GenServer.call/3   --&amp;gt;       def handle_call/3&lt;br /&gt;
* GenServer.cast/2   --&amp;gt;       handle_cast/2&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Start and Call ==&lt;br /&gt;
&lt;br /&gt;
Call and Cast can be used to perform the same operations. The &lt;br /&gt;
&lt;br /&gt;
__________________________________________________________&lt;br /&gt;
Genserver timed events&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule Go do&lt;br /&gt;
  use GenServer&lt;br /&gt;
&lt;br /&gt;
  def go() do&lt;br /&gt;
    GenServer.start_link(__MODULE__, [])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def init(list) do&lt;br /&gt;
    :timer.apply_interval(1000, __MODULE__, :add, [self(), &amp;quot;weeeee&amp;quot;])&lt;br /&gt;
    {:ok, list}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def view(pid) do&lt;br /&gt;
    GenServer.call(pid, :view)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_call(:view, _from, list) do&lt;br /&gt;
    {:reply, list, list}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def add(pid, new_item) do&lt;br /&gt;
    GenServer.call(pid, {:item, new_item})&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_call({:item, new_item}, _from, state) do&lt;br /&gt;
    result = [new_item] ++ state&lt;br /&gt;
    {:reply, result, result}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule ShoppingList do&lt;br /&gt;
  use GenServer&lt;br /&gt;
&lt;br /&gt;
  def start_link() do&lt;br /&gt;
    GenServer.start_link(ShoppingList, [])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def init(list) do&lt;br /&gt;
    {:ok, list}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def view(pid) do&lt;br /&gt;
    GenServer.call(pid, :view)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_call(:view, _from, list) do&lt;br /&gt;
    {:reply, list, list}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def add(pid, new_item) do&lt;br /&gt;
    GenServer.call(pid, {:item, new_item})&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_call({:item, new_item}, _from, state) do&lt;br /&gt;
    result = [new_item] ++ state&lt;br /&gt;
    {:reply, result, result}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://blog.appsignal.com/2018/06/12/elixir-alchemy-deconstructing-genservers.html&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule KeyValue do&lt;br /&gt;
  # 1&lt;br /&gt;
  def init(state \\ %{}) do&lt;br /&gt;
    {:ok, state}&lt;br /&gt;
  end&lt;br /&gt;
 &lt;br /&gt;
  # 2&lt;br /&gt;
  def handle_cast({:put, key, value}, state) do&lt;br /&gt;
    {:noreply, Map.put(state, key, value)}&lt;br /&gt;
  end&lt;br /&gt;
 &lt;br /&gt;
  # 3&lt;br /&gt;
  def handle_call({:get, key}, _from, state) do&lt;br /&gt;
    {:reply, Map.fetch!(state, key), state}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
# {:ok, pid} = GenServer.start(KeyValue, %{})&lt;br /&gt;
# GenServer.cast(pid, {:put, :foo, &amp;quot;bar&amp;quot;})&lt;br /&gt;
# GenServer.call(pid, {:get, :foo})&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Send messages via these functions wrapped in module functions .You can look at these are functions used to fire &amp;quot;GenServer Events&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
* start_link&lt;br /&gt;
* GenServer.call&lt;br /&gt;
* GenServer.cast&lt;br /&gt;
&lt;br /&gt;
The corresponding server functions that reply are:&lt;br /&gt;
&lt;br /&gt;
* init&lt;br /&gt;
* handle__call&lt;br /&gt;
* handle_cast&lt;br /&gt;
* &lt;br /&gt;
&lt;br /&gt;
These can be looked at as &amp;quot;listeners&amp;quot; - in JavaScript parlance. &lt;br /&gt;
__________________________________________&lt;br /&gt;
&lt;br /&gt;
If you have experience with programming languages other than Elixir the idea of GenServers may be very foreign and require a strong context shift to learn. This document is intended to simplify the concept.&lt;br /&gt;
&lt;br /&gt;
* What: GenServers are simply a way to hold state and/or invoke actions based on incoming events. &lt;br /&gt;
* when &lt;br /&gt;
* where&lt;br /&gt;
* why&lt;br /&gt;
* how&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
___________________________________________&lt;br /&gt;
GenServer timer example&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule Timer do&lt;br /&gt;
  use GenServer&lt;br /&gt;
&lt;br /&gt;
  def init(_) do&lt;br /&gt;
    :timer.send_interval(1000, :xyz)&lt;br /&gt;
    {:ok, 0}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_info(:xyz, state) do&lt;br /&gt;
    IO.inspect(state)&lt;br /&gt;
    {:noreply, state + 1}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
[&lt;br /&gt;
   {&lt;br /&gt;
     data:{&lt;br /&gt;
        creationTime,&lt;br /&gt;
        publishDate,&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
     featured:{&lt;br /&gt;
        setAmount,&lt;br /&gt;
        items:[]&lt;br /&gt;
     },&lt;br /&gt;
&lt;br /&gt;
     children:{&lt;br /&gt;
        setAmount,&lt;br /&gt;
        items:[]&lt;br /&gt;
     },&lt;br /&gt;
     links:{&lt;br /&gt;
        setAmount,&lt;br /&gt;
        items:[]&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
jason.encode / jason.decode&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  def run(num) do&lt;br /&gt;
&lt;br /&gt;
    Enum.each(0..99999, fn(_x) -&amp;gt;&lt;br /&gt;
      task = Task.async(fn -&amp;gt; num + _x end)&lt;br /&gt;
    IO.inspect Task.await(task)&lt;br /&gt;
  end)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enum.map(feed.entries, fn x -&amp;gt; %{url: x.url, title: x.title} end)&lt;br /&gt;
&lt;br /&gt;
App is split:&lt;br /&gt;
&lt;br /&gt;
App that captures RSS in UI and lets admin select stories. THere are settings to determine the number of FEATURED,CHILD and LINK stories.&lt;br /&gt;
News categories are horizontal and scrollable.&lt;br /&gt;
This exports a json doc with all RSS data for each story.&lt;br /&gt;
The &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
App that reads the json data. This app creates tables and is the front end.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://stephenbussey.com/tags/elixir.html&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule AppWeb.GroupLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  alias App.TestBeds&lt;br /&gt;
  alias App.Groups&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    {:ok, assign(socket, testbeds: TestBeds.list_testbeds(), groups: Groups.list_groups())}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;select-group&amp;quot;, params, socket)  do  &lt;br /&gt;
     group = App.Groups.get_group!(params[&amp;quot;group-id&amp;quot;])&lt;br /&gt;
     testbed = App.TestBeds.get_test_bed!(params[&amp;quot;testbed_id&amp;quot;])&lt;br /&gt;
     App.TestBeds.update_test_bed(testbed, %{group_id: group.id})&lt;br /&gt;
     {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def updated_groups(testbed_id)  do  &lt;br /&gt;
     testbed = App.TestBeds.get_test_bed!(testbed_id)&lt;br /&gt;
     groups = App.Groups.list_groups&lt;br /&gt;
     tail = Enum.filter(groups, fn(item)-&amp;gt; item.id !== testbed.group_id end)&lt;br /&gt;
     head = Enum.filter(groups, fn(item)-&amp;gt; item.id == testbed.group_id end)&lt;br /&gt;
            |&amp;gt;Enum.at(0)&lt;br /&gt;
    [head | tail]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        &amp;lt;%= for testbed &amp;lt;- Enum.sort_by(@testbeds , &amp;amp;(&amp;quot;#{&amp;amp;1.name}&amp;quot;), :asc)do %&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;grid grid-cols-4 gap-4 p-8 rounded shadow bg-white&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;h2&amp;gt; Name&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;%= testbed.name %&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;h2&amp;gt; Group&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div&amp;gt;&lt;br /&gt;
            &amp;lt;form phx-change=&amp;quot;select-group&amp;quot; name=&amp;quot;testbed_id&amp;quot;  &amp;gt;&lt;br /&gt;
               &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;testbed_id&amp;quot; value={testbed.id}/&amp;gt;&lt;br /&gt;
               &amp;lt;select id=&amp;quot;group-selection&amp;quot;  name=&amp;quot;group-id&amp;quot; class=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;%= for group &amp;lt;- updated_groups(testbed.id) do %&amp;gt;&lt;br /&gt;
                  &amp;lt;%= if group !== nil do %&amp;gt;&lt;br /&gt;
                      &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}&amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
                      &amp;lt;%else%&amp;gt;&lt;br /&gt;
                      &amp;lt;option value= {&amp;quot;Unassigned&amp;quot;}&amp;gt;NONE&amp;lt;/option&amp;gt;&lt;br /&gt;
                  &amp;lt;% end %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
               &amp;lt;/select&amp;gt;&lt;br /&gt;
            &amp;lt;/form&amp;gt;&lt;br /&gt;
          &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
       &amp;lt;% end %&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Developer Notes ==&lt;br /&gt;
===Groups Feature ===&lt;br /&gt;
To complete this feature do these things.&lt;br /&gt;
* Run through the steps in [http://elixirblocks.com/index.php?title=Create_Foreign_Key_Relationship_Between_Ecto_Tables  | this document] to create Group table.&lt;br /&gt;
* Groups have these fields  '''name: string''', '''description: string''' and '''color: string'''  &lt;br /&gt;
* Add unique constraint in migration file: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def change do&lt;br /&gt;
     create unique_index(:groups, [:name])&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Port over Group LiveView code (temporarily placed at discussion page).&lt;br /&gt;
* On completion '''possibly''', create a Group named '''No Group''' and set all Testbeds to it.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
________&lt;br /&gt;
https://blog.appsignal.com/2022/10/11/phoenix-liveview-018-new-special-html-attributes.html&lt;br /&gt;
https://blixtdev.com/whats-new-phoenix-1-7/&lt;br /&gt;
https://github.com/devato/inertia_phoenix&lt;br /&gt;
https://phoenixonrails.com/blog/you-can-stop-using-form-for-in-phoenix&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://samuelmullen.com/articles/phoenix_templates_rendering_and_layouts&lt;br /&gt;
&lt;br /&gt;
WorkFlow of Todo App in Both LiveView and DeadView.&lt;br /&gt;
&lt;br /&gt;
Note:&lt;br /&gt;
&lt;br /&gt;
Create foreign key data.&lt;br /&gt;
Create live view. List all testbeds and form to assign each a group by group-name.&lt;br /&gt;
&lt;br /&gt;
Repeat in dead view&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Mental model and data flows&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
home.html.heex&lt;br /&gt;
&amp;lt;a href=&amp;quot;/data&amp;quot; name=&amp;quot;we are the world&amp;quot; &amp;gt;  click me&amp;lt;/a&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;%= @message %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
page controller&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  def home(conn, _params) do&lt;br /&gt;
    IO.inspect _params&lt;br /&gt;
    render(conn, :home, message: &amp;quot;Hello&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
get &amp;quot;/:yay&amp;quot;, PageController, :index&lt;br /&gt;
&lt;br /&gt;
get &amp;quot;/&amp;quot;, PageController, :index&lt;br /&gt;
&lt;br /&gt;
* Explain control flow of &amp;quot;Dead Views&amp;quot; and the Generator HTML Control flow.&lt;br /&gt;
* Proper Way to use Modal&lt;br /&gt;
* How to give Focus to Fields in Modal (or other forms fields)&lt;br /&gt;
* &lt;br /&gt;
* &lt;br /&gt;
* How to Create Database Seed Data.&lt;br /&gt;
* How to structure code so controller code is in one file and HTML Heex is in another&lt;br /&gt;
* How to Use Generators in a Real World Project&lt;br /&gt;
* How to Work with Database Data via Basic Commands and Custom Change sets.&lt;br /&gt;
* How to Render Database Data to LiveView (via Context Commands).&lt;br /&gt;
* How to Create a Chat using PubSub.&lt;br /&gt;
* How to Create Event Handlers in LiveView&lt;br /&gt;
* How to Create a Dynamic Route from Scratch.&lt;br /&gt;
* How to Use Elixirs Template language&lt;br /&gt;
* How to Work with Modal&lt;br /&gt;
* How to Use CSS From Scratch (Without bundler)&lt;br /&gt;
* How to use JS hooks&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
______________________&lt;br /&gt;
https://studioindie.co/blog/heex-guide/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
get &amp;quot;/&amp;quot;, PageController, :some-atom    #This is the route. some-atom is the controller name&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  def some-atom(conn, _params) do                 # controller name&lt;br /&gt;
    # The home page is often custom made,&lt;br /&gt;
    # so skip the default app layout.&lt;br /&gt;
    render(conn, :some-atom, layout: false)      # :some-atom is template name&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Controllers page_html.ex contains &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageHTML do&lt;br /&gt;
  use AppWeb, :html&lt;br /&gt;
&lt;br /&gt;
  embed_templates &amp;quot;page_html/*&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''page_html''' is the name of the folder in '''Controllers/page_html'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Controllers/page_html/some-atom.html.heex  (this is the template) &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__________________________________________&lt;br /&gt;
Set all association with preload:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  def list_groups do&lt;br /&gt;
    Repo.all(Group)&lt;br /&gt;
     |&amp;gt; Repo.preload([:testbeds])&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Insert Child into Parent ===&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
App.get_group!(2) # arg is id&lt;br /&gt;
|&amp;gt; Ecto.build_assoc(:testbeds)&lt;br /&gt;
|&amp;gt; Repo.insert()&lt;br /&gt;
&lt;br /&gt;
Or&lt;br /&gt;
&lt;br /&gt;
group = App.get_group!(2) # arg is id&lt;br /&gt;
&lt;br /&gt;
testbeds = Ecto.build_assoc(group, :testbeds)&lt;br /&gt;
&lt;br /&gt;
App.Group.create_group(testbeds)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
group = App.Groups.get_group!(1)&lt;br /&gt;
thing = Ecto.build_assoc(group, :testbeds, name: &amp;quot;DUMB&amp;quot;)&lt;br /&gt;
alias App.{Repo}&lt;br /&gt;
Repo.insert(thing)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
avatar = %Avatar{nick_name: &amp;quot;Elixir&amp;quot;, pic_url: &amp;quot;http://elixir-lang.org/images/logo.png&amp;quot;}&lt;br /&gt;
user = %User{name: &amp;quot;John Doe&amp;quot;, email: &amp;quot;john.doe@example.com&amp;quot;, avatar: avatar}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://www.reddit.com/r/elixir/comments/oh318k/is_there_a_way_to_avoid_ectoassociationnotloaded/h4mmcfi/?utm_source=share&amp;amp;utm_medium=web3x&amp;amp;utm_name=web3xcss&amp;amp;utm_term=1&amp;amp;utm_content=share_button&lt;br /&gt;
&lt;br /&gt;
# Create Group Table&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
mix phx.gen.html Groups Group groups name:string  &lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Set the resources / &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
mix ecto.migrate&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For testbeds create a migration file and add this field:   group_id:references:groups&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
def change do&lt;br /&gt;
    alter table(:testbeds) do    # customize to your code&lt;br /&gt;
      add :group_id, references(:groups)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Update Groups Schema (Don't forget alias / has_many)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule App.Groups.Group do&lt;br /&gt;
	use Ecto.Schema&lt;br /&gt;
	import Ecto.Changeset&lt;br /&gt;
	alias App.Testbeds.Testbed   # Alias!&lt;br /&gt;
&lt;br /&gt;
	schema &amp;quot;posts&amp;quot; do&lt;br /&gt;
		field :body, :string&lt;br /&gt;
		field :title, :string&lt;br /&gt;
		has_many :testbeds, Testbed    # Has many&lt;br /&gt;
&lt;br /&gt;
		timestamps()&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	@doc false&lt;br /&gt;
	def changeset(post, attrs) do&lt;br /&gt;
		post&lt;br /&gt;
		|&amp;gt; cast(attrs, [:title, :body])&lt;br /&gt;
		|&amp;gt; validate_required([:title, :body])&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
TESTBEDS Schema&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule App.Testbeds.Testbed do&lt;br /&gt;
  use Ecto.Schema&lt;br /&gt;
  import Ecto.Changeset&lt;br /&gt;
  alias App.Groups.Group      # Alias&lt;br /&gt;
  schema &amp;quot;testbeds&amp;quot; do&lt;br /&gt;
    field :name, :string&lt;br /&gt;
    belongs_to :group, Group    # Belongs to&lt;br /&gt;
    timestamps()&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  @doc false&lt;br /&gt;
  def changeset(testbed, attrs) do&lt;br /&gt;
    testbed&lt;br /&gt;
    |&amp;gt; cast(attrs, [:name])&lt;br /&gt;
    |&amp;gt; validate_required([:name])&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
_____________________________________&lt;br /&gt;
Side notes.&lt;br /&gt;
&lt;br /&gt;
defmodule App.Repo.Migrations.CreateTestbeds do&lt;br /&gt;
  use Ecto.Migration&lt;br /&gt;
&lt;br /&gt;
  def change do&lt;br /&gt;
    create table(:testbeds) do&lt;br /&gt;
      add :name, :string&lt;br /&gt;
      add :group_id, references(:groups, on_delete: :nothing)&lt;br /&gt;
&lt;br /&gt;
      timestamps()&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    create index(:testbeds, [:group_id])&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
________________________________&lt;br /&gt;
&lt;br /&gt;
mix phx.gen.context Comments Comment comments name:string content:text post_id:references:posts&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
mix phx.gen.html Testbeds Testbed testbeds name:string  group_id:references:groups&lt;br /&gt;
&lt;br /&gt;
https://graffino.com/web-development/first-steps-in-elixir-and-phoenix-create-a-blog-prototype&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://blog.logrocket.com/getting-started-ecto-phoenix/&lt;br /&gt;
&lt;br /&gt;
https://serokell.io/blog/ecto-guide-for-beginners&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
mix phx.gen.html Testbeds Testbed testbeds name:string&lt;br /&gt;
&lt;br /&gt;
mix phx.gen.html Groups Group groups name:string&lt;br /&gt;
&lt;br /&gt;
Create migration for &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
mix ecto.gen.migration add_testbed_group_reference&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Migration:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  def change do&lt;br /&gt;
    alter table(:testbeds) do    # customize to your code&lt;br /&gt;
      add :group_id, references(:groups)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Manually Change:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule App.Group do&lt;br /&gt;
  use Ecto.Schema&lt;br /&gt;
&lt;br /&gt;
  schema &amp;quot;groups&amp;quot; do&lt;br /&gt;
    field :title, :string&lt;br /&gt;
    field :tagline, :string&lt;br /&gt;
    has_many :testbeds, App.Testbed&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
testbeds&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule App.Repo.Migrations.AddTextbedGroups do&lt;br /&gt;
  use Ecto.Migration&lt;br /&gt;
&lt;br /&gt;
  def change do&lt;br /&gt;
    create table(:testbeds) do&lt;br /&gt;
      add :name, :string&lt;br /&gt;
      add :group_id, references(:groups)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
# lib/app/testbeds.ex&lt;br /&gt;
&lt;br /&gt;
defmodule App.Testbed do&lt;br /&gt;
  use Ecto.Schema&lt;br /&gt;
&lt;br /&gt;
  schema &amp;quot;testbedss&amp;quot; do&lt;br /&gt;
    field :name, :string&lt;br /&gt;
    belongs_to :group, App.Group&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_____________________&lt;br /&gt;
&lt;br /&gt;
%App.TestBeds.TestBed{&lt;br /&gt;
  __meta__: #Ecto.Schema.Metadata&amp;lt;:loaded, &amp;quot;testbeds&amp;quot;&amp;gt;,&lt;br /&gt;
  id: 1,&lt;br /&gt;
  developer: &amp;quot;None&amp;quot;,&lt;br /&gt;
  name: &amp;quot;sdfsd&amp;quot;,&lt;br /&gt;
  owner: &amp;quot;sdfsddf&amp;quot;,&lt;br /&gt;
  note: &amp;quot;sdsfsddf&amp;quot;,&lt;br /&gt;
  status: &amp;quot;Available&amp;quot;,&lt;br /&gt;
  url: &amp;quot;sdf&amp;quot;,&lt;br /&gt;
  version: &amp;quot;ddf&amp;quot;,&lt;br /&gt;
  manager: &amp;quot;sf&amp;quot;,&lt;br /&gt;
  inserted_at: ~N[2023-08-21 13:45:39],&lt;br /&gt;
  updated_at: ~N[2023-08-21 13:45:44]&lt;br /&gt;
}&lt;br /&gt;
________________________________________________________________---&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.SendLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  &lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    {:ok, socket}&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  def handle_event(&amp;quot;send&amp;quot;, %{&amp;quot;text&amp;quot; =&amp;gt; text}, socket) do&lt;br /&gt;
&lt;br /&gt;
    AppWeb.Endpoint.broadcast(topic, &amp;quot;message&amp;quot;, text)&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  defp topic do&lt;br /&gt;
    &amp;quot;chat&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def render(assigns)do   &lt;br /&gt;
   ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
  &amp;lt;h1&amp;gt;Send Message&amp;lt;/h1&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;form phx-submit=&amp;quot;send&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;text&amp;quot; /&amp;gt;&lt;br /&gt;
    &amp;lt;button type=&amp;quot;submit&amp;quot;&amp;gt;Send&amp;lt;/button&amp;gt;&lt;br /&gt;
  &amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
______________________________________________________________&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.ReceiveLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  &lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    if connected?(socket) do&lt;br /&gt;
      AppWeb.Endpoint.subscribe(topic)&lt;br /&gt;
    end&lt;br /&gt;
    {:ok, assign(socket, messages: &amp;quot;&amp;quot;)}&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def handle_info(%{event: &amp;quot;message&amp;quot;, payload: message}, socket) do&lt;br /&gt;
    IO.inspect message&lt;br /&gt;
    {:noreply, assign(socket, messages: message)}&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  defp topic do&lt;br /&gt;
    &amp;quot;chat&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns)do   &lt;br /&gt;
   ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
  &amp;lt;h1&amp;gt;ChatLive&amp;lt;/h1&amp;gt;&lt;br /&gt;
  &amp;lt;%= @messages %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
______________________________________________________________&lt;br /&gt;
When you hover over a list of items this hook finds items with the same name and sets the opacity of all others to 0. You see all the items similar to the one you are hovering over.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
TestbedVersionHover: {&lt;br /&gt;
			// https://jsfiddle.net/IrvinDominin/7K2Z3/&lt;br /&gt;
            mounted() {&lt;br /&gt;
&lt;br /&gt;
                let rows = document.getElementsByClassName(&amp;quot;testbed-version&amp;quot;)&lt;br /&gt;
                // this.ele = element&lt;br /&gt;
				// rows = this.ele;&lt;br /&gt;
                &lt;br /&gt;
				for (var i = 0; i &amp;lt; rows.length; i++) {&lt;br /&gt;
					rows[i].onmouseenter = function (event) {&lt;br /&gt;
						for (var j = 0; j &amp;lt; rows.length; j++) {&lt;br /&gt;
							let preversion = this.textContent;&lt;br /&gt;
							let version = preversion.slice(0,5)&lt;br /&gt;
							let compareVersion = rows[j].textContent.slice(0,5)&lt;br /&gt;
							if (compareVersion === version) continue&lt;br /&gt;
							rows[j].className += &amp;quot; other&amp;quot;;&lt;br /&gt;
						}&lt;br /&gt;
					};&lt;br /&gt;
				&lt;br /&gt;
					rows[i].onmouseleave = function (event) {&lt;br /&gt;
						var hovers = document.getElementsByClassName('other');&lt;br /&gt;
						var len = hovers.length;&lt;br /&gt;
						for (var j = 0; j &amp;lt; len; j++) {&lt;br /&gt;
							hovers[0].className = hovers[0].className.replace(/\sother(\s|$)/, '');&lt;br /&gt;
						}&lt;br /&gt;
					};&lt;br /&gt;
				}&lt;br /&gt;
&lt;br /&gt;
                // this.ele.addEventListener(&amp;quot;click&amp;quot;, (e) =&amp;gt; {&lt;br /&gt;
                //     console.log(e.target)&lt;br /&gt;
                    &lt;br /&gt;
                // });&lt;br /&gt;
&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* How to Create Database Seed Data.&lt;br /&gt;
* How to structure code so controller code is in one file and HTML Heex is in another&lt;br /&gt;
* How to Use Generators in a Real World Project&lt;br /&gt;
* How to Work with Database Data via Basic Commands and Custom Change sets.&lt;br /&gt;
* How to Render Database Data to LiveView (via Context Commands).&lt;br /&gt;
* How to Create a Chat using PubSub.&lt;br /&gt;
* How to Create Event Handlers in LiveView&lt;br /&gt;
* How to Create a Dynamic Route from Scratch.&lt;br /&gt;
* How to Use Elixirs Template language&lt;br /&gt;
* How to Work with Modal&lt;br /&gt;
* How to Use CSS From Scratch (Without bundler)&lt;br /&gt;
* How to use JS hooks&lt;br /&gt;
* Dissect Table Component and Update it to Order List in Reverse.&lt;br /&gt;
&lt;br /&gt;
Selenium&lt;br /&gt;
https://www.builder.io/blog/debug-nodejs&lt;br /&gt;
&lt;br /&gt;
https://marketplace.visualstudio.com/items?itemName=ms-vscode.live-server#running-the-extension&lt;br /&gt;
&lt;br /&gt;
This was added recently (see microsoft/vscode#109276).&lt;br /&gt;
    1. Open the palette (Ctrl + Shift + P)&lt;br /&gt;
    2. Select &amp;quot;Simple Browser: Preview&amp;quot;&lt;br /&gt;
    3. Enter web address&lt;br /&gt;
&lt;br /&gt;
_______________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
const {By, Key, Builder} = require(&amp;quot;selenium-webdriver&amp;quot;);&lt;br /&gt;
const assert = require(&amp;quot;assert&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
require(&amp;quot;chromedriver&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
async function test_case(){&lt;br /&gt;
  let driver = await new Builder().forBrowser(&amp;quot;chrome&amp;quot;).build();&lt;br /&gt;
  await driver.get(&amp;quot;sie&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  await driver.findElement(By.name('password')).clear();&lt;br /&gt;
  await driver.findElement(By.name('identification')).clear();&lt;br /&gt;
  await driver.findElement(By.name('identification')).sendKeys(&amp;quot;bill&amp;quot;);&lt;br /&gt;
  await driver.findElement(By.name('password')).sendKeys(&amp;quot;password&amp;quot;, Key.RETURN);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 setTimeout(()=&amp;gt;{&lt;br /&gt;
   driver.findElement(By.className(&amp;quot;req_lan_license&amp;quot;)).click();&lt;br /&gt;
 },5000)&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageLive do &lt;br /&gt;
&lt;br /&gt;
  use AppWeb, :live_view  &lt;br /&gt;
  alias App.Testbeds &lt;br /&gt;
  def mount(_params, _session, socket)do   &lt;br /&gt;
     {:ok, assign(socket, testbeds: Testbeds.list_testbeds())}   &lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
    def button_event(&amp;quot;invoke_editing&amp;quot;) do&lt;br /&gt;
    %JS{}&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;active&amp;quot;, to: &amp;quot;#editing_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#editing_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#preview_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;active&amp;quot;, to: &amp;quot;#preview_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;active&amp;quot;, to: &amp;quot;#preview&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#preview&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#editing&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;active&amp;quot;, to: &amp;quot;#editing&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def button_event(&amp;quot;invoke_preview&amp;quot;) do&lt;br /&gt;
    %JS{}&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;active&amp;quot;, to: &amp;quot;#preview_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#preview_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#editing_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;active&amp;quot;, to: &amp;quot;#editing_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;active&amp;quot;, to: &amp;quot;#editing&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#editing&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#preview&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;active&amp;quot;, to: &amp;quot;#preview&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;send&amp;quot;, params, socket) do&lt;br /&gt;
    hide_modal(&amp;quot;notes-modal-0&amp;quot;)&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do  &lt;br /&gt;
     ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
		&amp;lt;.modal id={&amp;quot;notes-modal-#{testbed.id}&amp;quot;}&amp;gt;&lt;br /&gt;
		    &amp;lt;.button phx-click={button_event(&amp;quot;invoke_editing&amp;quot;)} id=&amp;quot;editing_button&amp;quot; class=&amp;quot;hidden&amp;quot;&amp;gt;&lt;br /&gt;
		      Preview&lt;br /&gt;
		    &amp;lt;/.button&amp;gt;&lt;br /&gt;
		    &amp;lt;.button phx-click={button_event(&amp;quot;invoke_preview&amp;quot;)} id=&amp;quot;preview_button&amp;quot;&amp;gt;&lt;br /&gt;
		      Edit Me&lt;br /&gt;
		    &amp;lt;/.button&amp;gt;&lt;br /&gt;
		    &amp;lt;div id=&amp;quot;editing&amp;quot;&amp;gt; PREVIEWING THE WORK&amp;lt;/div&amp;gt;&lt;br /&gt;
		    &amp;lt;form phx-submit = &amp;quot;send&amp;quot;   id=&amp;quot;preview&amp;quot; class=&amp;quot;hidden&amp;quot;&amp;gt;&lt;br /&gt;
		      &amp;lt;textarea value = {testbed.note}&amp;gt;&amp;lt;/textarea&amp;gt;&lt;br /&gt;
		      &amp;lt;.button type=&amp;quot;submit&amp;quot; phx-click={hide_modal(&amp;quot;notes-modal-#{testbed.id}&amp;quot;)}&amp;gt;SAVE WORK&amp;lt;/.button&amp;gt;&lt;br /&gt;
		    &amp;lt;/form&amp;gt;&lt;br /&gt;
		&amp;lt;/.modal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;%= if testbed.note do %&amp;gt;&lt;br /&gt;
      &amp;lt;div phx-click={show_modal(&amp;quot;notes-modal-#{testbed.id}&amp;quot;)}&amp;gt;READ ME  ...&amp;lt;%= testbed.note %&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
	   &lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
       &lt;br /&gt;
      &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
import {HfInference} from &amp;quot;@huggingface/inference&amp;quot;;&lt;br /&gt;
import dotenv from &amp;quot;dotenv&amp;quot;;&lt;br /&gt;
dotenv.config()&lt;br /&gt;
&lt;br /&gt;
const HF_ACCESS_TOKEN = process.env.HF_ACCESS_TOKEN&lt;br /&gt;
&lt;br /&gt;
const hf = new HfInference(HF_ACCESS_TOKEN);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*______Uncomment for this example______________________&lt;br /&gt;
&lt;br /&gt;
const model = &amp;quot;nlpconnect/vit-gpt2-image-captioning&amp;quot;;&lt;br /&gt;
const imageURL = &amp;quot;https://i.imgur.com/lTvb7Et.png&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
const response = await fetch(imageURL);&lt;br /&gt;
const imageBlob = await response.blob();&lt;br /&gt;
&lt;br /&gt;
const result  = await hf.imageToText({&lt;br /&gt;
	data: imageBlob,&lt;br /&gt;
	model: model,&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
_______________________________________________________*/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*________Another example ___________________*/&lt;br /&gt;
&lt;br /&gt;
const result = await hf.summarization({&lt;br /&gt;
	model: 'facebook/bart-large-cnn',&lt;br /&gt;
	inputs: &amp;quot;The role of a dumb man is to get smarter oogy bookie boo&amp;quot;,&lt;br /&gt;
	parameters:{&lt;br /&gt;
		max_length: 100&lt;br /&gt;
	}&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
console.log(result);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
________________________________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://fly.io/phoenix-files/sdeb-toggling-element/&lt;br /&gt;
https://www.youtube.com/watch?v=vBgZvQapqhs&lt;br /&gt;
&lt;br /&gt;
https://blog.testdouble.com/posts/2022-11-28-how-to-use-javascript-with-phoenix-liveview/&lt;br /&gt;
&lt;br /&gt;
https://hexdocs.pm/phoenix_live_view/0.19.3/Phoenix.Component.html&lt;br /&gt;
_______________________________________&lt;br /&gt;
https://www.smashingmagazine.com/2011/10/quick-look-math-animations-javascript/&lt;br /&gt;
* Depth first traversal&lt;br /&gt;
* Breadth first traversal&lt;br /&gt;
&lt;br /&gt;
https://dev.to/codesphere/10-algorithms-every-developer-should-learn-3lnm&lt;br /&gt;
&lt;br /&gt;
https://www.youtube.com/watch?v=fPz40W9mfCg&lt;br /&gt;
&lt;br /&gt;
__________________________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.GroupLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  alias App.TestBeds&lt;br /&gt;
  alias App.Groups&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    {:ok, assign(socket, testbeds: TestBeds.list_testbeds(), groups: Groups.list_groups())}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;select-group&amp;quot;, params, socket)  do  &lt;br /&gt;
         &lt;br /&gt;
       IO.inspect params&lt;br /&gt;
       {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div class=&amp;quot;grid grid-columns-2 grid-flow-col gap-4&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;column-1&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;%= testbed.name %&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;column-2&amp;quot;&amp;gt;    &lt;br /&gt;
            &amp;lt;form phx-change=&amp;quot;select-group&amp;quot;  &amp;gt;&lt;br /&gt;
               &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;testbed_id&amp;quot; value={testbed.id}/&amp;gt;&lt;br /&gt;
               &amp;lt;select id=&amp;quot;group-selection&amp;quot;  name=&amp;quot;group-id&amp;quot; &amp;gt;&lt;br /&gt;
                &amp;lt;%= for group &amp;lt;- @groups do %&amp;gt;&lt;br /&gt;
                  &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}  &amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
               &amp;lt;/select&amp;gt;&lt;br /&gt;
            &amp;lt;/form&amp;gt;&lt;br /&gt;
         &amp;lt;/div&amp;gt;&lt;br /&gt;
       &amp;lt;% end %&amp;gt;&lt;br /&gt;
   &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
____________________________&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.GroupLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  alias App.TestBeds&lt;br /&gt;
  alias App.Groups&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
&lt;br /&gt;
    {:ok, assign(socket, testbeds: TestBeds.list_testbeds(), groups: Groups.list_groups(), messages: [])}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;select-group&amp;quot;, params, socket)  do  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
      group = App.Groups.get_group!(params[&amp;quot;group-id&amp;quot;])&lt;br /&gt;
       # IO.inspect group&lt;br /&gt;
       testbed = App.TestBeds.get_test_bed!(params[&amp;quot;testbed_id&amp;quot;])&lt;br /&gt;
     &lt;br /&gt;
       App.TestBeds.update_test_bed(testbed, %{group_id: group.id})&lt;br /&gt;
         &lt;br /&gt;
    &lt;br /&gt;
       {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def updated_groups(testbed_id)  do  &lt;br /&gt;
       groups = App.Groups.list_groups&lt;br /&gt;
       tail = Enum.filter(groups, fn(item)-&amp;gt; item.id !== testbed_id end)&lt;br /&gt;
       head = Enum.filter(groups, fn(item)-&amp;gt; item.id == testbed_id end)&lt;br /&gt;
              |&amp;gt;Enum.at(0)&lt;br /&gt;
     [head | tail]&lt;br /&gt;
         &lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
 # def handle_event(&amp;quot;groups&amp;quot;, params, socket)do  &lt;br /&gt;
 #       selected_testbed = %{name: &amp;quot;my testbed name&amp;quot;, id: 3}&lt;br /&gt;
 #       groups = App.Groups.list_groups&lt;br /&gt;
 #       tail = Enum.filter(groups, fn(item)-&amp;gt; item.id !== selected_testbed.id end)&lt;br /&gt;
 #       head = Enum.filter(groups, fn(item)-&amp;gt; item.id == selected_testbed.id end)&lt;br /&gt;
 #              |&amp;gt;Enum.at(0)&lt;br /&gt;
         &lt;br /&gt;
 &lt;br /&gt;
 #       # result = Enum.filter([1, 2, 3], fn x -&amp;gt; x.id !== 1 end)&lt;br /&gt;
 #      IO.inspect [head | tail]&lt;br /&gt;
         &lt;br /&gt;
 #      #&lt;br /&gt;
 #      {:noreply, socket, assigns.message:}&lt;br /&gt;
 #  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    &lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
       &amp;lt;%!-- &amp;lt;div phx-click = &amp;quot;groups&amp;quot;&amp;gt;CLICK ME&amp;lt;/div&amp;gt; --%&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;grid grid-cols-4 gap-4 p-8 rounded shadow bg-white&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;h2&amp;gt; Name&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;%= testbed.name %&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;h2&amp;gt; Group&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;form phx-change=&amp;quot;select-group&amp;quot; name=&amp;quot;testbed_id&amp;quot;  &amp;gt;&lt;br /&gt;
               &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;testbed_id&amp;quot; value={testbed.id}/&amp;gt;&lt;br /&gt;
               &amp;lt;select id=&amp;quot;group-selection&amp;quot;  name=&amp;quot;group-id&amp;quot; class=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
                &amp;lt;%= for group &amp;lt;- updated_groups(testbed.id) do %&amp;gt;&lt;br /&gt;
                  &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}  &amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
                  &amp;lt;!-- Write code to reorder with testbed.group_id matching group_id --&amp;gt;&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
               &amp;lt;/select&amp;gt;&lt;br /&gt;
            &amp;lt;/form&amp;gt;&lt;br /&gt;
          &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
       &amp;lt;% end %&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_____________________________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
   use AppWeb, :live_view  &lt;br /&gt;
     alias App.Testbeds&lt;br /&gt;
  alias App.Groups&lt;br /&gt;
   def mount(_params, _session, socket)  do&lt;br /&gt;
	     {:ok, assign(socket, testbeds: Testbeds.list_testbeds(), groups: Groups.list_groups())}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
   def handle_event(&amp;quot;select-group&amp;quot;, params, socket)  do  &lt;br /&gt;
       group = App.Groups.get_group!(params[&amp;quot;group-id&amp;quot;])&lt;br /&gt;
       testbed = App.Testbeds.get_testbed!(params[&amp;quot;testbed_id&amp;quot;])&lt;br /&gt;
       result = App.Testbeds.update_testbed(testbed, %{group_id: group.id})&lt;br /&gt;
       IO.inspect result&lt;br /&gt;
      &lt;br /&gt;
       {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
    def updated_groups(testbed_id)  do  &lt;br /&gt;
       testbed = App.Testbeds.get_testbed!(testbed_id)&lt;br /&gt;
       groups = App.Groups.list_groups&lt;br /&gt;
       tail = Enum.filter(groups, fn(item)-&amp;gt; item.id !== testbed.group_id end)&lt;br /&gt;
       head = Enum.filter(groups, fn(item)-&amp;gt; item.id == testbed.group_id end)&lt;br /&gt;
              |&amp;gt;Enum.at(0)&lt;br /&gt;
 &lt;br /&gt;
       [head | tail]&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    &lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;grid grid-cols-4 gap-4 p-8 rounded shadow bg-white&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;h2&amp;gt; Name&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;%= testbed.name %&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;h2&amp;gt; Group&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;form phx-change=&amp;quot;select-group&amp;quot; name=&amp;quot;testbed_id&amp;quot;  &amp;gt;&lt;br /&gt;
               &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;testbed_id&amp;quot; value={testbed.id}/&amp;gt;&lt;br /&gt;
               &amp;lt;select id=&amp;quot;group-selection&amp;quot;  name=&amp;quot;group-id&amp;quot; class=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
                &amp;lt;%= for group &amp;lt;- updated_groups(testbed.id) do %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
                  &amp;lt;%!-- &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}&amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt; --%&amp;gt;&lt;br /&gt;
                  &amp;lt;!-- Write code to reorder with testbed.group_id matching group_id --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
                  &amp;lt;%= if group !== nil do %&amp;gt;&lt;br /&gt;
                      &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}&amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
       &lt;br /&gt;
                  &amp;lt;% end %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
               &amp;lt;/select&amp;gt;&lt;br /&gt;
            &amp;lt;/form&amp;gt;&lt;br /&gt;
          &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
       &amp;lt;% end %&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  has_many :testbeds, TestBed, on_delete: :restrict   # Has many&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://elixirforum.com/t/ecto-has-many-on-delete-protect/49550&lt;br /&gt;
&lt;br /&gt;
https://hexdocs.pm/ecto/Ecto.Changeset.html#unique_constraint/3&lt;br /&gt;
&lt;br /&gt;
____________________________________________________________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== How to Create a Mix Project and Use It in Another Mix Project ==&lt;br /&gt;
&lt;br /&gt;
To create and use a **Mix project** inside another **Mix project** in Elixir, follow the steps below:&lt;br /&gt;
&lt;br /&gt;
=== 1. Create a New Mix Project ===&lt;br /&gt;
&lt;br /&gt;
First, you need to create a new Mix project. Let's call this project `library_project`. Run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mix new library_project --module LibraryProject&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will create a new Elixir Mix project named `library_project`. The `--module` flag specifies the name of the module that will be created (in this case `LibraryProject`).&lt;br /&gt;
&lt;br /&gt;
The directory structure of `library_project` will look like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
library_project/&lt;br /&gt;
  |_ lib/&lt;br /&gt;
      |_ library_project.ex&lt;br /&gt;
  |_ mix.exs&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can then add some basic functionality inside the `library_project/lib/library_project.ex` file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule LibraryProject do&lt;br /&gt;
  def hello do&lt;br /&gt;
    IO.puts &amp;quot;Hello from LibraryProject!&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now, `library_project` is ready to be used by another Mix project.&lt;br /&gt;
&lt;br /&gt;
=== 2. Create a Second Mix Project ===&lt;br /&gt;
&lt;br /&gt;
Next, create the second Mix project where you want to use `library_project`. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mix new app_project --module AppProject&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will create another Elixir project called `app_project`.&lt;br /&gt;
&lt;br /&gt;
The directory structure for this project will look like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
app_project/&lt;br /&gt;
  |_ lib/&lt;br /&gt;
      |_ app_project.ex&lt;br /&gt;
  |_ mix.exs&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 3. Add `library_project` as a Dependency in `app_project` ===&lt;br /&gt;
&lt;br /&gt;
Now, you want to make `library_project` available in `app_project`. There are two main ways to do this:&lt;br /&gt;
&lt;br /&gt;
==== Option 1: Local Dependency (via `path`) ====&lt;br /&gt;
&lt;br /&gt;
If `library_project` is a local project (i.e., it's stored in a different directory), you can add it to the `mix.exs` of `app_project` as a local dependency by specifying the path to `library_project`.&lt;br /&gt;
&lt;br /&gt;
Edit the `mix.exs` of `app_project`:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule AppProject.MixProject do&lt;br /&gt;
  use Mix.Project&lt;br /&gt;
&lt;br /&gt;
  def project do&lt;br /&gt;
    [&lt;br /&gt;
      app: :app_project,&lt;br /&gt;
      version: &amp;quot;0.1.0&amp;quot;,&lt;br /&gt;
      elixir: &amp;quot;~&amp;gt; 1.14&amp;quot;,&lt;br /&gt;
      start_permanent: Mix.env() == :prod,&lt;br /&gt;
      deps: deps()&lt;br /&gt;
    ]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  defp deps do&lt;br /&gt;
    [&lt;br /&gt;
      {:library_project, path: &amp;quot;../library_project&amp;quot;}  # Add the local dependency&lt;br /&gt;
    ]&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here, `{:library_project, path: &amp;quot;../library_project&amp;quot;}` tells Mix to use the local `library_project` located in the `../library_project` directory (relative to `app_project`).&lt;br /&gt;
&lt;br /&gt;
After updating the `mix.exs`, run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd app_project&lt;br /&gt;
mix deps.get&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will fetch the dependency and compile `library_project`.&lt;br /&gt;
&lt;br /&gt;
==== Option 2: Publish and Fetch as a Hex Package ====&lt;br /&gt;
&lt;br /&gt;
If you want to use `library_project` as a package in another project (for example, by publishing it to **Hex.pm**, Elixir’s package manager), you need to publish it to Hex and then add it as a dependency.&lt;br /&gt;
&lt;br /&gt;
1. Publish `library_project` to Hex (if it's public or for your private use).&lt;br /&gt;
2. Add `library_project` to your `app_project`’s `mix.exs` dependencies:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defp deps do&lt;br /&gt;
  [&lt;br /&gt;
    {:library_project, &amp;quot;~&amp;gt; 0.1.0&amp;quot;}  # Specify the published version from Hex&lt;br /&gt;
  ]&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Run `mix deps.get` to fetch the package from Hex.&lt;br /&gt;
&lt;br /&gt;
=== 4. Use `library_project` in `app_project` ===&lt;br /&gt;
&lt;br /&gt;
Now, you can use the functionality from `library_project` inside your `app_project`. For example, in `app_project/lib/app_project.ex`, you can call the function from `library_project`:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule AppProject do&lt;br /&gt;
  def start do&lt;br /&gt;
    IO.puts &amp;quot;Starting app_project!&amp;quot;&lt;br /&gt;
    LibraryProject.hello()  # Call the function from the library_project&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 5. Run the App ===&lt;br /&gt;
&lt;br /&gt;
Finally, you can run your `app_project`:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd app_project&lt;br /&gt;
mix run -e &amp;quot;AppProject.start()&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will print:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Starting app_project!&lt;br /&gt;
Hello from LibraryProject!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Recap of the Process ==&lt;br /&gt;
1. **Create the `library_project`**: Use `mix new` to generate a library project.&lt;br /&gt;
2. **Create the `app_project`**: Create the second project where you will use the library.&lt;br /&gt;
3. **Add the `library_project` as a dependency**:&lt;br /&gt;
   - Use the `path` option to point to the local project or publish it to Hex for public access.&lt;br /&gt;
4. **Use the `library_project` in the `app_project`**: Call functions or use modules from the library inside the second project.&lt;br /&gt;
5. **Run the app**: Use `mix run` to execute the project.&lt;br /&gt;
&lt;br /&gt;
This way, you can reuse code from one Mix project in another by adding it as a dependency.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==z==&lt;br /&gt;
Overloaded functions are extremely common in Elixir applications. They are&lt;br /&gt;
regularly used for recursive functions and for changing behavior based on&lt;br /&gt;
configuration.&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>http://elixirblocks.com/index.php?title=User:Admin&amp;diff=1869</id>
		<title>User:Admin</title>
		<link rel="alternate" type="text/html" href="http://elixirblocks.com/index.php?title=User:Admin&amp;diff=1869"/>
		<updated>2024-12-23T00:57:27Z</updated>

		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;________________________________________________________&lt;br /&gt;
&lt;br /&gt;
# CRUD Forms&lt;br /&gt;
&lt;br /&gt;
To understand CRUD forms you will need to understand the following concepts. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Ecto Schema&lt;br /&gt;
* Ecto Context&lt;br /&gt;
* Form Basics&lt;br /&gt;
* form/1&lt;br /&gt;
* simple_form/1&lt;br /&gt;
* changesets&lt;br /&gt;
&lt;br /&gt;
We are not going to go in order. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_______________________________________________________&lt;br /&gt;
In that case, you really should switch it to prod mode. Instead of doing all that above with the &amp;quot;config/secret.exs&amp;quot; file, create the &amp;quot;.env&amp;quot; in the project root, then add DotenvParser.load_file(&amp;quot;.env&amp;quot;) to &amp;quot;config/runtime.exs&amp;quot; as the first line inside the if config_env() == :prod do. In the .env file, set the DATABASE_URL and SECRET_KEY_BASE. Then run it as MIX_ENV=prod mix phx.server.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def get_titles do&lt;br /&gt;
    urls = [&lt;br /&gt;
      &amp;quot;https://cointelegraph.com/rss&amp;quot;,&lt;br /&gt;
      &amp;quot;https://chaski.huffpost.com/us/auto/vertical/us-news&amp;quot;&lt;br /&gt;
      # Add more RSS feed URLs here&lt;br /&gt;
    ]&lt;br /&gt;
&lt;br /&gt;
    urls&lt;br /&gt;
    |&amp;gt; Enum.map(fn url -&amp;gt;&lt;br /&gt;
      with {:ok, feed} &amp;lt;- ElixirRss.fetch_and_parse(url) do&lt;br /&gt;
        Enum.map(feed.entries, &amp;amp; &amp;amp;1.title)&lt;br /&gt;
      else&lt;br /&gt;
        {:error, reason} -&amp;gt; {:error, reason}&lt;br /&gt;
      end&lt;br /&gt;
    end)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule App do&lt;br /&gt;
&lt;br /&gt;
  def get_titles() do&lt;br /&gt;
    data = [&lt;br /&gt;
      &amp;quot;https://cointelegraph.com/rss&amp;quot;,&lt;br /&gt;
      &amp;quot;https://chaski.huffpost.com/us/auto/vertical/us-news&amp;quot;&lt;br /&gt;
      # Add more RSS feed URLs here&lt;br /&gt;
    ]&lt;br /&gt;
&lt;br /&gt;
    data&lt;br /&gt;
    |&amp;gt; Enum.map(fn url -&amp;gt;&lt;br /&gt;
      case ElixirRss.fetch_and_parse(url) do&lt;br /&gt;
        {:ok, feed} -&amp;gt; feed.entries |&amp;gt; Enum.map(fn entry -&amp;gt; entry end)&lt;br /&gt;
        {:error, reason} -&amp;gt; {:error, reason}&lt;br /&gt;
      end&lt;br /&gt;
    end)&lt;br /&gt;
    |&amp;gt; Enum.map(fn entry_list -&amp;gt;&lt;br /&gt;
      entry_list&lt;br /&gt;
      |&amp;gt; Enum.map(fn entry -&amp;gt; entry.title end)&lt;br /&gt;
    end)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def hello do&lt;br /&gt;
    rss_feeds = [&lt;br /&gt;
      &amp;quot;https://cointelegraph.com/rss&amp;quot;,&lt;br /&gt;
      &amp;quot;https://chaski.huffpost.com/us/auto/vertical/us-news&amp;quot;&lt;br /&gt;
      # Add more RSS feed URLs here&lt;br /&gt;
    ]&lt;br /&gt;
&lt;br /&gt;
    rss_feeds&lt;br /&gt;
    |&amp;gt; Enum.map(fn url -&amp;gt;&lt;br /&gt;
      case ElixirRss.fetch_and_parse(url) do&lt;br /&gt;
        {:ok, feed} -&amp;gt; feed.entries |&amp;gt; Enum.map(fn entry -&amp;gt; entry end)&lt;br /&gt;
        {:error, reason} -&amp;gt; {:error, reason}&lt;br /&gt;
      end&lt;br /&gt;
    end)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    if connected?(socket) do&lt;br /&gt;
      Phoenix.PubSub.subscribe(App.PubSub, &amp;quot;message&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
    {:ok, assign(socket, message_item: &amp;quot;different&amp;quot;)}&lt;br /&gt;
  end&lt;br /&gt;
  def handle_info({:pubsub_transmission, text}, socket) do&lt;br /&gt;
    IO.inspect &amp;quot;pub sub working&amp;quot;&lt;br /&gt;
    {:noreply, assign(socket, message_item: text)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def loop(data) do&lt;br /&gt;
     IO.inspect data&lt;br /&gt;
     if data &amp;gt; 0 do&lt;br /&gt;
      IO.inspect &amp;quot;notify&amp;quot;&lt;br /&gt;
      # run code to compare files, loop. If different run pubsub code below&lt;br /&gt;
      :timer.sleep(2000)&lt;br /&gt;
      loop(data-1)&lt;br /&gt;
&lt;br /&gt;
     end&lt;br /&gt;
     if data &amp;lt;= 0 do&lt;br /&gt;
&lt;br /&gt;
      Phoenix.PubSub.broadcast(App.PubSub, &amp;quot;message&amp;quot;, {:pubsub_transmission, &amp;quot;data&amp;quot;})&lt;br /&gt;
      &amp;quot;done&amp;quot;&lt;br /&gt;
     end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;change-text&amp;quot;, _params, socket) do&lt;br /&gt;
    spawn(fn -&amp;gt; loop(3) end)&lt;br /&gt;
    {:noreply, assign(socket, message_item: &amp;quot;START&amp;quot; )}&lt;br /&gt;
  end&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
&lt;br /&gt;
    # AppWeb.PageLive.loop(&amp;quot;xxx&amp;quot;)&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    SANDBOX&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;.button phx-click=&amp;quot;change-text&amp;quot; value={@message_item}&amp;gt;CLICK ME&amp;lt;/.button&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;%= @message_item %&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
elixir :   1.16.2&lt;br /&gt;
&lt;br /&gt;
Erl:   20&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# PostGres&lt;br /&gt;
Created Saturday 18 February 2023&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Launch [PostGres](#PostGres) from Terminal&lt;br /&gt;
------------------------------------------&lt;br /&gt;
sudo -u postgres psql&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Set User Permission&lt;br /&gt;
-------------------&lt;br /&gt;
&amp;lt;https://commandprompt.com/education/how-to-create-a-superuser-in-postgresql/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ALTER USER user_name WITH PASSWORD 'new_password';&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Run Post Gres Commands&lt;br /&gt;
----------------------&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
sudo -i -u postgres&lt;br /&gt;
psql&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Create and Delete Database&lt;br /&gt;
&lt;br /&gt;
CREATE DATABASE name;&lt;br /&gt;
DROP DATABASE name;&lt;br /&gt;
## View user list&lt;br /&gt;
&lt;br /&gt;
\du&lt;br /&gt;
&lt;br /&gt;
 View all databases&lt;br /&gt;
&lt;br /&gt;
postgres=# \l&lt;br /&gt;
&lt;br /&gt;
 Change databases&lt;br /&gt;
&lt;br /&gt;
postgres=# \c    name-of-database&lt;br /&gt;
&lt;br /&gt;
View Tables&lt;br /&gt;
&lt;br /&gt;
After you change databases and are selected on one of them do this:&lt;br /&gt;
&lt;br /&gt;
\dt&lt;br /&gt;
&lt;br /&gt;
SELECT * FROM mytablename;&lt;br /&gt;
&lt;br /&gt;
EMPTY TABLE&lt;br /&gt;
DELETE FROM name-of-table&lt;br /&gt;
&lt;br /&gt;
CREATE TABLE&lt;br /&gt;
&lt;br /&gt;
CREATE TABLE table_name(&lt;br /&gt;
   column1 datatype,&lt;br /&gt;
   column2 datatype,&lt;br /&gt;
   column3 datatype,&lt;br /&gt;
   .....&lt;br /&gt;
   columnN datatype,&lt;br /&gt;
   PRIMARY KEY( one or more columns )&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
INSERT&lt;br /&gt;
&lt;br /&gt;
INSERT INTO ITEMS(id, name) VALUES(1,'htvjbjbgni');     Strings are single quote&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Roadmap==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.ItemsLive do&lt;br /&gt;
    use AppWeb, :live_view  &lt;br /&gt;
    def mount(_params, _session, socket)  do&lt;br /&gt;
      {:ok, assign(socket, switches: [&amp;quot;grindy&amp;quot;,&amp;quot;sonic&amp;quot;,&amp;quot;ogre&amp;quot;])}  &lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    def handle_event(&amp;quot;run&amp;quot;,_params,socket) do  &lt;br /&gt;
        &lt;br /&gt;
        IO.inspect &amp;quot;DOWNLOAD VIA SSH&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        {:noreply, redirect(socket, to: &amp;quot;/download&amp;quot;)}&lt;br /&gt;
&lt;br /&gt;
    end&lt;br /&gt;
   &lt;br /&gt;
&lt;br /&gt;
    def render(assigns) do&lt;br /&gt;
        &lt;br /&gt;
        ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        &amp;lt;ul&amp;gt;&lt;br /&gt;
        &amp;lt;%= for switch &amp;lt;- @switches do %&amp;gt;&lt;br /&gt;
         &amp;lt;a phx-submit=&amp;quot;click&amp;quot; href=&amp;quot;/download&amp;quot;&amp;gt;  &amp;lt;li&amp;gt; &amp;lt;%= switch %&amp;gt;  &amp;lt;/li&amp;gt; &amp;lt;/a&amp;gt;&lt;br /&gt;
&lt;br /&gt;
        &amp;lt;%end%&amp;gt;&lt;br /&gt;
        &amp;lt;/ul&amp;gt;&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot; &lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Notes==&lt;br /&gt;
List of Switches and the option to select the one needed.&lt;br /&gt;
Button to download JSON file.&lt;br /&gt;
Drag and Drop Palette to upload JSON file.&lt;br /&gt;
&lt;br /&gt;
After JSON file is uploaded a button titled &amp;quot;Make Active&amp;quot; is available.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://medium.com/@fraiha26/pushing-events-to-livecomponents-from-js-hooks-w-phoenix-elixir-d5544d4c3dfa&lt;br /&gt;
&lt;br /&gt;
Changeset notes and forms&lt;br /&gt;
&lt;br /&gt;
NOTE: Use case statements for pattern matching&lt;br /&gt;
____________________________________________&lt;br /&gt;
&lt;br /&gt;
Create a basic &amp;lt;.form&amp;gt;&amp;lt;/form&amp;gt; without error handling&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&amp;lt;.form :let={f} for={@changeset}  action={~p&amp;quot;/items&amp;quot;} &amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;.input field={f[:title]} type=&amp;quot;text&amp;quot; label=&amp;quot;Title&amp;quot; /&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
  &amp;lt;.button&amp;gt;Save Item&amp;lt;/.button&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;/.form&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With error handling looks like this:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;.form :let={f} for={@changeset}  action={~p&amp;quot;/items&amp;quot;} &amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;.error :if={@changeset.action}&amp;gt;&lt;br /&gt;
    Oops, something went wrong! Please check the errors below.&lt;br /&gt;
  &amp;lt;/.error&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;.input field={f[:title]} type=&amp;quot;text&amp;quot; label=&amp;quot;Title&amp;quot; /&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
  &amp;lt;.button&amp;gt;Save Item&amp;lt;/.button&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;/.form&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Create the routes for render and post to endpoint.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The controller for the page render needs to pass in the changeset via ```Items.change_item(%Item{})```&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  def new(conn, _params) do&lt;br /&gt;
    changeset = Items.change_item(%Item{})&lt;br /&gt;
    render(conn, :new, changeset: changeset)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Post route without error handling&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  def create(conn, %{&amp;quot;item&amp;quot; =&amp;gt; item_params}) do&lt;br /&gt;
    case Items.create_item(item_params) do&lt;br /&gt;
      {:ok, item} -&amp;gt;&lt;br /&gt;
        conn&lt;br /&gt;
        |&amp;gt; put_flash(:info, &amp;quot;Item created successfully.&amp;quot;)&lt;br /&gt;
        |&amp;gt; redirect(to: ~p&amp;quot;/items/#{item}&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With error handling&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  def create(conn, %{&amp;quot;item&amp;quot; =&amp;gt; item_params}) do&lt;br /&gt;
    case Items.create_item(item_params) do&lt;br /&gt;
      {:ok, item} -&amp;gt;&lt;br /&gt;
        conn&lt;br /&gt;
        |&amp;gt; put_flash(:info, &amp;quot;Item created successfully.&amp;quot;)&lt;br /&gt;
        |&amp;gt; redirect(to: ~p&amp;quot;/items/#{item}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
      {:error, %Ecto.Changeset{} = changeset} -&amp;gt;&lt;br /&gt;
        render(conn, :new, changeset: changeset)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_____________________________________________&lt;br /&gt;
https://medium.com/@vincentlin/phoenix-very-simple-form-c4b121697fcb&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''home.html.heex'''&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&amp;lt;form action=&amp;quot;/submit&amp;quot; method=&amp;quot;post&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;label for=&amp;quot;name&amp;quot;&amp;gt;Name:&amp;lt;/label&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;input type=&amp;quot;text&amp;quot; id=&amp;quot;name&amp;quot; name=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;_csrf_token&amp;quot; value={@csrf_token} /&amp;gt;&lt;br /&gt;
  &amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Submit&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
page_controller.ex&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.PageController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  def home(conn, _params) do&lt;br /&gt;
    # The home page is often custom made,&lt;br /&gt;
&lt;br /&gt;
    csrf_token = Plug.CSRFProtection.get_csrf_token()&lt;br /&gt;
    render(conn, :home, csrf_token: csrf_token)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def submit(conn, _params) do&lt;br /&gt;
    # The home page is often custom made,&lt;br /&gt;
     IO.inspect(_params)&lt;br /&gt;
     IO.inspect &amp;quot;___________________________&amp;quot;&lt;br /&gt;
    csrf_token = Plug.CSRFProtection.get_csrf_token()&lt;br /&gt;
    render(conn, :home, csrf_token: csrf_token)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
router.ex&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  scope &amp;quot;/&amp;quot;, AppWeb do&lt;br /&gt;
    pipe_through :browser&lt;br /&gt;
    post &amp;quot;/submit&amp;quot;, PageController, :submit&lt;br /&gt;
    get &amp;quot;/&amp;quot;, PageController, :home&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ecto.Adapters.SQL.query(Repo, &amp;quot;select * from artists where id=1&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ecto cheatsheet:  https://hexdocs.pm/ecto/crud.html&lt;br /&gt;
__________________________________________________________________&lt;br /&gt;
Most programming languages give you the ability to set global state by creating globally scoped variables. Elixir does not do this. Instead, Elixir provides a tool called a &amp;quot;processes&amp;quot; to persist  state. Elixir applications are composed of these &amp;quot;processes&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
Processes by themselves are complicated to use, thus Elixir provides abstractions to make working with processes easier. One of these abstractions is called a GenServer.&lt;br /&gt;
&lt;br /&gt;
GenServers are not only used to store state, they are also used to invoke work independent of the main application process. &lt;br /&gt;
&lt;br /&gt;
==Creating a GenServer to Store State==&lt;br /&gt;
&lt;br /&gt;
To Create a GenServer, start by creating a basic Module that ''uses'' the GenServer module (image below)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule App do  &lt;br /&gt;
  use GenServer&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We now need to describe the actions we want to perform. Being that this is used to store state, we will use basic CRUD actions: Create, Read, Update, Delete. To begins, empty functions describing each action is created.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule App do&lt;br /&gt;
   def create do &lt;br /&gt;
&lt;br /&gt;
   end&lt;br /&gt;
   def read do &lt;br /&gt;
&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
   def update do  &lt;br /&gt;
&lt;br /&gt;
   end &lt;br /&gt;
&lt;br /&gt;
   def delete do &lt;br /&gt;
&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==What now?==&lt;br /&gt;
&lt;br /&gt;
To fill in the functions with the appropriate code we must first have a basic understanding of how GenServers are structured.&lt;br /&gt;
&lt;br /&gt;
GenServers are composed of the GenServer module invoking callbacks. The callbacks have built in names that you, as a developer have to use.&lt;br /&gt;
&lt;br /&gt;
These callbacks are named:&lt;br /&gt;
&lt;br /&gt;
* init&lt;br /&gt;
* handle_cast&lt;br /&gt;
* handle_call&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To demonstrate, here is an example :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{:ok, pid} = GenServer.start(ModuleNameOfGenServer, %{})&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above function named &amp;quot;start&amp;quot; calls the function named init in the Module below.&lt;br /&gt;
In GenServer syntax the name of the GenServer functions always invoke callbacks that are determined by the language. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule ModuleNameOfGenServer do&lt;br /&gt;
  # 1&lt;br /&gt;
  def init(state \\ %{}) do&lt;br /&gt;
    {:ok, state}&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is a list of the GenServer functions and their corresponding callbacks.&lt;br /&gt;
&lt;br /&gt;
* GenServer.start/1  --&amp;gt;       init/1&lt;br /&gt;
* GenServer.call/3   --&amp;gt;       def handle_call/3&lt;br /&gt;
* GenServer.cast/2   --&amp;gt;       handle_cast/2&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Start and Call ==&lt;br /&gt;
&lt;br /&gt;
Call and Cast can be used to perform the same operations. The &lt;br /&gt;
&lt;br /&gt;
__________________________________________________________&lt;br /&gt;
Genserver timed events&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule Go do&lt;br /&gt;
  use GenServer&lt;br /&gt;
&lt;br /&gt;
  def go() do&lt;br /&gt;
    GenServer.start_link(__MODULE__, [])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def init(list) do&lt;br /&gt;
    :timer.apply_interval(1000, __MODULE__, :add, [self(), &amp;quot;weeeee&amp;quot;])&lt;br /&gt;
    {:ok, list}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def view(pid) do&lt;br /&gt;
    GenServer.call(pid, :view)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_call(:view, _from, list) do&lt;br /&gt;
    {:reply, list, list}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def add(pid, new_item) do&lt;br /&gt;
    GenServer.call(pid, {:item, new_item})&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_call({:item, new_item}, _from, state) do&lt;br /&gt;
    result = [new_item] ++ state&lt;br /&gt;
    {:reply, result, result}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule ShoppingList do&lt;br /&gt;
  use GenServer&lt;br /&gt;
&lt;br /&gt;
  def start_link() do&lt;br /&gt;
    GenServer.start_link(ShoppingList, [])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def init(list) do&lt;br /&gt;
    {:ok, list}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def view(pid) do&lt;br /&gt;
    GenServer.call(pid, :view)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_call(:view, _from, list) do&lt;br /&gt;
    {:reply, list, list}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def add(pid, new_item) do&lt;br /&gt;
    GenServer.call(pid, {:item, new_item})&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_call({:item, new_item}, _from, state) do&lt;br /&gt;
    result = [new_item] ++ state&lt;br /&gt;
    {:reply, result, result}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://blog.appsignal.com/2018/06/12/elixir-alchemy-deconstructing-genservers.html&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule KeyValue do&lt;br /&gt;
  # 1&lt;br /&gt;
  def init(state \\ %{}) do&lt;br /&gt;
    {:ok, state}&lt;br /&gt;
  end&lt;br /&gt;
 &lt;br /&gt;
  # 2&lt;br /&gt;
  def handle_cast({:put, key, value}, state) do&lt;br /&gt;
    {:noreply, Map.put(state, key, value)}&lt;br /&gt;
  end&lt;br /&gt;
 &lt;br /&gt;
  # 3&lt;br /&gt;
  def handle_call({:get, key}, _from, state) do&lt;br /&gt;
    {:reply, Map.fetch!(state, key), state}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
# {:ok, pid} = GenServer.start(KeyValue, %{})&lt;br /&gt;
# GenServer.cast(pid, {:put, :foo, &amp;quot;bar&amp;quot;})&lt;br /&gt;
# GenServer.call(pid, {:get, :foo})&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Send messages via these functions wrapped in module functions .You can look at these are functions used to fire &amp;quot;GenServer Events&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
* start_link&lt;br /&gt;
* GenServer.call&lt;br /&gt;
* GenServer.cast&lt;br /&gt;
&lt;br /&gt;
The corresponding server functions that reply are:&lt;br /&gt;
&lt;br /&gt;
* init&lt;br /&gt;
* handle__call&lt;br /&gt;
* handle_cast&lt;br /&gt;
* &lt;br /&gt;
&lt;br /&gt;
These can be looked at as &amp;quot;listeners&amp;quot; - in JavaScript parlance. &lt;br /&gt;
__________________________________________&lt;br /&gt;
&lt;br /&gt;
If you have experience with programming languages other than Elixir the idea of GenServers may be very foreign and require a strong context shift to learn. This document is intended to simplify the concept.&lt;br /&gt;
&lt;br /&gt;
* What: GenServers are simply a way to hold state and/or invoke actions based on incoming events. &lt;br /&gt;
* when &lt;br /&gt;
* where&lt;br /&gt;
* why&lt;br /&gt;
* how&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
___________________________________________&lt;br /&gt;
GenServer timer example&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule Timer do&lt;br /&gt;
  use GenServer&lt;br /&gt;
&lt;br /&gt;
  def init(_) do&lt;br /&gt;
    :timer.send_interval(1000, :xyz)&lt;br /&gt;
    {:ok, 0}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_info(:xyz, state) do&lt;br /&gt;
    IO.inspect(state)&lt;br /&gt;
    {:noreply, state + 1}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
[&lt;br /&gt;
   {&lt;br /&gt;
     data:{&lt;br /&gt;
        creationTime,&lt;br /&gt;
        publishDate,&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
     featured:{&lt;br /&gt;
        setAmount,&lt;br /&gt;
        items:[]&lt;br /&gt;
     },&lt;br /&gt;
&lt;br /&gt;
     children:{&lt;br /&gt;
        setAmount,&lt;br /&gt;
        items:[]&lt;br /&gt;
     },&lt;br /&gt;
     links:{&lt;br /&gt;
        setAmount,&lt;br /&gt;
        items:[]&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
jason.encode / jason.decode&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  def run(num) do&lt;br /&gt;
&lt;br /&gt;
    Enum.each(0..99999, fn(_x) -&amp;gt;&lt;br /&gt;
      task = Task.async(fn -&amp;gt; num + _x end)&lt;br /&gt;
    IO.inspect Task.await(task)&lt;br /&gt;
  end)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enum.map(feed.entries, fn x -&amp;gt; %{url: x.url, title: x.title} end)&lt;br /&gt;
&lt;br /&gt;
App is split:&lt;br /&gt;
&lt;br /&gt;
App that captures RSS in UI and lets admin select stories. THere are settings to determine the number of FEATURED,CHILD and LINK stories.&lt;br /&gt;
News categories are horizontal and scrollable.&lt;br /&gt;
This exports a json doc with all RSS data for each story.&lt;br /&gt;
The &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
App that reads the json data. This app creates tables and is the front end.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://stephenbussey.com/tags/elixir.html&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule AppWeb.GroupLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  alias App.TestBeds&lt;br /&gt;
  alias App.Groups&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    {:ok, assign(socket, testbeds: TestBeds.list_testbeds(), groups: Groups.list_groups())}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;select-group&amp;quot;, params, socket)  do  &lt;br /&gt;
     group = App.Groups.get_group!(params[&amp;quot;group-id&amp;quot;])&lt;br /&gt;
     testbed = App.TestBeds.get_test_bed!(params[&amp;quot;testbed_id&amp;quot;])&lt;br /&gt;
     App.TestBeds.update_test_bed(testbed, %{group_id: group.id})&lt;br /&gt;
     {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def updated_groups(testbed_id)  do  &lt;br /&gt;
     testbed = App.TestBeds.get_test_bed!(testbed_id)&lt;br /&gt;
     groups = App.Groups.list_groups&lt;br /&gt;
     tail = Enum.filter(groups, fn(item)-&amp;gt; item.id !== testbed.group_id end)&lt;br /&gt;
     head = Enum.filter(groups, fn(item)-&amp;gt; item.id == testbed.group_id end)&lt;br /&gt;
            |&amp;gt;Enum.at(0)&lt;br /&gt;
    [head | tail]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        &amp;lt;%= for testbed &amp;lt;- Enum.sort_by(@testbeds , &amp;amp;(&amp;quot;#{&amp;amp;1.name}&amp;quot;), :asc)do %&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;grid grid-cols-4 gap-4 p-8 rounded shadow bg-white&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;h2&amp;gt; Name&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;%= testbed.name %&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;h2&amp;gt; Group&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div&amp;gt;&lt;br /&gt;
            &amp;lt;form phx-change=&amp;quot;select-group&amp;quot; name=&amp;quot;testbed_id&amp;quot;  &amp;gt;&lt;br /&gt;
               &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;testbed_id&amp;quot; value={testbed.id}/&amp;gt;&lt;br /&gt;
               &amp;lt;select id=&amp;quot;group-selection&amp;quot;  name=&amp;quot;group-id&amp;quot; class=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;%= for group &amp;lt;- updated_groups(testbed.id) do %&amp;gt;&lt;br /&gt;
                  &amp;lt;%= if group !== nil do %&amp;gt;&lt;br /&gt;
                      &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}&amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
                      &amp;lt;%else%&amp;gt;&lt;br /&gt;
                      &amp;lt;option value= {&amp;quot;Unassigned&amp;quot;}&amp;gt;NONE&amp;lt;/option&amp;gt;&lt;br /&gt;
                  &amp;lt;% end %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
               &amp;lt;/select&amp;gt;&lt;br /&gt;
            &amp;lt;/form&amp;gt;&lt;br /&gt;
          &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
       &amp;lt;% end %&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Developer Notes ==&lt;br /&gt;
===Groups Feature ===&lt;br /&gt;
To complete this feature do these things.&lt;br /&gt;
* Run through the steps in [http://elixirblocks.com/index.php?title=Create_Foreign_Key_Relationship_Between_Ecto_Tables  | this document] to create Group table.&lt;br /&gt;
* Groups have these fields  '''name: string''', '''description: string''' and '''color: string'''  &lt;br /&gt;
* Add unique constraint in migration file: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def change do&lt;br /&gt;
     create unique_index(:groups, [:name])&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Port over Group LiveView code (temporarily placed at discussion page).&lt;br /&gt;
* On completion '''possibly''', create a Group named '''No Group''' and set all Testbeds to it.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
________&lt;br /&gt;
https://blog.appsignal.com/2022/10/11/phoenix-liveview-018-new-special-html-attributes.html&lt;br /&gt;
https://blixtdev.com/whats-new-phoenix-1-7/&lt;br /&gt;
https://github.com/devato/inertia_phoenix&lt;br /&gt;
https://phoenixonrails.com/blog/you-can-stop-using-form-for-in-phoenix&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://samuelmullen.com/articles/phoenix_templates_rendering_and_layouts&lt;br /&gt;
&lt;br /&gt;
WorkFlow of Todo App in Both LiveView and DeadView.&lt;br /&gt;
&lt;br /&gt;
Note:&lt;br /&gt;
&lt;br /&gt;
Create foreign key data.&lt;br /&gt;
Create live view. List all testbeds and form to assign each a group by group-name.&lt;br /&gt;
&lt;br /&gt;
Repeat in dead view&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Mental model and data flows&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
home.html.heex&lt;br /&gt;
&amp;lt;a href=&amp;quot;/data&amp;quot; name=&amp;quot;we are the world&amp;quot; &amp;gt;  click me&amp;lt;/a&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;%= @message %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
page controller&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  def home(conn, _params) do&lt;br /&gt;
    IO.inspect _params&lt;br /&gt;
    render(conn, :home, message: &amp;quot;Hello&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
get &amp;quot;/:yay&amp;quot;, PageController, :index&lt;br /&gt;
&lt;br /&gt;
get &amp;quot;/&amp;quot;, PageController, :index&lt;br /&gt;
&lt;br /&gt;
* Explain control flow of &amp;quot;Dead Views&amp;quot; and the Generator HTML Control flow.&lt;br /&gt;
* Proper Way to use Modal&lt;br /&gt;
* How to give Focus to Fields in Modal (or other forms fields)&lt;br /&gt;
* &lt;br /&gt;
* &lt;br /&gt;
* How to Create Database Seed Data.&lt;br /&gt;
* How to structure code so controller code is in one file and HTML Heex is in another&lt;br /&gt;
* How to Use Generators in a Real World Project&lt;br /&gt;
* How to Work with Database Data via Basic Commands and Custom Change sets.&lt;br /&gt;
* How to Render Database Data to LiveView (via Context Commands).&lt;br /&gt;
* How to Create a Chat using PubSub.&lt;br /&gt;
* How to Create Event Handlers in LiveView&lt;br /&gt;
* How to Create a Dynamic Route from Scratch.&lt;br /&gt;
* How to Use Elixirs Template language&lt;br /&gt;
* How to Work with Modal&lt;br /&gt;
* How to Use CSS From Scratch (Without bundler)&lt;br /&gt;
* How to use JS hooks&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
______________________&lt;br /&gt;
https://studioindie.co/blog/heex-guide/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
get &amp;quot;/&amp;quot;, PageController, :some-atom    #This is the route. some-atom is the controller name&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  def some-atom(conn, _params) do                 # controller name&lt;br /&gt;
    # The home page is often custom made,&lt;br /&gt;
    # so skip the default app layout.&lt;br /&gt;
    render(conn, :some-atom, layout: false)      # :some-atom is template name&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Controllers page_html.ex contains &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageHTML do&lt;br /&gt;
  use AppWeb, :html&lt;br /&gt;
&lt;br /&gt;
  embed_templates &amp;quot;page_html/*&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''page_html''' is the name of the folder in '''Controllers/page_html'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Controllers/page_html/some-atom.html.heex  (this is the template) &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__________________________________________&lt;br /&gt;
Set all association with preload:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  def list_groups do&lt;br /&gt;
    Repo.all(Group)&lt;br /&gt;
     |&amp;gt; Repo.preload([:testbeds])&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Insert Child into Parent ===&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
App.get_group!(2) # arg is id&lt;br /&gt;
|&amp;gt; Ecto.build_assoc(:testbeds)&lt;br /&gt;
|&amp;gt; Repo.insert()&lt;br /&gt;
&lt;br /&gt;
Or&lt;br /&gt;
&lt;br /&gt;
group = App.get_group!(2) # arg is id&lt;br /&gt;
&lt;br /&gt;
testbeds = Ecto.build_assoc(group, :testbeds)&lt;br /&gt;
&lt;br /&gt;
App.Group.create_group(testbeds)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
group = App.Groups.get_group!(1)&lt;br /&gt;
thing = Ecto.build_assoc(group, :testbeds, name: &amp;quot;DUMB&amp;quot;)&lt;br /&gt;
alias App.{Repo}&lt;br /&gt;
Repo.insert(thing)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
avatar = %Avatar{nick_name: &amp;quot;Elixir&amp;quot;, pic_url: &amp;quot;http://elixir-lang.org/images/logo.png&amp;quot;}&lt;br /&gt;
user = %User{name: &amp;quot;John Doe&amp;quot;, email: &amp;quot;john.doe@example.com&amp;quot;, avatar: avatar}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://www.reddit.com/r/elixir/comments/oh318k/is_there_a_way_to_avoid_ectoassociationnotloaded/h4mmcfi/?utm_source=share&amp;amp;utm_medium=web3x&amp;amp;utm_name=web3xcss&amp;amp;utm_term=1&amp;amp;utm_content=share_button&lt;br /&gt;
&lt;br /&gt;
# Create Group Table&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
mix phx.gen.html Groups Group groups name:string  &lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Set the resources / &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
mix ecto.migrate&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For testbeds create a migration file and add this field:   group_id:references:groups&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
def change do&lt;br /&gt;
    alter table(:testbeds) do    # customize to your code&lt;br /&gt;
      add :group_id, references(:groups)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Update Groups Schema (Don't forget alias / has_many)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule App.Groups.Group do&lt;br /&gt;
	use Ecto.Schema&lt;br /&gt;
	import Ecto.Changeset&lt;br /&gt;
	alias App.Testbeds.Testbed   # Alias!&lt;br /&gt;
&lt;br /&gt;
	schema &amp;quot;posts&amp;quot; do&lt;br /&gt;
		field :body, :string&lt;br /&gt;
		field :title, :string&lt;br /&gt;
		has_many :testbeds, Testbed    # Has many&lt;br /&gt;
&lt;br /&gt;
		timestamps()&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	@doc false&lt;br /&gt;
	def changeset(post, attrs) do&lt;br /&gt;
		post&lt;br /&gt;
		|&amp;gt; cast(attrs, [:title, :body])&lt;br /&gt;
		|&amp;gt; validate_required([:title, :body])&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
TESTBEDS Schema&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule App.Testbeds.Testbed do&lt;br /&gt;
  use Ecto.Schema&lt;br /&gt;
  import Ecto.Changeset&lt;br /&gt;
  alias App.Groups.Group      # Alias&lt;br /&gt;
  schema &amp;quot;testbeds&amp;quot; do&lt;br /&gt;
    field :name, :string&lt;br /&gt;
    belongs_to :group, Group    # Belongs to&lt;br /&gt;
    timestamps()&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  @doc false&lt;br /&gt;
  def changeset(testbed, attrs) do&lt;br /&gt;
    testbed&lt;br /&gt;
    |&amp;gt; cast(attrs, [:name])&lt;br /&gt;
    |&amp;gt; validate_required([:name])&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
_____________________________________&lt;br /&gt;
Side notes.&lt;br /&gt;
&lt;br /&gt;
defmodule App.Repo.Migrations.CreateTestbeds do&lt;br /&gt;
  use Ecto.Migration&lt;br /&gt;
&lt;br /&gt;
  def change do&lt;br /&gt;
    create table(:testbeds) do&lt;br /&gt;
      add :name, :string&lt;br /&gt;
      add :group_id, references(:groups, on_delete: :nothing)&lt;br /&gt;
&lt;br /&gt;
      timestamps()&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    create index(:testbeds, [:group_id])&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
________________________________&lt;br /&gt;
&lt;br /&gt;
mix phx.gen.context Comments Comment comments name:string content:text post_id:references:posts&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
mix phx.gen.html Testbeds Testbed testbeds name:string  group_id:references:groups&lt;br /&gt;
&lt;br /&gt;
https://graffino.com/web-development/first-steps-in-elixir-and-phoenix-create-a-blog-prototype&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://blog.logrocket.com/getting-started-ecto-phoenix/&lt;br /&gt;
&lt;br /&gt;
https://serokell.io/blog/ecto-guide-for-beginners&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
mix phx.gen.html Testbeds Testbed testbeds name:string&lt;br /&gt;
&lt;br /&gt;
mix phx.gen.html Groups Group groups name:string&lt;br /&gt;
&lt;br /&gt;
Create migration for &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
mix ecto.gen.migration add_testbed_group_reference&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Migration:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  def change do&lt;br /&gt;
    alter table(:testbeds) do    # customize to your code&lt;br /&gt;
      add :group_id, references(:groups)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Manually Change:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule App.Group do&lt;br /&gt;
  use Ecto.Schema&lt;br /&gt;
&lt;br /&gt;
  schema &amp;quot;groups&amp;quot; do&lt;br /&gt;
    field :title, :string&lt;br /&gt;
    field :tagline, :string&lt;br /&gt;
    has_many :testbeds, App.Testbed&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
testbeds&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule App.Repo.Migrations.AddTextbedGroups do&lt;br /&gt;
  use Ecto.Migration&lt;br /&gt;
&lt;br /&gt;
  def change do&lt;br /&gt;
    create table(:testbeds) do&lt;br /&gt;
      add :name, :string&lt;br /&gt;
      add :group_id, references(:groups)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
# lib/app/testbeds.ex&lt;br /&gt;
&lt;br /&gt;
defmodule App.Testbed do&lt;br /&gt;
  use Ecto.Schema&lt;br /&gt;
&lt;br /&gt;
  schema &amp;quot;testbedss&amp;quot; do&lt;br /&gt;
    field :name, :string&lt;br /&gt;
    belongs_to :group, App.Group&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_____________________&lt;br /&gt;
&lt;br /&gt;
%App.TestBeds.TestBed{&lt;br /&gt;
  __meta__: #Ecto.Schema.Metadata&amp;lt;:loaded, &amp;quot;testbeds&amp;quot;&amp;gt;,&lt;br /&gt;
  id: 1,&lt;br /&gt;
  developer: &amp;quot;None&amp;quot;,&lt;br /&gt;
  name: &amp;quot;sdfsd&amp;quot;,&lt;br /&gt;
  owner: &amp;quot;sdfsddf&amp;quot;,&lt;br /&gt;
  note: &amp;quot;sdsfsddf&amp;quot;,&lt;br /&gt;
  status: &amp;quot;Available&amp;quot;,&lt;br /&gt;
  url: &amp;quot;sdf&amp;quot;,&lt;br /&gt;
  version: &amp;quot;ddf&amp;quot;,&lt;br /&gt;
  manager: &amp;quot;sf&amp;quot;,&lt;br /&gt;
  inserted_at: ~N[2023-08-21 13:45:39],&lt;br /&gt;
  updated_at: ~N[2023-08-21 13:45:44]&lt;br /&gt;
}&lt;br /&gt;
________________________________________________________________---&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.SendLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  &lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    {:ok, socket}&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  def handle_event(&amp;quot;send&amp;quot;, %{&amp;quot;text&amp;quot; =&amp;gt; text}, socket) do&lt;br /&gt;
&lt;br /&gt;
    AppWeb.Endpoint.broadcast(topic, &amp;quot;message&amp;quot;, text)&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  defp topic do&lt;br /&gt;
    &amp;quot;chat&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def render(assigns)do   &lt;br /&gt;
   ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
  &amp;lt;h1&amp;gt;Send Message&amp;lt;/h1&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;form phx-submit=&amp;quot;send&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;text&amp;quot; /&amp;gt;&lt;br /&gt;
    &amp;lt;button type=&amp;quot;submit&amp;quot;&amp;gt;Send&amp;lt;/button&amp;gt;&lt;br /&gt;
  &amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
______________________________________________________________&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.ReceiveLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  &lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    if connected?(socket) do&lt;br /&gt;
      AppWeb.Endpoint.subscribe(topic)&lt;br /&gt;
    end&lt;br /&gt;
    {:ok, assign(socket, messages: &amp;quot;&amp;quot;)}&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def handle_info(%{event: &amp;quot;message&amp;quot;, payload: message}, socket) do&lt;br /&gt;
    IO.inspect message&lt;br /&gt;
    {:noreply, assign(socket, messages: message)}&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  defp topic do&lt;br /&gt;
    &amp;quot;chat&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns)do   &lt;br /&gt;
   ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
  &amp;lt;h1&amp;gt;ChatLive&amp;lt;/h1&amp;gt;&lt;br /&gt;
  &amp;lt;%= @messages %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
______________________________________________________________&lt;br /&gt;
When you hover over a list of items this hook finds items with the same name and sets the opacity of all others to 0. You see all the items similar to the one you are hovering over.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
TestbedVersionHover: {&lt;br /&gt;
			// https://jsfiddle.net/IrvinDominin/7K2Z3/&lt;br /&gt;
            mounted() {&lt;br /&gt;
&lt;br /&gt;
                let rows = document.getElementsByClassName(&amp;quot;testbed-version&amp;quot;)&lt;br /&gt;
                // this.ele = element&lt;br /&gt;
				// rows = this.ele;&lt;br /&gt;
                &lt;br /&gt;
				for (var i = 0; i &amp;lt; rows.length; i++) {&lt;br /&gt;
					rows[i].onmouseenter = function (event) {&lt;br /&gt;
						for (var j = 0; j &amp;lt; rows.length; j++) {&lt;br /&gt;
							let preversion = this.textContent;&lt;br /&gt;
							let version = preversion.slice(0,5)&lt;br /&gt;
							let compareVersion = rows[j].textContent.slice(0,5)&lt;br /&gt;
							if (compareVersion === version) continue&lt;br /&gt;
							rows[j].className += &amp;quot; other&amp;quot;;&lt;br /&gt;
						}&lt;br /&gt;
					};&lt;br /&gt;
				&lt;br /&gt;
					rows[i].onmouseleave = function (event) {&lt;br /&gt;
						var hovers = document.getElementsByClassName('other');&lt;br /&gt;
						var len = hovers.length;&lt;br /&gt;
						for (var j = 0; j &amp;lt; len; j++) {&lt;br /&gt;
							hovers[0].className = hovers[0].className.replace(/\sother(\s|$)/, '');&lt;br /&gt;
						}&lt;br /&gt;
					};&lt;br /&gt;
				}&lt;br /&gt;
&lt;br /&gt;
                // this.ele.addEventListener(&amp;quot;click&amp;quot;, (e) =&amp;gt; {&lt;br /&gt;
                //     console.log(e.target)&lt;br /&gt;
                    &lt;br /&gt;
                // });&lt;br /&gt;
&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* How to Create Database Seed Data.&lt;br /&gt;
* How to structure code so controller code is in one file and HTML Heex is in another&lt;br /&gt;
* How to Use Generators in a Real World Project&lt;br /&gt;
* How to Work with Database Data via Basic Commands and Custom Change sets.&lt;br /&gt;
* How to Render Database Data to LiveView (via Context Commands).&lt;br /&gt;
* How to Create a Chat using PubSub.&lt;br /&gt;
* How to Create Event Handlers in LiveView&lt;br /&gt;
* How to Create a Dynamic Route from Scratch.&lt;br /&gt;
* How to Use Elixirs Template language&lt;br /&gt;
* How to Work with Modal&lt;br /&gt;
* How to Use CSS From Scratch (Without bundler)&lt;br /&gt;
* How to use JS hooks&lt;br /&gt;
* Dissect Table Component and Update it to Order List in Reverse.&lt;br /&gt;
&lt;br /&gt;
Selenium&lt;br /&gt;
https://www.builder.io/blog/debug-nodejs&lt;br /&gt;
&lt;br /&gt;
https://marketplace.visualstudio.com/items?itemName=ms-vscode.live-server#running-the-extension&lt;br /&gt;
&lt;br /&gt;
This was added recently (see microsoft/vscode#109276).&lt;br /&gt;
    1. Open the palette (Ctrl + Shift + P)&lt;br /&gt;
    2. Select &amp;quot;Simple Browser: Preview&amp;quot;&lt;br /&gt;
    3. Enter web address&lt;br /&gt;
&lt;br /&gt;
_______________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
const {By, Key, Builder} = require(&amp;quot;selenium-webdriver&amp;quot;);&lt;br /&gt;
const assert = require(&amp;quot;assert&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
require(&amp;quot;chromedriver&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
async function test_case(){&lt;br /&gt;
  let driver = await new Builder().forBrowser(&amp;quot;chrome&amp;quot;).build();&lt;br /&gt;
  await driver.get(&amp;quot;sie&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  await driver.findElement(By.name('password')).clear();&lt;br /&gt;
  await driver.findElement(By.name('identification')).clear();&lt;br /&gt;
  await driver.findElement(By.name('identification')).sendKeys(&amp;quot;bill&amp;quot;);&lt;br /&gt;
  await driver.findElement(By.name('password')).sendKeys(&amp;quot;password&amp;quot;, Key.RETURN);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 setTimeout(()=&amp;gt;{&lt;br /&gt;
   driver.findElement(By.className(&amp;quot;req_lan_license&amp;quot;)).click();&lt;br /&gt;
 },5000)&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageLive do &lt;br /&gt;
&lt;br /&gt;
  use AppWeb, :live_view  &lt;br /&gt;
  alias App.Testbeds &lt;br /&gt;
  def mount(_params, _session, socket)do   &lt;br /&gt;
     {:ok, assign(socket, testbeds: Testbeds.list_testbeds())}   &lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
    def button_event(&amp;quot;invoke_editing&amp;quot;) do&lt;br /&gt;
    %JS{}&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;active&amp;quot;, to: &amp;quot;#editing_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#editing_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#preview_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;active&amp;quot;, to: &amp;quot;#preview_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;active&amp;quot;, to: &amp;quot;#preview&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#preview&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#editing&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;active&amp;quot;, to: &amp;quot;#editing&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def button_event(&amp;quot;invoke_preview&amp;quot;) do&lt;br /&gt;
    %JS{}&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;active&amp;quot;, to: &amp;quot;#preview_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#preview_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#editing_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;active&amp;quot;, to: &amp;quot;#editing_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;active&amp;quot;, to: &amp;quot;#editing&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#editing&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#preview&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;active&amp;quot;, to: &amp;quot;#preview&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;send&amp;quot;, params, socket) do&lt;br /&gt;
    hide_modal(&amp;quot;notes-modal-0&amp;quot;)&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do  &lt;br /&gt;
     ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
		&amp;lt;.modal id={&amp;quot;notes-modal-#{testbed.id}&amp;quot;}&amp;gt;&lt;br /&gt;
		    &amp;lt;.button phx-click={button_event(&amp;quot;invoke_editing&amp;quot;)} id=&amp;quot;editing_button&amp;quot; class=&amp;quot;hidden&amp;quot;&amp;gt;&lt;br /&gt;
		      Preview&lt;br /&gt;
		    &amp;lt;/.button&amp;gt;&lt;br /&gt;
		    &amp;lt;.button phx-click={button_event(&amp;quot;invoke_preview&amp;quot;)} id=&amp;quot;preview_button&amp;quot;&amp;gt;&lt;br /&gt;
		      Edit Me&lt;br /&gt;
		    &amp;lt;/.button&amp;gt;&lt;br /&gt;
		    &amp;lt;div id=&amp;quot;editing&amp;quot;&amp;gt; PREVIEWING THE WORK&amp;lt;/div&amp;gt;&lt;br /&gt;
		    &amp;lt;form phx-submit = &amp;quot;send&amp;quot;   id=&amp;quot;preview&amp;quot; class=&amp;quot;hidden&amp;quot;&amp;gt;&lt;br /&gt;
		      &amp;lt;textarea value = {testbed.note}&amp;gt;&amp;lt;/textarea&amp;gt;&lt;br /&gt;
		      &amp;lt;.button type=&amp;quot;submit&amp;quot; phx-click={hide_modal(&amp;quot;notes-modal-#{testbed.id}&amp;quot;)}&amp;gt;SAVE WORK&amp;lt;/.button&amp;gt;&lt;br /&gt;
		    &amp;lt;/form&amp;gt;&lt;br /&gt;
		&amp;lt;/.modal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;%= if testbed.note do %&amp;gt;&lt;br /&gt;
      &amp;lt;div phx-click={show_modal(&amp;quot;notes-modal-#{testbed.id}&amp;quot;)}&amp;gt;READ ME  ...&amp;lt;%= testbed.note %&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
	   &lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
       &lt;br /&gt;
      &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
import {HfInference} from &amp;quot;@huggingface/inference&amp;quot;;&lt;br /&gt;
import dotenv from &amp;quot;dotenv&amp;quot;;&lt;br /&gt;
dotenv.config()&lt;br /&gt;
&lt;br /&gt;
const HF_ACCESS_TOKEN = process.env.HF_ACCESS_TOKEN&lt;br /&gt;
&lt;br /&gt;
const hf = new HfInference(HF_ACCESS_TOKEN);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*______Uncomment for this example______________________&lt;br /&gt;
&lt;br /&gt;
const model = &amp;quot;nlpconnect/vit-gpt2-image-captioning&amp;quot;;&lt;br /&gt;
const imageURL = &amp;quot;https://i.imgur.com/lTvb7Et.png&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
const response = await fetch(imageURL);&lt;br /&gt;
const imageBlob = await response.blob();&lt;br /&gt;
&lt;br /&gt;
const result  = await hf.imageToText({&lt;br /&gt;
	data: imageBlob,&lt;br /&gt;
	model: model,&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
_______________________________________________________*/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*________Another example ___________________*/&lt;br /&gt;
&lt;br /&gt;
const result = await hf.summarization({&lt;br /&gt;
	model: 'facebook/bart-large-cnn',&lt;br /&gt;
	inputs: &amp;quot;The role of a dumb man is to get smarter oogy bookie boo&amp;quot;,&lt;br /&gt;
	parameters:{&lt;br /&gt;
		max_length: 100&lt;br /&gt;
	}&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
console.log(result);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
________________________________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://fly.io/phoenix-files/sdeb-toggling-element/&lt;br /&gt;
https://www.youtube.com/watch?v=vBgZvQapqhs&lt;br /&gt;
&lt;br /&gt;
https://blog.testdouble.com/posts/2022-11-28-how-to-use-javascript-with-phoenix-liveview/&lt;br /&gt;
&lt;br /&gt;
https://hexdocs.pm/phoenix_live_view/0.19.3/Phoenix.Component.html&lt;br /&gt;
_______________________________________&lt;br /&gt;
https://www.smashingmagazine.com/2011/10/quick-look-math-animations-javascript/&lt;br /&gt;
* Depth first traversal&lt;br /&gt;
* Breadth first traversal&lt;br /&gt;
&lt;br /&gt;
https://dev.to/codesphere/10-algorithms-every-developer-should-learn-3lnm&lt;br /&gt;
&lt;br /&gt;
https://www.youtube.com/watch?v=fPz40W9mfCg&lt;br /&gt;
&lt;br /&gt;
__________________________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.GroupLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  alias App.TestBeds&lt;br /&gt;
  alias App.Groups&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    {:ok, assign(socket, testbeds: TestBeds.list_testbeds(), groups: Groups.list_groups())}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;select-group&amp;quot;, params, socket)  do  &lt;br /&gt;
         &lt;br /&gt;
       IO.inspect params&lt;br /&gt;
       {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div class=&amp;quot;grid grid-columns-2 grid-flow-col gap-4&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;column-1&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;%= testbed.name %&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;column-2&amp;quot;&amp;gt;    &lt;br /&gt;
            &amp;lt;form phx-change=&amp;quot;select-group&amp;quot;  &amp;gt;&lt;br /&gt;
               &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;testbed_id&amp;quot; value={testbed.id}/&amp;gt;&lt;br /&gt;
               &amp;lt;select id=&amp;quot;group-selection&amp;quot;  name=&amp;quot;group-id&amp;quot; &amp;gt;&lt;br /&gt;
                &amp;lt;%= for group &amp;lt;- @groups do %&amp;gt;&lt;br /&gt;
                  &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}  &amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
               &amp;lt;/select&amp;gt;&lt;br /&gt;
            &amp;lt;/form&amp;gt;&lt;br /&gt;
         &amp;lt;/div&amp;gt;&lt;br /&gt;
       &amp;lt;% end %&amp;gt;&lt;br /&gt;
   &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
____________________________&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.GroupLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  alias App.TestBeds&lt;br /&gt;
  alias App.Groups&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
&lt;br /&gt;
    {:ok, assign(socket, testbeds: TestBeds.list_testbeds(), groups: Groups.list_groups(), messages: [])}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;select-group&amp;quot;, params, socket)  do  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
      group = App.Groups.get_group!(params[&amp;quot;group-id&amp;quot;])&lt;br /&gt;
       # IO.inspect group&lt;br /&gt;
       testbed = App.TestBeds.get_test_bed!(params[&amp;quot;testbed_id&amp;quot;])&lt;br /&gt;
     &lt;br /&gt;
       App.TestBeds.update_test_bed(testbed, %{group_id: group.id})&lt;br /&gt;
         &lt;br /&gt;
    &lt;br /&gt;
       {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def updated_groups(testbed_id)  do  &lt;br /&gt;
       groups = App.Groups.list_groups&lt;br /&gt;
       tail = Enum.filter(groups, fn(item)-&amp;gt; item.id !== testbed_id end)&lt;br /&gt;
       head = Enum.filter(groups, fn(item)-&amp;gt; item.id == testbed_id end)&lt;br /&gt;
              |&amp;gt;Enum.at(0)&lt;br /&gt;
     [head | tail]&lt;br /&gt;
         &lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
 # def handle_event(&amp;quot;groups&amp;quot;, params, socket)do  &lt;br /&gt;
 #       selected_testbed = %{name: &amp;quot;my testbed name&amp;quot;, id: 3}&lt;br /&gt;
 #       groups = App.Groups.list_groups&lt;br /&gt;
 #       tail = Enum.filter(groups, fn(item)-&amp;gt; item.id !== selected_testbed.id end)&lt;br /&gt;
 #       head = Enum.filter(groups, fn(item)-&amp;gt; item.id == selected_testbed.id end)&lt;br /&gt;
 #              |&amp;gt;Enum.at(0)&lt;br /&gt;
         &lt;br /&gt;
 &lt;br /&gt;
 #       # result = Enum.filter([1, 2, 3], fn x -&amp;gt; x.id !== 1 end)&lt;br /&gt;
 #      IO.inspect [head | tail]&lt;br /&gt;
         &lt;br /&gt;
 #      #&lt;br /&gt;
 #      {:noreply, socket, assigns.message:}&lt;br /&gt;
 #  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    &lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
       &amp;lt;%!-- &amp;lt;div phx-click = &amp;quot;groups&amp;quot;&amp;gt;CLICK ME&amp;lt;/div&amp;gt; --%&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;grid grid-cols-4 gap-4 p-8 rounded shadow bg-white&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;h2&amp;gt; Name&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;%= testbed.name %&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;h2&amp;gt; Group&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;form phx-change=&amp;quot;select-group&amp;quot; name=&amp;quot;testbed_id&amp;quot;  &amp;gt;&lt;br /&gt;
               &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;testbed_id&amp;quot; value={testbed.id}/&amp;gt;&lt;br /&gt;
               &amp;lt;select id=&amp;quot;group-selection&amp;quot;  name=&amp;quot;group-id&amp;quot; class=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
                &amp;lt;%= for group &amp;lt;- updated_groups(testbed.id) do %&amp;gt;&lt;br /&gt;
                  &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}  &amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
                  &amp;lt;!-- Write code to reorder with testbed.group_id matching group_id --&amp;gt;&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
               &amp;lt;/select&amp;gt;&lt;br /&gt;
            &amp;lt;/form&amp;gt;&lt;br /&gt;
          &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
       &amp;lt;% end %&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_____________________________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
   use AppWeb, :live_view  &lt;br /&gt;
     alias App.Testbeds&lt;br /&gt;
  alias App.Groups&lt;br /&gt;
   def mount(_params, _session, socket)  do&lt;br /&gt;
	     {:ok, assign(socket, testbeds: Testbeds.list_testbeds(), groups: Groups.list_groups())}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
   def handle_event(&amp;quot;select-group&amp;quot;, params, socket)  do  &lt;br /&gt;
       group = App.Groups.get_group!(params[&amp;quot;group-id&amp;quot;])&lt;br /&gt;
       testbed = App.Testbeds.get_testbed!(params[&amp;quot;testbed_id&amp;quot;])&lt;br /&gt;
       result = App.Testbeds.update_testbed(testbed, %{group_id: group.id})&lt;br /&gt;
       IO.inspect result&lt;br /&gt;
      &lt;br /&gt;
       {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
    def updated_groups(testbed_id)  do  &lt;br /&gt;
       testbed = App.Testbeds.get_testbed!(testbed_id)&lt;br /&gt;
       groups = App.Groups.list_groups&lt;br /&gt;
       tail = Enum.filter(groups, fn(item)-&amp;gt; item.id !== testbed.group_id end)&lt;br /&gt;
       head = Enum.filter(groups, fn(item)-&amp;gt; item.id == testbed.group_id end)&lt;br /&gt;
              |&amp;gt;Enum.at(0)&lt;br /&gt;
 &lt;br /&gt;
       [head | tail]&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    &lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;grid grid-cols-4 gap-4 p-8 rounded shadow bg-white&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;h2&amp;gt; Name&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;%= testbed.name %&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;h2&amp;gt; Group&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;form phx-change=&amp;quot;select-group&amp;quot; name=&amp;quot;testbed_id&amp;quot;  &amp;gt;&lt;br /&gt;
               &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;testbed_id&amp;quot; value={testbed.id}/&amp;gt;&lt;br /&gt;
               &amp;lt;select id=&amp;quot;group-selection&amp;quot;  name=&amp;quot;group-id&amp;quot; class=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
                &amp;lt;%= for group &amp;lt;- updated_groups(testbed.id) do %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
                  &amp;lt;%!-- &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}&amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt; --%&amp;gt;&lt;br /&gt;
                  &amp;lt;!-- Write code to reorder with testbed.group_id matching group_id --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
                  &amp;lt;%= if group !== nil do %&amp;gt;&lt;br /&gt;
                      &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}&amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
       &lt;br /&gt;
                  &amp;lt;% end %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
               &amp;lt;/select&amp;gt;&lt;br /&gt;
            &amp;lt;/form&amp;gt;&lt;br /&gt;
          &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
       &amp;lt;% end %&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  has_many :testbeds, TestBed, on_delete: :restrict   # Has many&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://elixirforum.com/t/ecto-has-many-on-delete-protect/49550&lt;br /&gt;
&lt;br /&gt;
https://hexdocs.pm/ecto/Ecto.Changeset.html#unique_constraint/3&lt;br /&gt;
&lt;br /&gt;
____________________________________________________________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== How to Create a Mix Project and Use It in Another Mix Project ==&lt;br /&gt;
&lt;br /&gt;
To create and use a **Mix project** inside another **Mix project** in Elixir, follow the steps below:&lt;br /&gt;
&lt;br /&gt;
=== 1. Create a New Mix Project ===&lt;br /&gt;
&lt;br /&gt;
First, you need to create a new Mix project. Let's call this project `library_project`. Run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mix new library_project --module LibraryProject&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will create a new Elixir Mix project named `library_project`. The `--module` flag specifies the name of the module that will be created (in this case `LibraryProject`).&lt;br /&gt;
&lt;br /&gt;
The directory structure of `library_project` will look like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
library_project/&lt;br /&gt;
  |_ lib/&lt;br /&gt;
      |_ library_project.ex&lt;br /&gt;
  |_ mix.exs&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can then add some basic functionality inside the `library_project/lib/library_project.ex` file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule LibraryProject do&lt;br /&gt;
  def hello do&lt;br /&gt;
    IO.puts &amp;quot;Hello from LibraryProject!&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now, `library_project` is ready to be used by another Mix project.&lt;br /&gt;
&lt;br /&gt;
=== 2. Create a Second Mix Project ===&lt;br /&gt;
&lt;br /&gt;
Next, create the second Mix project where you want to use `library_project`. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mix new app_project --module AppProject&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will create another Elixir project called `app_project`.&lt;br /&gt;
&lt;br /&gt;
The directory structure for this project will look like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
app_project/&lt;br /&gt;
  |_ lib/&lt;br /&gt;
      |_ app_project.ex&lt;br /&gt;
  |_ mix.exs&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 3. Add `library_project` as a Dependency in `app_project` ===&lt;br /&gt;
&lt;br /&gt;
Now, you want to make `library_project` available in `app_project`. There are two main ways to do this:&lt;br /&gt;
&lt;br /&gt;
==== Option 1: Local Dependency (via `path`) ====&lt;br /&gt;
&lt;br /&gt;
If `library_project` is a local project (i.e., it's stored in a different directory), you can add it to the `mix.exs` of `app_project` as a local dependency by specifying the path to `library_project`.&lt;br /&gt;
&lt;br /&gt;
Edit the `mix.exs` of `app_project`:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule AppProject.MixProject do&lt;br /&gt;
  use Mix.Project&lt;br /&gt;
&lt;br /&gt;
  def project do&lt;br /&gt;
    [&lt;br /&gt;
      app: :app_project,&lt;br /&gt;
      version: &amp;quot;0.1.0&amp;quot;,&lt;br /&gt;
      elixir: &amp;quot;~&amp;gt; 1.14&amp;quot;,&lt;br /&gt;
      start_permanent: Mix.env() == :prod,&lt;br /&gt;
      deps: deps()&lt;br /&gt;
    ]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  defp deps do&lt;br /&gt;
    [&lt;br /&gt;
      {:library_project, path: &amp;quot;../library_project&amp;quot;}  # Add the local dependency&lt;br /&gt;
    ]&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here, `{:library_project, path: &amp;quot;../library_project&amp;quot;}` tells Mix to use the local `library_project` located in the `../library_project` directory (relative to `app_project`).&lt;br /&gt;
&lt;br /&gt;
After updating the `mix.exs`, run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd app_project&lt;br /&gt;
mix deps.get&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will fetch the dependency and compile `library_project`.&lt;br /&gt;
&lt;br /&gt;
==== Option 2: Publish and Fetch as a Hex Package ====&lt;br /&gt;
&lt;br /&gt;
If you want to use `library_project` as a package in another project (for example, by publishing it to **Hex.pm**, Elixir’s package manager), you need to publish it to Hex and then add it as a dependency.&lt;br /&gt;
&lt;br /&gt;
1. Publish `library_project` to Hex (if it's public or for your private use).&lt;br /&gt;
2. Add `library_project` to your `app_project`’s `mix.exs` dependencies:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defp deps do&lt;br /&gt;
  [&lt;br /&gt;
    {:library_project, &amp;quot;~&amp;gt; 0.1.0&amp;quot;}  # Specify the published version from Hex&lt;br /&gt;
  ]&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Run `mix deps.get` to fetch the package from Hex.&lt;br /&gt;
&lt;br /&gt;
=== 4. Use `library_project` in `app_project` ===&lt;br /&gt;
&lt;br /&gt;
Now, you can use the functionality from `library_project` inside your `app_project`. For example, in `app_project/lib/app_project.ex`, you can call the function from `library_project`:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule AppProject do&lt;br /&gt;
  def start do&lt;br /&gt;
    IO.puts &amp;quot;Starting app_project!&amp;quot;&lt;br /&gt;
    LibraryProject.hello()  # Call the function from the library_project&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 5. Run the App ===&lt;br /&gt;
&lt;br /&gt;
Finally, you can run your `app_project`:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd app_project&lt;br /&gt;
mix run -e &amp;quot;AppProject.start()&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will print:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Starting app_project!&lt;br /&gt;
Hello from LibraryProject!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Recap of the Process ==&lt;br /&gt;
1. **Create the `library_project`**: Use `mix new` to generate a library project.&lt;br /&gt;
2. **Create the `app_project`**: Create the second project where you will use the library.&lt;br /&gt;
3. **Add the `library_project` as a dependency**:&lt;br /&gt;
   - Use the `path` option to point to the local project or publish it to Hex for public access.&lt;br /&gt;
4. **Use the `library_project` in the `app_project`**: Call functions or use modules from the library inside the second project.&lt;br /&gt;
5. **Run the app**: Use `mix run` to execute the project.&lt;br /&gt;
&lt;br /&gt;
This way, you can reuse code from one Mix project in another by adding it as a dependency.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==z==&lt;br /&gt;
Overloaded functions are extremely common in Elixir applications. They are&lt;br /&gt;
regularly used for recursive functions and for changing behavior based on&lt;br /&gt;
configuration.&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>http://elixirblocks.com/index.php?title=Update_Phoenix_Generator&amp;diff=1868</id>
		<title>Update Phoenix Generator</title>
		<link rel="alternate" type="text/html" href="http://elixirblocks.com/index.php?title=Update_Phoenix_Generator&amp;diff=1868"/>
		<updated>2024-12-08T02:16:28Z</updated>

		<summary type="html">&lt;p&gt;Admin: Created page with &amp;quot;&amp;lt;pre&amp;gt;  mix archive.install hex phx_new  &amp;lt;/pre&amp;gt;&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
mix archive.install hex phx_new&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>http://elixirblocks.com/index.php?title=User:Admin&amp;diff=1867</id>
		<title>User:Admin</title>
		<link rel="alternate" type="text/html" href="http://elixirblocks.com/index.php?title=User:Admin&amp;diff=1867"/>
		<updated>2024-11-29T07:04:39Z</updated>

		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In that case, you really should switch it to prod mode. Instead of doing all that above with the &amp;quot;config/secret.exs&amp;quot; file, create the &amp;quot;.env&amp;quot; in the project root, then add DotenvParser.load_file(&amp;quot;.env&amp;quot;) to &amp;quot;config/runtime.exs&amp;quot; as the first line inside the if config_env() == :prod do. In the .env file, set the DATABASE_URL and SECRET_KEY_BASE. Then run it as MIX_ENV=prod mix phx.server.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def get_titles do&lt;br /&gt;
    urls = [&lt;br /&gt;
      &amp;quot;https://cointelegraph.com/rss&amp;quot;,&lt;br /&gt;
      &amp;quot;https://chaski.huffpost.com/us/auto/vertical/us-news&amp;quot;&lt;br /&gt;
      # Add more RSS feed URLs here&lt;br /&gt;
    ]&lt;br /&gt;
&lt;br /&gt;
    urls&lt;br /&gt;
    |&amp;gt; Enum.map(fn url -&amp;gt;&lt;br /&gt;
      with {:ok, feed} &amp;lt;- ElixirRss.fetch_and_parse(url) do&lt;br /&gt;
        Enum.map(feed.entries, &amp;amp; &amp;amp;1.title)&lt;br /&gt;
      else&lt;br /&gt;
        {:error, reason} -&amp;gt; {:error, reason}&lt;br /&gt;
      end&lt;br /&gt;
    end)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule App do&lt;br /&gt;
&lt;br /&gt;
  def get_titles() do&lt;br /&gt;
    data = [&lt;br /&gt;
      &amp;quot;https://cointelegraph.com/rss&amp;quot;,&lt;br /&gt;
      &amp;quot;https://chaski.huffpost.com/us/auto/vertical/us-news&amp;quot;&lt;br /&gt;
      # Add more RSS feed URLs here&lt;br /&gt;
    ]&lt;br /&gt;
&lt;br /&gt;
    data&lt;br /&gt;
    |&amp;gt; Enum.map(fn url -&amp;gt;&lt;br /&gt;
      case ElixirRss.fetch_and_parse(url) do&lt;br /&gt;
        {:ok, feed} -&amp;gt; feed.entries |&amp;gt; Enum.map(fn entry -&amp;gt; entry end)&lt;br /&gt;
        {:error, reason} -&amp;gt; {:error, reason}&lt;br /&gt;
      end&lt;br /&gt;
    end)&lt;br /&gt;
    |&amp;gt; Enum.map(fn entry_list -&amp;gt;&lt;br /&gt;
      entry_list&lt;br /&gt;
      |&amp;gt; Enum.map(fn entry -&amp;gt; entry.title end)&lt;br /&gt;
    end)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def hello do&lt;br /&gt;
    rss_feeds = [&lt;br /&gt;
      &amp;quot;https://cointelegraph.com/rss&amp;quot;,&lt;br /&gt;
      &amp;quot;https://chaski.huffpost.com/us/auto/vertical/us-news&amp;quot;&lt;br /&gt;
      # Add more RSS feed URLs here&lt;br /&gt;
    ]&lt;br /&gt;
&lt;br /&gt;
    rss_feeds&lt;br /&gt;
    |&amp;gt; Enum.map(fn url -&amp;gt;&lt;br /&gt;
      case ElixirRss.fetch_and_parse(url) do&lt;br /&gt;
        {:ok, feed} -&amp;gt; feed.entries |&amp;gt; Enum.map(fn entry -&amp;gt; entry end)&lt;br /&gt;
        {:error, reason} -&amp;gt; {:error, reason}&lt;br /&gt;
      end&lt;br /&gt;
    end)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    if connected?(socket) do&lt;br /&gt;
      Phoenix.PubSub.subscribe(App.PubSub, &amp;quot;message&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
    {:ok, assign(socket, message_item: &amp;quot;different&amp;quot;)}&lt;br /&gt;
  end&lt;br /&gt;
  def handle_info({:pubsub_transmission, text}, socket) do&lt;br /&gt;
    IO.inspect &amp;quot;pub sub working&amp;quot;&lt;br /&gt;
    {:noreply, assign(socket, message_item: text)}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def loop(data) do&lt;br /&gt;
     IO.inspect data&lt;br /&gt;
     if data &amp;gt; 0 do&lt;br /&gt;
      IO.inspect &amp;quot;notify&amp;quot;&lt;br /&gt;
      # run code to compare files, loop. If different run pubsub code below&lt;br /&gt;
      :timer.sleep(2000)&lt;br /&gt;
      loop(data-1)&lt;br /&gt;
&lt;br /&gt;
     end&lt;br /&gt;
     if data &amp;lt;= 0 do&lt;br /&gt;
&lt;br /&gt;
      Phoenix.PubSub.broadcast(App.PubSub, &amp;quot;message&amp;quot;, {:pubsub_transmission, &amp;quot;data&amp;quot;})&lt;br /&gt;
      &amp;quot;done&amp;quot;&lt;br /&gt;
     end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;change-text&amp;quot;, _params, socket) do&lt;br /&gt;
    spawn(fn -&amp;gt; loop(3) end)&lt;br /&gt;
    {:noreply, assign(socket, message_item: &amp;quot;START&amp;quot; )}&lt;br /&gt;
  end&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
&lt;br /&gt;
    # AppWeb.PageLive.loop(&amp;quot;xxx&amp;quot;)&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    SANDBOX&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;.button phx-click=&amp;quot;change-text&amp;quot; value={@message_item}&amp;gt;CLICK ME&amp;lt;/.button&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;%= @message_item %&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
elixir :   1.16.2&lt;br /&gt;
&lt;br /&gt;
Erl:   20&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# PostGres&lt;br /&gt;
Created Saturday 18 February 2023&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Launch [PostGres](#PostGres) from Terminal&lt;br /&gt;
------------------------------------------&lt;br /&gt;
sudo -u postgres psql&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Set User Permission&lt;br /&gt;
-------------------&lt;br /&gt;
&amp;lt;https://commandprompt.com/education/how-to-create-a-superuser-in-postgresql/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ALTER USER user_name WITH PASSWORD 'new_password';&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Run Post Gres Commands&lt;br /&gt;
----------------------&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
sudo -i -u postgres&lt;br /&gt;
psql&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Create and Delete Database&lt;br /&gt;
&lt;br /&gt;
CREATE DATABASE name;&lt;br /&gt;
DROP DATABASE name;&lt;br /&gt;
## View user list&lt;br /&gt;
&lt;br /&gt;
\du&lt;br /&gt;
&lt;br /&gt;
 View all databases&lt;br /&gt;
&lt;br /&gt;
postgres=# \l&lt;br /&gt;
&lt;br /&gt;
 Change databases&lt;br /&gt;
&lt;br /&gt;
postgres=# \c    name-of-database&lt;br /&gt;
&lt;br /&gt;
View Tables&lt;br /&gt;
&lt;br /&gt;
After you change databases and are selected on one of them do this:&lt;br /&gt;
&lt;br /&gt;
\dt&lt;br /&gt;
&lt;br /&gt;
SELECT * FROM mytablename;&lt;br /&gt;
&lt;br /&gt;
EMPTY TABLE&lt;br /&gt;
DELETE FROM name-of-table&lt;br /&gt;
&lt;br /&gt;
CREATE TABLE&lt;br /&gt;
&lt;br /&gt;
CREATE TABLE table_name(&lt;br /&gt;
   column1 datatype,&lt;br /&gt;
   column2 datatype,&lt;br /&gt;
   column3 datatype,&lt;br /&gt;
   .....&lt;br /&gt;
   columnN datatype,&lt;br /&gt;
   PRIMARY KEY( one or more columns )&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
INSERT&lt;br /&gt;
&lt;br /&gt;
INSERT INTO ITEMS(id, name) VALUES(1,'htvjbjbgni');     Strings are single quote&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Roadmap==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.ItemsLive do&lt;br /&gt;
    use AppWeb, :live_view  &lt;br /&gt;
    def mount(_params, _session, socket)  do&lt;br /&gt;
      {:ok, assign(socket, switches: [&amp;quot;grindy&amp;quot;,&amp;quot;sonic&amp;quot;,&amp;quot;ogre&amp;quot;])}  &lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    def handle_event(&amp;quot;run&amp;quot;,_params,socket) do  &lt;br /&gt;
        &lt;br /&gt;
        IO.inspect &amp;quot;DOWNLOAD VIA SSH&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        {:noreply, redirect(socket, to: &amp;quot;/download&amp;quot;)}&lt;br /&gt;
&lt;br /&gt;
    end&lt;br /&gt;
   &lt;br /&gt;
&lt;br /&gt;
    def render(assigns) do&lt;br /&gt;
        &lt;br /&gt;
        ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        &amp;lt;ul&amp;gt;&lt;br /&gt;
        &amp;lt;%= for switch &amp;lt;- @switches do %&amp;gt;&lt;br /&gt;
         &amp;lt;a phx-submit=&amp;quot;click&amp;quot; href=&amp;quot;/download&amp;quot;&amp;gt;  &amp;lt;li&amp;gt; &amp;lt;%= switch %&amp;gt;  &amp;lt;/li&amp;gt; &amp;lt;/a&amp;gt;&lt;br /&gt;
&lt;br /&gt;
        &amp;lt;%end%&amp;gt;&lt;br /&gt;
        &amp;lt;/ul&amp;gt;&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot; &lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Notes==&lt;br /&gt;
List of Switches and the option to select the one needed.&lt;br /&gt;
Button to download JSON file.&lt;br /&gt;
Drag and Drop Palette to upload JSON file.&lt;br /&gt;
&lt;br /&gt;
After JSON file is uploaded a button titled &amp;quot;Make Active&amp;quot; is available.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://medium.com/@fraiha26/pushing-events-to-livecomponents-from-js-hooks-w-phoenix-elixir-d5544d4c3dfa&lt;br /&gt;
&lt;br /&gt;
Changeset notes and forms&lt;br /&gt;
&lt;br /&gt;
NOTE: Use case statements for pattern matching&lt;br /&gt;
____________________________________________&lt;br /&gt;
&lt;br /&gt;
Create a basic &amp;lt;.form&amp;gt;&amp;lt;/form&amp;gt; without error handling&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&amp;lt;.form :let={f} for={@changeset}  action={~p&amp;quot;/items&amp;quot;} &amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;.input field={f[:title]} type=&amp;quot;text&amp;quot; label=&amp;quot;Title&amp;quot; /&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
  &amp;lt;.button&amp;gt;Save Item&amp;lt;/.button&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;/.form&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With error handling looks like this:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;.form :let={f} for={@changeset}  action={~p&amp;quot;/items&amp;quot;} &amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;.error :if={@changeset.action}&amp;gt;&lt;br /&gt;
    Oops, something went wrong! Please check the errors below.&lt;br /&gt;
  &amp;lt;/.error&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;.input field={f[:title]} type=&amp;quot;text&amp;quot; label=&amp;quot;Title&amp;quot; /&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
  &amp;lt;.button&amp;gt;Save Item&amp;lt;/.button&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;/.form&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Create the routes for render and post to endpoint.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The controller for the page render needs to pass in the changeset via ```Items.change_item(%Item{})```&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  def new(conn, _params) do&lt;br /&gt;
    changeset = Items.change_item(%Item{})&lt;br /&gt;
    render(conn, :new, changeset: changeset)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Post route without error handling&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  def create(conn, %{&amp;quot;item&amp;quot; =&amp;gt; item_params}) do&lt;br /&gt;
    case Items.create_item(item_params) do&lt;br /&gt;
      {:ok, item} -&amp;gt;&lt;br /&gt;
        conn&lt;br /&gt;
        |&amp;gt; put_flash(:info, &amp;quot;Item created successfully.&amp;quot;)&lt;br /&gt;
        |&amp;gt; redirect(to: ~p&amp;quot;/items/#{item}&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With error handling&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  def create(conn, %{&amp;quot;item&amp;quot; =&amp;gt; item_params}) do&lt;br /&gt;
    case Items.create_item(item_params) do&lt;br /&gt;
      {:ok, item} -&amp;gt;&lt;br /&gt;
        conn&lt;br /&gt;
        |&amp;gt; put_flash(:info, &amp;quot;Item created successfully.&amp;quot;)&lt;br /&gt;
        |&amp;gt; redirect(to: ~p&amp;quot;/items/#{item}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
      {:error, %Ecto.Changeset{} = changeset} -&amp;gt;&lt;br /&gt;
        render(conn, :new, changeset: changeset)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_____________________________________________&lt;br /&gt;
https://medium.com/@vincentlin/phoenix-very-simple-form-c4b121697fcb&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''home.html.heex'''&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&amp;lt;form action=&amp;quot;/submit&amp;quot; method=&amp;quot;post&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;label for=&amp;quot;name&amp;quot;&amp;gt;Name:&amp;lt;/label&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;input type=&amp;quot;text&amp;quot; id=&amp;quot;name&amp;quot; name=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;_csrf_token&amp;quot; value={@csrf_token} /&amp;gt;&lt;br /&gt;
  &amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Submit&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
page_controller.ex&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.PageController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  def home(conn, _params) do&lt;br /&gt;
    # The home page is often custom made,&lt;br /&gt;
&lt;br /&gt;
    csrf_token = Plug.CSRFProtection.get_csrf_token()&lt;br /&gt;
    render(conn, :home, csrf_token: csrf_token)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def submit(conn, _params) do&lt;br /&gt;
    # The home page is often custom made,&lt;br /&gt;
     IO.inspect(_params)&lt;br /&gt;
     IO.inspect &amp;quot;___________________________&amp;quot;&lt;br /&gt;
    csrf_token = Plug.CSRFProtection.get_csrf_token()&lt;br /&gt;
    render(conn, :home, csrf_token: csrf_token)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
router.ex&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  scope &amp;quot;/&amp;quot;, AppWeb do&lt;br /&gt;
    pipe_through :browser&lt;br /&gt;
    post &amp;quot;/submit&amp;quot;, PageController, :submit&lt;br /&gt;
    get &amp;quot;/&amp;quot;, PageController, :home&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ecto.Adapters.SQL.query(Repo, &amp;quot;select * from artists where id=1&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ecto cheatsheet:  https://hexdocs.pm/ecto/crud.html&lt;br /&gt;
__________________________________________________________________&lt;br /&gt;
Most programming languages give you the ability to set global state by creating globally scoped variables. Elixir does not do this. Instead, Elixir provides a tool called a &amp;quot;processes&amp;quot; to persist  state. Elixir applications are composed of these &amp;quot;processes&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
Processes by themselves are complicated to use, thus Elixir provides abstractions to make working with processes easier. One of these abstractions is called a GenServer.&lt;br /&gt;
&lt;br /&gt;
GenServers are not only used to store state, they are also used to invoke work independent of the main application process. &lt;br /&gt;
&lt;br /&gt;
==Creating a GenServer to Store State==&lt;br /&gt;
&lt;br /&gt;
To Create a GenServer, start by creating a basic Module that ''uses'' the GenServer module (image below)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule App do  &lt;br /&gt;
  use GenServer&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We now need to describe the actions we want to perform. Being that this is used to store state, we will use basic CRUD actions: Create, Read, Update, Delete. To begins, empty functions describing each action is created.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule App do&lt;br /&gt;
   def create do &lt;br /&gt;
&lt;br /&gt;
   end&lt;br /&gt;
   def read do &lt;br /&gt;
&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
   def update do  &lt;br /&gt;
&lt;br /&gt;
   end &lt;br /&gt;
&lt;br /&gt;
   def delete do &lt;br /&gt;
&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==What now?==&lt;br /&gt;
&lt;br /&gt;
To fill in the functions with the appropriate code we must first have a basic understanding of how GenServers are structured.&lt;br /&gt;
&lt;br /&gt;
GenServers are composed of the GenServer module invoking callbacks. The callbacks have built in names that you, as a developer have to use.&lt;br /&gt;
&lt;br /&gt;
These callbacks are named:&lt;br /&gt;
&lt;br /&gt;
* init&lt;br /&gt;
* handle_cast&lt;br /&gt;
* handle_call&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To demonstrate, here is an example :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{:ok, pid} = GenServer.start(ModuleNameOfGenServer, %{})&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above function named &amp;quot;start&amp;quot; calls the function named init in the Module below.&lt;br /&gt;
In GenServer syntax the name of the GenServer functions always invoke callbacks that are determined by the language. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule ModuleNameOfGenServer do&lt;br /&gt;
  # 1&lt;br /&gt;
  def init(state \\ %{}) do&lt;br /&gt;
    {:ok, state}&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is a list of the GenServer functions and their corresponding callbacks.&lt;br /&gt;
&lt;br /&gt;
* GenServer.start/1  --&amp;gt;       init/1&lt;br /&gt;
* GenServer.call/3   --&amp;gt;       def handle_call/3&lt;br /&gt;
* GenServer.cast/2   --&amp;gt;       handle_cast/2&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Start and Call ==&lt;br /&gt;
&lt;br /&gt;
Call and Cast can be used to perform the same operations. The &lt;br /&gt;
&lt;br /&gt;
__________________________________________________________&lt;br /&gt;
Genserver timed events&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule Go do&lt;br /&gt;
  use GenServer&lt;br /&gt;
&lt;br /&gt;
  def go() do&lt;br /&gt;
    GenServer.start_link(__MODULE__, [])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def init(list) do&lt;br /&gt;
    :timer.apply_interval(1000, __MODULE__, :add, [self(), &amp;quot;weeeee&amp;quot;])&lt;br /&gt;
    {:ok, list}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def view(pid) do&lt;br /&gt;
    GenServer.call(pid, :view)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_call(:view, _from, list) do&lt;br /&gt;
    {:reply, list, list}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def add(pid, new_item) do&lt;br /&gt;
    GenServer.call(pid, {:item, new_item})&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_call({:item, new_item}, _from, state) do&lt;br /&gt;
    result = [new_item] ++ state&lt;br /&gt;
    {:reply, result, result}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule ShoppingList do&lt;br /&gt;
  use GenServer&lt;br /&gt;
&lt;br /&gt;
  def start_link() do&lt;br /&gt;
    GenServer.start_link(ShoppingList, [])&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def init(list) do&lt;br /&gt;
    {:ok, list}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def view(pid) do&lt;br /&gt;
    GenServer.call(pid, :view)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_call(:view, _from, list) do&lt;br /&gt;
    {:reply, list, list}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def add(pid, new_item) do&lt;br /&gt;
    GenServer.call(pid, {:item, new_item})&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_call({:item, new_item}, _from, state) do&lt;br /&gt;
    result = [new_item] ++ state&lt;br /&gt;
    {:reply, result, result}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://blog.appsignal.com/2018/06/12/elixir-alchemy-deconstructing-genservers.html&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule KeyValue do&lt;br /&gt;
  # 1&lt;br /&gt;
  def init(state \\ %{}) do&lt;br /&gt;
    {:ok, state}&lt;br /&gt;
  end&lt;br /&gt;
 &lt;br /&gt;
  # 2&lt;br /&gt;
  def handle_cast({:put, key, value}, state) do&lt;br /&gt;
    {:noreply, Map.put(state, key, value)}&lt;br /&gt;
  end&lt;br /&gt;
 &lt;br /&gt;
  # 3&lt;br /&gt;
  def handle_call({:get, key}, _from, state) do&lt;br /&gt;
    {:reply, Map.fetch!(state, key), state}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
# {:ok, pid} = GenServer.start(KeyValue, %{})&lt;br /&gt;
# GenServer.cast(pid, {:put, :foo, &amp;quot;bar&amp;quot;})&lt;br /&gt;
# GenServer.call(pid, {:get, :foo})&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Send messages via these functions wrapped in module functions .You can look at these are functions used to fire &amp;quot;GenServer Events&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
* start_link&lt;br /&gt;
* GenServer.call&lt;br /&gt;
* GenServer.cast&lt;br /&gt;
&lt;br /&gt;
The corresponding server functions that reply are:&lt;br /&gt;
&lt;br /&gt;
* init&lt;br /&gt;
* handle__call&lt;br /&gt;
* handle_cast&lt;br /&gt;
* &lt;br /&gt;
&lt;br /&gt;
These can be looked at as &amp;quot;listeners&amp;quot; - in JavaScript parlance. &lt;br /&gt;
__________________________________________&lt;br /&gt;
&lt;br /&gt;
If you have experience with programming languages other than Elixir the idea of GenServers may be very foreign and require a strong context shift to learn. This document is intended to simplify the concept.&lt;br /&gt;
&lt;br /&gt;
* What: GenServers are simply a way to hold state and/or invoke actions based on incoming events. &lt;br /&gt;
* when &lt;br /&gt;
* where&lt;br /&gt;
* why&lt;br /&gt;
* how&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
___________________________________________&lt;br /&gt;
GenServer timer example&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule Timer do&lt;br /&gt;
  use GenServer&lt;br /&gt;
&lt;br /&gt;
  def init(_) do&lt;br /&gt;
    :timer.send_interval(1000, :xyz)&lt;br /&gt;
    {:ok, 0}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_info(:xyz, state) do&lt;br /&gt;
    IO.inspect(state)&lt;br /&gt;
    {:noreply, state + 1}&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
[&lt;br /&gt;
   {&lt;br /&gt;
     data:{&lt;br /&gt;
        creationTime,&lt;br /&gt;
        publishDate,&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
     featured:{&lt;br /&gt;
        setAmount,&lt;br /&gt;
        items:[]&lt;br /&gt;
     },&lt;br /&gt;
&lt;br /&gt;
     children:{&lt;br /&gt;
        setAmount,&lt;br /&gt;
        items:[]&lt;br /&gt;
     },&lt;br /&gt;
     links:{&lt;br /&gt;
        setAmount,&lt;br /&gt;
        items:[]&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
jason.encode / jason.decode&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  def run(num) do&lt;br /&gt;
&lt;br /&gt;
    Enum.each(0..99999, fn(_x) -&amp;gt;&lt;br /&gt;
      task = Task.async(fn -&amp;gt; num + _x end)&lt;br /&gt;
    IO.inspect Task.await(task)&lt;br /&gt;
  end)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enum.map(feed.entries, fn x -&amp;gt; %{url: x.url, title: x.title} end)&lt;br /&gt;
&lt;br /&gt;
App is split:&lt;br /&gt;
&lt;br /&gt;
App that captures RSS in UI and lets admin select stories. THere are settings to determine the number of FEATURED,CHILD and LINK stories.&lt;br /&gt;
News categories are horizontal and scrollable.&lt;br /&gt;
This exports a json doc with all RSS data for each story.&lt;br /&gt;
The &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
App that reads the json data. This app creates tables and is the front end.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://stephenbussey.com/tags/elixir.html&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule AppWeb.GroupLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  alias App.TestBeds&lt;br /&gt;
  alias App.Groups&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    {:ok, assign(socket, testbeds: TestBeds.list_testbeds(), groups: Groups.list_groups())}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;select-group&amp;quot;, params, socket)  do  &lt;br /&gt;
     group = App.Groups.get_group!(params[&amp;quot;group-id&amp;quot;])&lt;br /&gt;
     testbed = App.TestBeds.get_test_bed!(params[&amp;quot;testbed_id&amp;quot;])&lt;br /&gt;
     App.TestBeds.update_test_bed(testbed, %{group_id: group.id})&lt;br /&gt;
     {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def updated_groups(testbed_id)  do  &lt;br /&gt;
     testbed = App.TestBeds.get_test_bed!(testbed_id)&lt;br /&gt;
     groups = App.Groups.list_groups&lt;br /&gt;
     tail = Enum.filter(groups, fn(item)-&amp;gt; item.id !== testbed.group_id end)&lt;br /&gt;
     head = Enum.filter(groups, fn(item)-&amp;gt; item.id == testbed.group_id end)&lt;br /&gt;
            |&amp;gt;Enum.at(0)&lt;br /&gt;
    [head | tail]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        &amp;lt;%= for testbed &amp;lt;- Enum.sort_by(@testbeds , &amp;amp;(&amp;quot;#{&amp;amp;1.name}&amp;quot;), :asc)do %&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;grid grid-cols-4 gap-4 p-8 rounded shadow bg-white&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;h2&amp;gt; Name&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;%= testbed.name %&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;h2&amp;gt; Group&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div&amp;gt;&lt;br /&gt;
            &amp;lt;form phx-change=&amp;quot;select-group&amp;quot; name=&amp;quot;testbed_id&amp;quot;  &amp;gt;&lt;br /&gt;
               &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;testbed_id&amp;quot; value={testbed.id}/&amp;gt;&lt;br /&gt;
               &amp;lt;select id=&amp;quot;group-selection&amp;quot;  name=&amp;quot;group-id&amp;quot; class=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;%= for group &amp;lt;- updated_groups(testbed.id) do %&amp;gt;&lt;br /&gt;
                  &amp;lt;%= if group !== nil do %&amp;gt;&lt;br /&gt;
                      &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}&amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
                      &amp;lt;%else%&amp;gt;&lt;br /&gt;
                      &amp;lt;option value= {&amp;quot;Unassigned&amp;quot;}&amp;gt;NONE&amp;lt;/option&amp;gt;&lt;br /&gt;
                  &amp;lt;% end %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
               &amp;lt;/select&amp;gt;&lt;br /&gt;
            &amp;lt;/form&amp;gt;&lt;br /&gt;
          &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
       &amp;lt;% end %&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Developer Notes ==&lt;br /&gt;
===Groups Feature ===&lt;br /&gt;
To complete this feature do these things.&lt;br /&gt;
* Run through the steps in [http://elixirblocks.com/index.php?title=Create_Foreign_Key_Relationship_Between_Ecto_Tables  | this document] to create Group table.&lt;br /&gt;
* Groups have these fields  '''name: string''', '''description: string''' and '''color: string'''  &lt;br /&gt;
* Add unique constraint in migration file: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def change do&lt;br /&gt;
     create unique_index(:groups, [:name])&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Port over Group LiveView code (temporarily placed at discussion page).&lt;br /&gt;
* On completion '''possibly''', create a Group named '''No Group''' and set all Testbeds to it.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
________&lt;br /&gt;
https://blog.appsignal.com/2022/10/11/phoenix-liveview-018-new-special-html-attributes.html&lt;br /&gt;
https://blixtdev.com/whats-new-phoenix-1-7/&lt;br /&gt;
https://github.com/devato/inertia_phoenix&lt;br /&gt;
https://phoenixonrails.com/blog/you-can-stop-using-form-for-in-phoenix&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://samuelmullen.com/articles/phoenix_templates_rendering_and_layouts&lt;br /&gt;
&lt;br /&gt;
WorkFlow of Todo App in Both LiveView and DeadView.&lt;br /&gt;
&lt;br /&gt;
Note:&lt;br /&gt;
&lt;br /&gt;
Create foreign key data.&lt;br /&gt;
Create live view. List all testbeds and form to assign each a group by group-name.&lt;br /&gt;
&lt;br /&gt;
Repeat in dead view&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Mental model and data flows&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
home.html.heex&lt;br /&gt;
&amp;lt;a href=&amp;quot;/data&amp;quot; name=&amp;quot;we are the world&amp;quot; &amp;gt;  click me&amp;lt;/a&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;%= @message %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
page controller&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  def home(conn, _params) do&lt;br /&gt;
    IO.inspect _params&lt;br /&gt;
    render(conn, :home, message: &amp;quot;Hello&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
get &amp;quot;/:yay&amp;quot;, PageController, :index&lt;br /&gt;
&lt;br /&gt;
get &amp;quot;/&amp;quot;, PageController, :index&lt;br /&gt;
&lt;br /&gt;
* Explain control flow of &amp;quot;Dead Views&amp;quot; and the Generator HTML Control flow.&lt;br /&gt;
* Proper Way to use Modal&lt;br /&gt;
* How to give Focus to Fields in Modal (or other forms fields)&lt;br /&gt;
* &lt;br /&gt;
* &lt;br /&gt;
* How to Create Database Seed Data.&lt;br /&gt;
* How to structure code so controller code is in one file and HTML Heex is in another&lt;br /&gt;
* How to Use Generators in a Real World Project&lt;br /&gt;
* How to Work with Database Data via Basic Commands and Custom Change sets.&lt;br /&gt;
* How to Render Database Data to LiveView (via Context Commands).&lt;br /&gt;
* How to Create a Chat using PubSub.&lt;br /&gt;
* How to Create Event Handlers in LiveView&lt;br /&gt;
* How to Create a Dynamic Route from Scratch.&lt;br /&gt;
* How to Use Elixirs Template language&lt;br /&gt;
* How to Work with Modal&lt;br /&gt;
* How to Use CSS From Scratch (Without bundler)&lt;br /&gt;
* How to use JS hooks&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
______________________&lt;br /&gt;
https://studioindie.co/blog/heex-guide/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
get &amp;quot;/&amp;quot;, PageController, :some-atom    #This is the route. some-atom is the controller name&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageController do&lt;br /&gt;
  use AppWeb, :controller&lt;br /&gt;
&lt;br /&gt;
  def some-atom(conn, _params) do                 # controller name&lt;br /&gt;
    # The home page is often custom made,&lt;br /&gt;
    # so skip the default app layout.&lt;br /&gt;
    render(conn, :some-atom, layout: false)      # :some-atom is template name&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Controllers page_html.ex contains &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageHTML do&lt;br /&gt;
  use AppWeb, :html&lt;br /&gt;
&lt;br /&gt;
  embed_templates &amp;quot;page_html/*&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''page_html''' is the name of the folder in '''Controllers/page_html'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Controllers/page_html/some-atom.html.heex  (this is the template) &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__________________________________________&lt;br /&gt;
Set all association with preload:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  def list_groups do&lt;br /&gt;
    Repo.all(Group)&lt;br /&gt;
     |&amp;gt; Repo.preload([:testbeds])&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Insert Child into Parent ===&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
App.get_group!(2) # arg is id&lt;br /&gt;
|&amp;gt; Ecto.build_assoc(:testbeds)&lt;br /&gt;
|&amp;gt; Repo.insert()&lt;br /&gt;
&lt;br /&gt;
Or&lt;br /&gt;
&lt;br /&gt;
group = App.get_group!(2) # arg is id&lt;br /&gt;
&lt;br /&gt;
testbeds = Ecto.build_assoc(group, :testbeds)&lt;br /&gt;
&lt;br /&gt;
App.Group.create_group(testbeds)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
group = App.Groups.get_group!(1)&lt;br /&gt;
thing = Ecto.build_assoc(group, :testbeds, name: &amp;quot;DUMB&amp;quot;)&lt;br /&gt;
alias App.{Repo}&lt;br /&gt;
Repo.insert(thing)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
avatar = %Avatar{nick_name: &amp;quot;Elixir&amp;quot;, pic_url: &amp;quot;http://elixir-lang.org/images/logo.png&amp;quot;}&lt;br /&gt;
user = %User{name: &amp;quot;John Doe&amp;quot;, email: &amp;quot;john.doe@example.com&amp;quot;, avatar: avatar}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://www.reddit.com/r/elixir/comments/oh318k/is_there_a_way_to_avoid_ectoassociationnotloaded/h4mmcfi/?utm_source=share&amp;amp;utm_medium=web3x&amp;amp;utm_name=web3xcss&amp;amp;utm_term=1&amp;amp;utm_content=share_button&lt;br /&gt;
&lt;br /&gt;
# Create Group Table&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
mix phx.gen.html Groups Group groups name:string  &lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Set the resources / &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
mix ecto.migrate&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For testbeds create a migration file and add this field:   group_id:references:groups&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
def change do&lt;br /&gt;
    alter table(:testbeds) do    # customize to your code&lt;br /&gt;
      add :group_id, references(:groups)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Update Groups Schema (Don't forget alias / has_many)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule App.Groups.Group do&lt;br /&gt;
	use Ecto.Schema&lt;br /&gt;
	import Ecto.Changeset&lt;br /&gt;
	alias App.Testbeds.Testbed   # Alias!&lt;br /&gt;
&lt;br /&gt;
	schema &amp;quot;posts&amp;quot; do&lt;br /&gt;
		field :body, :string&lt;br /&gt;
		field :title, :string&lt;br /&gt;
		has_many :testbeds, Testbed    # Has many&lt;br /&gt;
&lt;br /&gt;
		timestamps()&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	@doc false&lt;br /&gt;
	def changeset(post, attrs) do&lt;br /&gt;
		post&lt;br /&gt;
		|&amp;gt; cast(attrs, [:title, :body])&lt;br /&gt;
		|&amp;gt; validate_required([:title, :body])&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
TESTBEDS Schema&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule App.Testbeds.Testbed do&lt;br /&gt;
  use Ecto.Schema&lt;br /&gt;
  import Ecto.Changeset&lt;br /&gt;
  alias App.Groups.Group      # Alias&lt;br /&gt;
  schema &amp;quot;testbeds&amp;quot; do&lt;br /&gt;
    field :name, :string&lt;br /&gt;
    belongs_to :group, Group    # Belongs to&lt;br /&gt;
    timestamps()&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  @doc false&lt;br /&gt;
  def changeset(testbed, attrs) do&lt;br /&gt;
    testbed&lt;br /&gt;
    |&amp;gt; cast(attrs, [:name])&lt;br /&gt;
    |&amp;gt; validate_required([:name])&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
_____________________________________&lt;br /&gt;
Side notes.&lt;br /&gt;
&lt;br /&gt;
defmodule App.Repo.Migrations.CreateTestbeds do&lt;br /&gt;
  use Ecto.Migration&lt;br /&gt;
&lt;br /&gt;
  def change do&lt;br /&gt;
    create table(:testbeds) do&lt;br /&gt;
      add :name, :string&lt;br /&gt;
      add :group_id, references(:groups, on_delete: :nothing)&lt;br /&gt;
&lt;br /&gt;
      timestamps()&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    create index(:testbeds, [:group_id])&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
________________________________&lt;br /&gt;
&lt;br /&gt;
mix phx.gen.context Comments Comment comments name:string content:text post_id:references:posts&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
mix phx.gen.html Testbeds Testbed testbeds name:string  group_id:references:groups&lt;br /&gt;
&lt;br /&gt;
https://graffino.com/web-development/first-steps-in-elixir-and-phoenix-create-a-blog-prototype&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://blog.logrocket.com/getting-started-ecto-phoenix/&lt;br /&gt;
&lt;br /&gt;
https://serokell.io/blog/ecto-guide-for-beginners&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
mix phx.gen.html Testbeds Testbed testbeds name:string&lt;br /&gt;
&lt;br /&gt;
mix phx.gen.html Groups Group groups name:string&lt;br /&gt;
&lt;br /&gt;
Create migration for &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
mix ecto.gen.migration add_testbed_group_reference&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Migration:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  def change do&lt;br /&gt;
    alter table(:testbeds) do    # customize to your code&lt;br /&gt;
      add :group_id, references(:groups)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Manually Change:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule App.Group do&lt;br /&gt;
  use Ecto.Schema&lt;br /&gt;
&lt;br /&gt;
  schema &amp;quot;groups&amp;quot; do&lt;br /&gt;
    field :title, :string&lt;br /&gt;
    field :tagline, :string&lt;br /&gt;
    has_many :testbeds, App.Testbed&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
testbeds&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule App.Repo.Migrations.AddTextbedGroups do&lt;br /&gt;
  use Ecto.Migration&lt;br /&gt;
&lt;br /&gt;
  def change do&lt;br /&gt;
    create table(:testbeds) do&lt;br /&gt;
      add :name, :string&lt;br /&gt;
      add :group_id, references(:groups)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
# lib/app/testbeds.ex&lt;br /&gt;
&lt;br /&gt;
defmodule App.Testbed do&lt;br /&gt;
  use Ecto.Schema&lt;br /&gt;
&lt;br /&gt;
  schema &amp;quot;testbedss&amp;quot; do&lt;br /&gt;
    field :name, :string&lt;br /&gt;
    belongs_to :group, App.Group&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_____________________&lt;br /&gt;
&lt;br /&gt;
%App.TestBeds.TestBed{&lt;br /&gt;
  __meta__: #Ecto.Schema.Metadata&amp;lt;:loaded, &amp;quot;testbeds&amp;quot;&amp;gt;,&lt;br /&gt;
  id: 1,&lt;br /&gt;
  developer: &amp;quot;None&amp;quot;,&lt;br /&gt;
  name: &amp;quot;sdfsd&amp;quot;,&lt;br /&gt;
  owner: &amp;quot;sdfsddf&amp;quot;,&lt;br /&gt;
  note: &amp;quot;sdsfsddf&amp;quot;,&lt;br /&gt;
  status: &amp;quot;Available&amp;quot;,&lt;br /&gt;
  url: &amp;quot;sdf&amp;quot;,&lt;br /&gt;
  version: &amp;quot;ddf&amp;quot;,&lt;br /&gt;
  manager: &amp;quot;sf&amp;quot;,&lt;br /&gt;
  inserted_at: ~N[2023-08-21 13:45:39],&lt;br /&gt;
  updated_at: ~N[2023-08-21 13:45:44]&lt;br /&gt;
}&lt;br /&gt;
________________________________________________________________---&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.SendLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  &lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    {:ok, socket}&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  def handle_event(&amp;quot;send&amp;quot;, %{&amp;quot;text&amp;quot; =&amp;gt; text}, socket) do&lt;br /&gt;
&lt;br /&gt;
    AppWeb.Endpoint.broadcast(topic, &amp;quot;message&amp;quot;, text)&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  defp topic do&lt;br /&gt;
    &amp;quot;chat&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def render(assigns)do   &lt;br /&gt;
   ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
  &amp;lt;h1&amp;gt;Send Message&amp;lt;/h1&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;form phx-submit=&amp;quot;send&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;text&amp;quot; /&amp;gt;&lt;br /&gt;
    &amp;lt;button type=&amp;quot;submit&amp;quot;&amp;gt;Send&amp;lt;/button&amp;gt;&lt;br /&gt;
  &amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
______________________________________________________________&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.ReceiveLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  &lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    if connected?(socket) do&lt;br /&gt;
      AppWeb.Endpoint.subscribe(topic)&lt;br /&gt;
    end&lt;br /&gt;
    {:ok, assign(socket, messages: &amp;quot;&amp;quot;)}&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def handle_info(%{event: &amp;quot;message&amp;quot;, payload: message}, socket) do&lt;br /&gt;
    IO.inspect message&lt;br /&gt;
    {:noreply, assign(socket, messages: message)}&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  defp topic do&lt;br /&gt;
    &amp;quot;chat&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns)do   &lt;br /&gt;
   ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
  &amp;lt;h1&amp;gt;ChatLive&amp;lt;/h1&amp;gt;&lt;br /&gt;
  &amp;lt;%= @messages %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
______________________________________________________________&lt;br /&gt;
When you hover over a list of items this hook finds items with the same name and sets the opacity of all others to 0. You see all the items similar to the one you are hovering over.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
TestbedVersionHover: {&lt;br /&gt;
			// https://jsfiddle.net/IrvinDominin/7K2Z3/&lt;br /&gt;
            mounted() {&lt;br /&gt;
&lt;br /&gt;
                let rows = document.getElementsByClassName(&amp;quot;testbed-version&amp;quot;)&lt;br /&gt;
                // this.ele = element&lt;br /&gt;
				// rows = this.ele;&lt;br /&gt;
                &lt;br /&gt;
				for (var i = 0; i &amp;lt; rows.length; i++) {&lt;br /&gt;
					rows[i].onmouseenter = function (event) {&lt;br /&gt;
						for (var j = 0; j &amp;lt; rows.length; j++) {&lt;br /&gt;
							let preversion = this.textContent;&lt;br /&gt;
							let version = preversion.slice(0,5)&lt;br /&gt;
							let compareVersion = rows[j].textContent.slice(0,5)&lt;br /&gt;
							if (compareVersion === version) continue&lt;br /&gt;
							rows[j].className += &amp;quot; other&amp;quot;;&lt;br /&gt;
						}&lt;br /&gt;
					};&lt;br /&gt;
				&lt;br /&gt;
					rows[i].onmouseleave = function (event) {&lt;br /&gt;
						var hovers = document.getElementsByClassName('other');&lt;br /&gt;
						var len = hovers.length;&lt;br /&gt;
						for (var j = 0; j &amp;lt; len; j++) {&lt;br /&gt;
							hovers[0].className = hovers[0].className.replace(/\sother(\s|$)/, '');&lt;br /&gt;
						}&lt;br /&gt;
					};&lt;br /&gt;
				}&lt;br /&gt;
&lt;br /&gt;
                // this.ele.addEventListener(&amp;quot;click&amp;quot;, (e) =&amp;gt; {&lt;br /&gt;
                //     console.log(e.target)&lt;br /&gt;
                    &lt;br /&gt;
                // });&lt;br /&gt;
&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* How to Create Database Seed Data.&lt;br /&gt;
* How to structure code so controller code is in one file and HTML Heex is in another&lt;br /&gt;
* How to Use Generators in a Real World Project&lt;br /&gt;
* How to Work with Database Data via Basic Commands and Custom Change sets.&lt;br /&gt;
* How to Render Database Data to LiveView (via Context Commands).&lt;br /&gt;
* How to Create a Chat using PubSub.&lt;br /&gt;
* How to Create Event Handlers in LiveView&lt;br /&gt;
* How to Create a Dynamic Route from Scratch.&lt;br /&gt;
* How to Use Elixirs Template language&lt;br /&gt;
* How to Work with Modal&lt;br /&gt;
* How to Use CSS From Scratch (Without bundler)&lt;br /&gt;
* How to use JS hooks&lt;br /&gt;
* Dissect Table Component and Update it to Order List in Reverse.&lt;br /&gt;
&lt;br /&gt;
Selenium&lt;br /&gt;
https://www.builder.io/blog/debug-nodejs&lt;br /&gt;
&lt;br /&gt;
https://marketplace.visualstudio.com/items?itemName=ms-vscode.live-server#running-the-extension&lt;br /&gt;
&lt;br /&gt;
This was added recently (see microsoft/vscode#109276).&lt;br /&gt;
    1. Open the palette (Ctrl + Shift + P)&lt;br /&gt;
    2. Select &amp;quot;Simple Browser: Preview&amp;quot;&lt;br /&gt;
    3. Enter web address&lt;br /&gt;
&lt;br /&gt;
_______________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
const {By, Key, Builder} = require(&amp;quot;selenium-webdriver&amp;quot;);&lt;br /&gt;
const assert = require(&amp;quot;assert&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
require(&amp;quot;chromedriver&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
async function test_case(){&lt;br /&gt;
  let driver = await new Builder().forBrowser(&amp;quot;chrome&amp;quot;).build();&lt;br /&gt;
  await driver.get(&amp;quot;sie&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  await driver.findElement(By.name('password')).clear();&lt;br /&gt;
  await driver.findElement(By.name('identification')).clear();&lt;br /&gt;
  await driver.findElement(By.name('identification')).sendKeys(&amp;quot;bill&amp;quot;);&lt;br /&gt;
  await driver.findElement(By.name('password')).sendKeys(&amp;quot;password&amp;quot;, Key.RETURN);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 setTimeout(()=&amp;gt;{&lt;br /&gt;
   driver.findElement(By.className(&amp;quot;req_lan_license&amp;quot;)).click();&lt;br /&gt;
 },5000)&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageLive do &lt;br /&gt;
&lt;br /&gt;
  use AppWeb, :live_view  &lt;br /&gt;
  alias App.Testbeds &lt;br /&gt;
  def mount(_params, _session, socket)do   &lt;br /&gt;
     {:ok, assign(socket, testbeds: Testbeds.list_testbeds())}   &lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
    def button_event(&amp;quot;invoke_editing&amp;quot;) do&lt;br /&gt;
    %JS{}&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;active&amp;quot;, to: &amp;quot;#editing_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#editing_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#preview_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;active&amp;quot;, to: &amp;quot;#preview_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;active&amp;quot;, to: &amp;quot;#preview&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#preview&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#editing&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;active&amp;quot;, to: &amp;quot;#editing&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def button_event(&amp;quot;invoke_preview&amp;quot;) do&lt;br /&gt;
    %JS{}&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;active&amp;quot;, to: &amp;quot;#preview_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#preview_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#editing_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;active&amp;quot;, to: &amp;quot;#editing_button&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;active&amp;quot;, to: &amp;quot;#editing&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#editing&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.remove_class(&amp;quot;hidden&amp;quot;, to: &amp;quot;#preview&amp;quot;)&lt;br /&gt;
    |&amp;gt; JS.add_class(&amp;quot;active&amp;quot;, to: &amp;quot;#preview&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;send&amp;quot;, params, socket) do&lt;br /&gt;
    hide_modal(&amp;quot;notes-modal-0&amp;quot;)&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do  &lt;br /&gt;
     ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
		&amp;lt;.modal id={&amp;quot;notes-modal-#{testbed.id}&amp;quot;}&amp;gt;&lt;br /&gt;
		    &amp;lt;.button phx-click={button_event(&amp;quot;invoke_editing&amp;quot;)} id=&amp;quot;editing_button&amp;quot; class=&amp;quot;hidden&amp;quot;&amp;gt;&lt;br /&gt;
		      Preview&lt;br /&gt;
		    &amp;lt;/.button&amp;gt;&lt;br /&gt;
		    &amp;lt;.button phx-click={button_event(&amp;quot;invoke_preview&amp;quot;)} id=&amp;quot;preview_button&amp;quot;&amp;gt;&lt;br /&gt;
		      Edit Me&lt;br /&gt;
		    &amp;lt;/.button&amp;gt;&lt;br /&gt;
		    &amp;lt;div id=&amp;quot;editing&amp;quot;&amp;gt; PREVIEWING THE WORK&amp;lt;/div&amp;gt;&lt;br /&gt;
		    &amp;lt;form phx-submit = &amp;quot;send&amp;quot;   id=&amp;quot;preview&amp;quot; class=&amp;quot;hidden&amp;quot;&amp;gt;&lt;br /&gt;
		      &amp;lt;textarea value = {testbed.note}&amp;gt;&amp;lt;/textarea&amp;gt;&lt;br /&gt;
		      &amp;lt;.button type=&amp;quot;submit&amp;quot; phx-click={hide_modal(&amp;quot;notes-modal-#{testbed.id}&amp;quot;)}&amp;gt;SAVE WORK&amp;lt;/.button&amp;gt;&lt;br /&gt;
		    &amp;lt;/form&amp;gt;&lt;br /&gt;
		&amp;lt;/.modal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;%= if testbed.note do %&amp;gt;&lt;br /&gt;
      &amp;lt;div phx-click={show_modal(&amp;quot;notes-modal-#{testbed.id}&amp;quot;)}&amp;gt;READ ME  ...&amp;lt;%= testbed.note %&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
	   &lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
       &lt;br /&gt;
      &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
import {HfInference} from &amp;quot;@huggingface/inference&amp;quot;;&lt;br /&gt;
import dotenv from &amp;quot;dotenv&amp;quot;;&lt;br /&gt;
dotenv.config()&lt;br /&gt;
&lt;br /&gt;
const HF_ACCESS_TOKEN = process.env.HF_ACCESS_TOKEN&lt;br /&gt;
&lt;br /&gt;
const hf = new HfInference(HF_ACCESS_TOKEN);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*______Uncomment for this example______________________&lt;br /&gt;
&lt;br /&gt;
const model = &amp;quot;nlpconnect/vit-gpt2-image-captioning&amp;quot;;&lt;br /&gt;
const imageURL = &amp;quot;https://i.imgur.com/lTvb7Et.png&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
const response = await fetch(imageURL);&lt;br /&gt;
const imageBlob = await response.blob();&lt;br /&gt;
&lt;br /&gt;
const result  = await hf.imageToText({&lt;br /&gt;
	data: imageBlob,&lt;br /&gt;
	model: model,&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
_______________________________________________________*/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*________Another example ___________________*/&lt;br /&gt;
&lt;br /&gt;
const result = await hf.summarization({&lt;br /&gt;
	model: 'facebook/bart-large-cnn',&lt;br /&gt;
	inputs: &amp;quot;The role of a dumb man is to get smarter oogy bookie boo&amp;quot;,&lt;br /&gt;
	parameters:{&lt;br /&gt;
		max_length: 100&lt;br /&gt;
	}&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
console.log(result);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
________________________________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://fly.io/phoenix-files/sdeb-toggling-element/&lt;br /&gt;
https://www.youtube.com/watch?v=vBgZvQapqhs&lt;br /&gt;
&lt;br /&gt;
https://blog.testdouble.com/posts/2022-11-28-how-to-use-javascript-with-phoenix-liveview/&lt;br /&gt;
&lt;br /&gt;
https://hexdocs.pm/phoenix_live_view/0.19.3/Phoenix.Component.html&lt;br /&gt;
_______________________________________&lt;br /&gt;
https://www.smashingmagazine.com/2011/10/quick-look-math-animations-javascript/&lt;br /&gt;
* Depth first traversal&lt;br /&gt;
* Breadth first traversal&lt;br /&gt;
&lt;br /&gt;
https://dev.to/codesphere/10-algorithms-every-developer-should-learn-3lnm&lt;br /&gt;
&lt;br /&gt;
https://www.youtube.com/watch?v=fPz40W9mfCg&lt;br /&gt;
&lt;br /&gt;
__________________________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
defmodule AppWeb.GroupLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  alias App.TestBeds&lt;br /&gt;
  alias App.Groups&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    {:ok, assign(socket, testbeds: TestBeds.list_testbeds(), groups: Groups.list_groups())}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;select-group&amp;quot;, params, socket)  do  &lt;br /&gt;
         &lt;br /&gt;
       IO.inspect params&lt;br /&gt;
       {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div class=&amp;quot;grid grid-columns-2 grid-flow-col gap-4&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;column-1&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;%= testbed.name %&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;column-2&amp;quot;&amp;gt;    &lt;br /&gt;
            &amp;lt;form phx-change=&amp;quot;select-group&amp;quot;  &amp;gt;&lt;br /&gt;
               &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;testbed_id&amp;quot; value={testbed.id}/&amp;gt;&lt;br /&gt;
               &amp;lt;select id=&amp;quot;group-selection&amp;quot;  name=&amp;quot;group-id&amp;quot; &amp;gt;&lt;br /&gt;
                &amp;lt;%= for group &amp;lt;- @groups do %&amp;gt;&lt;br /&gt;
                  &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}  &amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
               &amp;lt;/select&amp;gt;&lt;br /&gt;
            &amp;lt;/form&amp;gt;&lt;br /&gt;
         &amp;lt;/div&amp;gt;&lt;br /&gt;
       &amp;lt;% end %&amp;gt;&lt;br /&gt;
   &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
____________________________&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.GroupLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
  alias App.TestBeds&lt;br /&gt;
  alias App.Groups&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
&lt;br /&gt;
    {:ok, assign(socket, testbeds: TestBeds.list_testbeds(), groups: Groups.list_groups(), messages: [])}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;select-group&amp;quot;, params, socket)  do  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
      group = App.Groups.get_group!(params[&amp;quot;group-id&amp;quot;])&lt;br /&gt;
       # IO.inspect group&lt;br /&gt;
       testbed = App.TestBeds.get_test_bed!(params[&amp;quot;testbed_id&amp;quot;])&lt;br /&gt;
     &lt;br /&gt;
       App.TestBeds.update_test_bed(testbed, %{group_id: group.id})&lt;br /&gt;
         &lt;br /&gt;
    &lt;br /&gt;
       {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def updated_groups(testbed_id)  do  &lt;br /&gt;
       groups = App.Groups.list_groups&lt;br /&gt;
       tail = Enum.filter(groups, fn(item)-&amp;gt; item.id !== testbed_id end)&lt;br /&gt;
       head = Enum.filter(groups, fn(item)-&amp;gt; item.id == testbed_id end)&lt;br /&gt;
              |&amp;gt;Enum.at(0)&lt;br /&gt;
     [head | tail]&lt;br /&gt;
         &lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
 # def handle_event(&amp;quot;groups&amp;quot;, params, socket)do  &lt;br /&gt;
 #       selected_testbed = %{name: &amp;quot;my testbed name&amp;quot;, id: 3}&lt;br /&gt;
 #       groups = App.Groups.list_groups&lt;br /&gt;
 #       tail = Enum.filter(groups, fn(item)-&amp;gt; item.id !== selected_testbed.id end)&lt;br /&gt;
 #       head = Enum.filter(groups, fn(item)-&amp;gt; item.id == selected_testbed.id end)&lt;br /&gt;
 #              |&amp;gt;Enum.at(0)&lt;br /&gt;
         &lt;br /&gt;
 &lt;br /&gt;
 #       # result = Enum.filter([1, 2, 3], fn x -&amp;gt; x.id !== 1 end)&lt;br /&gt;
 #      IO.inspect [head | tail]&lt;br /&gt;
         &lt;br /&gt;
 #      #&lt;br /&gt;
 #      {:noreply, socket, assigns.message:}&lt;br /&gt;
 #  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    &lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
       &amp;lt;%!-- &amp;lt;div phx-click = &amp;quot;groups&amp;quot;&amp;gt;CLICK ME&amp;lt;/div&amp;gt; --%&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;grid grid-cols-4 gap-4 p-8 rounded shadow bg-white&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;h2&amp;gt; Name&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;%= testbed.name %&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;h2&amp;gt; Group&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;form phx-change=&amp;quot;select-group&amp;quot; name=&amp;quot;testbed_id&amp;quot;  &amp;gt;&lt;br /&gt;
               &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;testbed_id&amp;quot; value={testbed.id}/&amp;gt;&lt;br /&gt;
               &amp;lt;select id=&amp;quot;group-selection&amp;quot;  name=&amp;quot;group-id&amp;quot; class=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
                &amp;lt;%= for group &amp;lt;- updated_groups(testbed.id) do %&amp;gt;&lt;br /&gt;
                  &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}  &amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
                  &amp;lt;!-- Write code to reorder with testbed.group_id matching group_id --&amp;gt;&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
               &amp;lt;/select&amp;gt;&lt;br /&gt;
            &amp;lt;/form&amp;gt;&lt;br /&gt;
          &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
       &amp;lt;% end %&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
_____________________________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
   use AppWeb, :live_view  &lt;br /&gt;
     alias App.Testbeds&lt;br /&gt;
  alias App.Groups&lt;br /&gt;
   def mount(_params, _session, socket)  do&lt;br /&gt;
	     {:ok, assign(socket, testbeds: Testbeds.list_testbeds(), groups: Groups.list_groups())}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
   def handle_event(&amp;quot;select-group&amp;quot;, params, socket)  do  &lt;br /&gt;
       group = App.Groups.get_group!(params[&amp;quot;group-id&amp;quot;])&lt;br /&gt;
       testbed = App.Testbeds.get_testbed!(params[&amp;quot;testbed_id&amp;quot;])&lt;br /&gt;
       result = App.Testbeds.update_testbed(testbed, %{group_id: group.id})&lt;br /&gt;
       IO.inspect result&lt;br /&gt;
      &lt;br /&gt;
       {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
    def updated_groups(testbed_id)  do  &lt;br /&gt;
       testbed = App.Testbeds.get_testbed!(testbed_id)&lt;br /&gt;
       groups = App.Groups.list_groups&lt;br /&gt;
       tail = Enum.filter(groups, fn(item)-&amp;gt; item.id !== testbed.group_id end)&lt;br /&gt;
       head = Enum.filter(groups, fn(item)-&amp;gt; item.id == testbed.group_id end)&lt;br /&gt;
              |&amp;gt;Enum.at(0)&lt;br /&gt;
 &lt;br /&gt;
       [head | tail]&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    &lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;%= for testbed &amp;lt;- @testbeds do %&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;grid grid-cols-4 gap-4 p-8 rounded shadow bg-white&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;h2&amp;gt; Name&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;name&amp;quot;&amp;gt;&amp;lt;%= testbed.name %&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;h2&amp;gt; Group&amp;lt;/h2&amp;gt;&lt;br /&gt;
          &amp;lt;div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;form phx-change=&amp;quot;select-group&amp;quot; name=&amp;quot;testbed_id&amp;quot;  &amp;gt;&lt;br /&gt;
               &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;testbed_id&amp;quot; value={testbed.id}/&amp;gt;&lt;br /&gt;
               &amp;lt;select id=&amp;quot;group-selection&amp;quot;  name=&amp;quot;group-id&amp;quot; class=&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
                &amp;lt;%= for group &amp;lt;- updated_groups(testbed.id) do %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
                  &amp;lt;%!-- &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}&amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt; --%&amp;gt;&lt;br /&gt;
                  &amp;lt;!-- Write code to reorder with testbed.group_id matching group_id --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
                  &amp;lt;%= if group !== nil do %&amp;gt;&lt;br /&gt;
                      &amp;lt;option value= {&amp;quot;#{group.id}&amp;quot;}&amp;gt;&amp;lt;%=group.name %&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
       &lt;br /&gt;
                  &amp;lt;% end %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
               &amp;lt;/select&amp;gt;&lt;br /&gt;
            &amp;lt;/form&amp;gt;&lt;br /&gt;
          &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
       &amp;lt;% end %&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
  has_many :testbeds, TestBed, on_delete: :restrict   # Has many&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
https://elixirforum.com/t/ecto-has-many-on-delete-protect/49550&lt;br /&gt;
&lt;br /&gt;
https://hexdocs.pm/ecto/Ecto.Changeset.html#unique_constraint/3&lt;br /&gt;
&lt;br /&gt;
____________________________________________________________________&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== How to Create a Mix Project and Use It in Another Mix Project ==&lt;br /&gt;
&lt;br /&gt;
To create and use a **Mix project** inside another **Mix project** in Elixir, follow the steps below:&lt;br /&gt;
&lt;br /&gt;
=== 1. Create a New Mix Project ===&lt;br /&gt;
&lt;br /&gt;
First, you need to create a new Mix project. Let's call this project `library_project`. Run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mix new library_project --module LibraryProject&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will create a new Elixir Mix project named `library_project`. The `--module` flag specifies the name of the module that will be created (in this case `LibraryProject`).&lt;br /&gt;
&lt;br /&gt;
The directory structure of `library_project` will look like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
library_project/&lt;br /&gt;
  |_ lib/&lt;br /&gt;
      |_ library_project.ex&lt;br /&gt;
  |_ mix.exs&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can then add some basic functionality inside the `library_project/lib/library_project.ex` file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule LibraryProject do&lt;br /&gt;
  def hello do&lt;br /&gt;
    IO.puts &amp;quot;Hello from LibraryProject!&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now, `library_project` is ready to be used by another Mix project.&lt;br /&gt;
&lt;br /&gt;
=== 2. Create a Second Mix Project ===&lt;br /&gt;
&lt;br /&gt;
Next, create the second Mix project where you want to use `library_project`. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mix new app_project --module AppProject&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will create another Elixir project called `app_project`.&lt;br /&gt;
&lt;br /&gt;
The directory structure for this project will look like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
app_project/&lt;br /&gt;
  |_ lib/&lt;br /&gt;
      |_ app_project.ex&lt;br /&gt;
  |_ mix.exs&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 3. Add `library_project` as a Dependency in `app_project` ===&lt;br /&gt;
&lt;br /&gt;
Now, you want to make `library_project` available in `app_project`. There are two main ways to do this:&lt;br /&gt;
&lt;br /&gt;
==== Option 1: Local Dependency (via `path`) ====&lt;br /&gt;
&lt;br /&gt;
If `library_project` is a local project (i.e., it's stored in a different directory), you can add it to the `mix.exs` of `app_project` as a local dependency by specifying the path to `library_project`.&lt;br /&gt;
&lt;br /&gt;
Edit the `mix.exs` of `app_project`:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule AppProject.MixProject do&lt;br /&gt;
  use Mix.Project&lt;br /&gt;
&lt;br /&gt;
  def project do&lt;br /&gt;
    [&lt;br /&gt;
      app: :app_project,&lt;br /&gt;
      version: &amp;quot;0.1.0&amp;quot;,&lt;br /&gt;
      elixir: &amp;quot;~&amp;gt; 1.14&amp;quot;,&lt;br /&gt;
      start_permanent: Mix.env() == :prod,&lt;br /&gt;
      deps: deps()&lt;br /&gt;
    ]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  defp deps do&lt;br /&gt;
    [&lt;br /&gt;
      {:library_project, path: &amp;quot;../library_project&amp;quot;}  # Add the local dependency&lt;br /&gt;
    ]&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here, `{:library_project, path: &amp;quot;../library_project&amp;quot;}` tells Mix to use the local `library_project` located in the `../library_project` directory (relative to `app_project`).&lt;br /&gt;
&lt;br /&gt;
After updating the `mix.exs`, run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd app_project&lt;br /&gt;
mix deps.get&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will fetch the dependency and compile `library_project`.&lt;br /&gt;
&lt;br /&gt;
==== Option 2: Publish and Fetch as a Hex Package ====&lt;br /&gt;
&lt;br /&gt;
If you want to use `library_project` as a package in another project (for example, by publishing it to **Hex.pm**, Elixir’s package manager), you need to publish it to Hex and then add it as a dependency.&lt;br /&gt;
&lt;br /&gt;
1. Publish `library_project` to Hex (if it's public or for your private use).&lt;br /&gt;
2. Add `library_project` to your `app_project`’s `mix.exs` dependencies:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defp deps do&lt;br /&gt;
  [&lt;br /&gt;
    {:library_project, &amp;quot;~&amp;gt; 0.1.0&amp;quot;}  # Specify the published version from Hex&lt;br /&gt;
  ]&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Run `mix deps.get` to fetch the package from Hex.&lt;br /&gt;
&lt;br /&gt;
=== 4. Use `library_project` in `app_project` ===&lt;br /&gt;
&lt;br /&gt;
Now, you can use the functionality from `library_project` inside your `app_project`. For example, in `app_project/lib/app_project.ex`, you can call the function from `library_project`:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
defmodule AppProject do&lt;br /&gt;
  def start do&lt;br /&gt;
    IO.puts &amp;quot;Starting app_project!&amp;quot;&lt;br /&gt;
    LibraryProject.hello()  # Call the function from the library_project&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 5. Run the App ===&lt;br /&gt;
&lt;br /&gt;
Finally, you can run your `app_project`:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd app_project&lt;br /&gt;
mix run -e &amp;quot;AppProject.start()&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will print:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Starting app_project!&lt;br /&gt;
Hello from LibraryProject!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Recap of the Process ==&lt;br /&gt;
1. **Create the `library_project`**: Use `mix new` to generate a library project.&lt;br /&gt;
2. **Create the `app_project`**: Create the second project where you will use the library.&lt;br /&gt;
3. **Add the `library_project` as a dependency**:&lt;br /&gt;
   - Use the `path` option to point to the local project or publish it to Hex for public access.&lt;br /&gt;
4. **Use the `library_project` in the `app_project`**: Call functions or use modules from the library inside the second project.&lt;br /&gt;
5. **Run the app**: Use `mix run` to execute the project.&lt;br /&gt;
&lt;br /&gt;
This way, you can reuse code from one Mix project in another by adding it as a dependency.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==z==&lt;br /&gt;
Overloaded functions are extremely common in Elixir applications. They are&lt;br /&gt;
regularly used for recursive functions and for changing behavior based on&lt;br /&gt;
configuration.&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
</feed>