Last active
April 9, 2025 16:52
-
-
Save tjchambers/bc4609229d0ba7f592eb75e60d69b4ac to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Application.put_env(:sample, Example.Endpoint, | |
http: [ip: {127, 0, 0, 1}, port: 5001], | |
server: true, | |
live_view: [signing_salt: "aaaaaaaa"], | |
secret_key_base: String.duplicate("a", 64) | |
) | |
Mix.install([ | |
{:plug_cowboy, "~> 2.5"}, | |
{:jason, "~> 1.0"}, | |
{:phoenix, "~> 1.7"}, | |
{:phoenix_html, "~> 4.1"}, | |
{:phoenix_html_helpers, "~> 1.0"}, | |
# please test your issue using the latest version of LV from GitHub! | |
{:phoenix_live_view, | |
github: "phoenixframework/phoenix_live_view", branch: "main", override: true} | |
]) | |
# if you're trying to test a specific LV commit, it may be necessary to manually build | |
# the JS assets. To do this, uncomment the following lines: | |
# this needs mix and npm available in your path! | |
# | |
# path = Phoenix.LiveView.__info__(:compile)[:source] |> Path.dirname() |> Path.join("../") | |
# System.cmd("mix", ["deps.get"], cd: path, into: IO.binstream()) | |
# System.cmd("npm", ["install"], cd: Path.join(path, "./assets"), into: IO.binstream()) | |
# System.cmd("mix", ["assets.build"], cd: path, into: IO.binstream()) | |
defmodule Example.ErrorView do | |
def render(template, _), do: Phoenix.Controller.status_message_from_template(template) | |
end | |
defmodule Example.HomeLive do | |
@moduledoc false | |
use Phoenix.LiveView, layout: {__MODULE__, :live} | |
use Phoenix.Component | |
use PhoenixHTMLHelpers | |
alias PhoenixHTMLHelpers.Form | |
attr(:form, :any, default: nil, doc: "") | |
attr(:field, :atom, default: nil, doc: "") | |
attr(:label, :string, default: nil, doc: "labels your field") | |
attr(:class, :any, default: "", doc: "extra classes for the text input") | |
attr(:options, :list, default: [], doc: "options for the select") | |
attr(:rest, :global, include: @form_attrs) | |
@doc """ | |
Renders a select field. | |
""" | |
@spec select(map()) :: Phoenix.HTML.safe() | |
def select(assigns) do | |
~H""" | |
{Form.select( | |
@form, | |
@field, | |
@options, | |
Map.to_list(@rest) | |
)} | |
""" | |
end | |
def mount(_params, _session, socket) do | |
indications = | |
Enum.map(1..6, fn n -> | |
%{permalink: n} | |
end) | |
{:ok, assign(socket, indications: indications)} | |
end | |
def render("live.html", assigns) do | |
~H""" | |
<script src="/assets/phoenix/phoenix.js"> | |
</script> | |
<script src="/assets/phoenix_live_view/phoenix_live_view.js"> | |
</script> | |
<%!-- uncomment to use enable tailwind --%> | |
<%!-- <script src="https://cdn.tailwindcss.com"></script> --%> | |
<script> | |
let liveSocket = new window.LiveView.LiveSocket("/live", window.Phoenix.Socket) | |
liveSocket.connect() | |
</script> | |
<style> | |
* { font-size: 1.1em; } | |
</style> | |
{@inner_content} | |
""" | |
end | |
def render(assigns) do | |
~H""" | |
<.form :let={f} phx-submit="submit" id="observation_form"> | |
<h1>With empty optgroup after item 3</h1> | |
<div :for={ind <- @indications}> | |
<.select | |
phx-change="pclass" | |
style="display:inline" | |
options={pclass_dropdown(ind)} | |
value={ind.permalink} | |
form={f} | |
name={"pclass_#{ind.permalink}"} | |
id={"pclass_#{ind.permalink}"} | |
class="w-min !pr-1" | |
/> | |
</div> | |
</.form> | |
""" | |
end | |
def pclass_dropdown(ind) do | |
[ | |
{"optgroupabove", | |
[ | |
[key: "a", value: "1", selected: ind.permalink == "1"], | |
[key: "b", value: "2", selected: ind.permalink == "2"], | |
[key: "c", value: "3", selected: ind.permalink == "3"] | |
]}, | |
{"optgroupempty", []}, | |
{"optgroupbelow", | |
[ | |
[key: "d", value: "4", selected: ind.permalink == "4"], | |
[key: "e", value: "5", selected: ind.permalink == "5"], | |
[key: "f", value: "6", selected: ind.permalink == "6"] | |
]} | |
] | |
end | |
def pclass_dropdown_sans_missing(ind) do | |
[ | |
{"optgroupabove", | |
[ | |
[key: "a", value: "1", selected: ind.permalink == "1"], | |
[key: "b", value: "2", selected: ind.permalink == "2"], | |
[key: "c", value: "3", selected: ind.permalink == "3"] | |
]}, | |
{"optgroupbelow", | |
[ | |
[key: "d", value: "4", selected: ind.permalink == "4"], | |
[key: "e", value: "5", selected: ind.permalink == "5"], | |
[key: "f", value: "6", selected: ind.permalink == "6"] | |
]} | |
] | |
end | |
end | |
defmodule Example.Router do | |
use Phoenix.Router | |
import Phoenix.LiveView.Router | |
pipeline :browser do | |
plug(:accepts, ["html"]) | |
end | |
scope "/", Example do | |
pipe_through(:browser) | |
live("/", HomeLive, :index) | |
end | |
end | |
defmodule Example.Endpoint do | |
use Phoenix.Endpoint, otp_app: :sample | |
socket("/live", Phoenix.LiveView.Socket) | |
plug Plug.Static, from: {:phoenix, "priv/static"}, at: "/assets/phoenix" | |
plug Plug.Static, | |
from: {:phoenix_live_view, "priv/static"}, | |
at: "/assets/phoenix_live_view" | |
plug(Example.Router) | |
end | |
{:ok, _} = Supervisor.start_link([Example.Endpoint], strategy: :one_for_one) | |
Process.sleep(:infinity) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment