Last active
February 28, 2024 22:13
-
-
Save goblinJoel/fa97c3b51f761a7d597e0f2f8ba6c3b4 to your computer and use it in GitHub Desktop.
LiveSelect test page
This file contains 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
// We need to import the CSS so that webpack will load it. | |
// The MiniCssExtractPlugin is used to separate it out into | |
// its own CSS file. | |
import "../css/app.css" | |
// webpack automatically bundles all modules in your | |
// entry points. Those entry points can be configured | |
// in "webpack.config.js". | |
// | |
// Import deps with the dep name or local files with a relative path, for example: | |
// | |
// import {Socket} from "phoenix" | |
// import socket from "./socket" | |
// | |
import "phoenix_html" | |
import {Socket, LongPoll} from "phoenix" | |
import {LiveSocket} from "phoenix_live_view" | |
// liveview-compatible multiselect widget | |
// import LiveSelect from "live_select" | |
let csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content") | |
// let Hooks = {LiveSelect} | |
let Hooks = {} | |
Hooks.LiveSelect = { | |
attachDomEventHandlers() { | |
console.log("attachDomEventHandlers()"); | |
this.el.querySelector("input[type=text]").onkeydown = (event) => { | |
if(event.code === "Enter") { | |
event.preventDefault() | |
} | |
this.pushEventTo(this.el, 'keydown', {key: event.code}) | |
} | |
}, | |
setInputValue(value) { | |
console.log("setInputValue()"); | |
this.el.querySelector("input[type=text]").value = value | |
}, | |
inputEvent(selection, mode) { | |
console.log("inputEvent()"); | |
const selector = mode === "single" ? "input.hidden" : (selection.length === 0 ? "input[name=live_select_empty_selection]" : "input[type=hidden]") | |
this.el.querySelector(selector).dispatchEvent(new Event('input', {bubbles: true})) | |
}, | |
mounted() { | |
console.log("mounted()"); | |
this.handleEvent("reset", ({id}) => { | |
console.log("reset") | |
if(this.el.id === id) { | |
this.setInputValue(null) | |
this.inputEvent([], "single") | |
} | |
}) | |
this.handleEvent("select", ({id, selection, mode}) => { | |
console.log("select") | |
if(this.el.id === id) { | |
if(mode === "single") { | |
const [{label}] = selection | |
this.setInputValue(label) | |
this.inputEvent(selection, mode) | |
} else { | |
this.setInputValue(null) | |
this.inputEvent(selection, mode) | |
} | |
} | |
}) | |
this.attachDomEventHandlers() | |
}, | |
updated() { | |
console.log("updated()"); | |
this.attachDomEventHandlers() | |
} | |
} | |
let liveSocket = new LiveSocket("/live", Socket, { | |
params: {_csrf_token: csrfToken}, | |
hooks: Hooks | |
}) | |
let socket = liveSocket.socket | |
socket.onError((error, transport, establishedConnections) => { | |
if(transport === WebSocket && establishedConnections === 0) { | |
socket.replaceTransport(LongPoll) | |
socket.connect() | |
} | |
}) | |
// Connect if there are any LiveViews on the page | |
liveSocket.connect() | |
window.liveSocket = liveSocket |
This file contains 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
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="utf-8"/> | |
<meta http-equiv="X-UA-Compatible" content="IE=edge"/> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"/> | |
<title>My Project</title> | |
<link rel="stylesheet" href="<%= Routes.static_path(@conn, "/css/app.css") %>"/> | |
<%= csrf_meta_tag() %> | |
<script defer type="text/javascript" src="<%= Routes.static_path(@conn, "/js/app.js") %>"></script> | |
</head> | |
<body class="flex flex-col bg-main"> | |
<div> | |
<%= @inner_content %> | |
</div> | |
</body> | |
</html> |
This file contains 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
defmodule MyProject.LiveSelectTest do | |
use Phoenix.LiveView | |
import LiveSelect | |
@impl true | |
def render(assigns) do | |
~H""" | |
<.form for={:my_form} :let={f} phx-change="other_change"> | |
<%= live_select f, :city_search %> | |
</.form> | |
""" | |
end | |
@impl true | |
def mount(_params, _session, socket) do | |
{:ok, socket} | |
end | |
@impl true | |
def handle_info(%LiveSelect.ChangeMsg{} = change_msg, socket) do | |
cities = [{"a", 1}, {"b", 2}] | |
# cities could be: | |
# [ {"city name 1", [lat_1, long_1]}, {"city name 2", [lat_2, long_2]}, ... ] | |
# | |
# but it could also be (no coordinates in this case): | |
# [ "city name 1", "city name 2", ... ] | |
# | |
# or: | |
# [ [label: "city name 1", value: [lat_1, long_1]], [label: "city name 2", value: [lat_2, long_2]], ... ] | |
# | |
# or even: | |
# ["city name 1": [lat_1, long_1], "city name 2": [lat_2, long_2]] | |
update_options(change_msg, cities) | |
{:noreply, socket} | |
end | |
@impl true | |
def handle_event( | |
"change", | |
%{"my_form" => %{"city_search_text_input" => city_name, "city_search" => city_coords}}, | |
socket | |
) do | |
IO.puts("You selected city #{city_name} located at: #{city_coords}") | |
{:noreply, socket} | |
end | |
@impl true | |
def handle_event( | |
"other_change", | |
%{"my_form" => %{"city_search_text_input" => city_name, "city_search" => city_coords}}, | |
socket | |
) do | |
IO.puts("OTHER: You selected city #{city_name} located at: #{city_coords}") | |
{:noreply, socket} | |
end | |
end |
This file contains 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
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="utf-8"/> | |
<meta http-equiv="X-UA-Compatible" content="IE=edge"/> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"/> | |
<title>My Project</title> | |
<link rel="stylesheet" href="/css/app.css"/> | |
<meta content="Ng8mKEM6cRICN21ELV1qPT5sITEcMS9HcnuZ2l5tcSX2b9RzXUDtsFyu" name="csrf-token"> | |
<script defer type="text/javascript" src="/js/app.js"></script> | |
</head> | |
<body class="flex flex-col bg-main"> | |
<div> | |
<div data-phx-main="true" data-phx-session="redacted" id="phx-FzbeTP8gbdFaTGbB"><form phx-change="other_change"> | |
<div id="my_form_city_search_component" class="relative h-full text-black" name="live-select" phx-hook="LiveSelect" phx-target="1"> | |
<input autocomplete="off" class="rounded-md w-full disabled:bg-gray-100 disabled:placeholder:text-gray-400 disabled:text-gray-400" id="my_form_city_search_text_input" name="my_form[city_search_text_input]" phx-blur="blur" phx-change="change" phx-click="click" phx-debounce="100" phx-focus="focus" phx-keyup="keyup" phx-target="1" type="text"> | |
<!-- TODO: this can become a hidden input when this fix is released: https://github.com/phoenixframework/phoenix_live_view/commit/2d6495a4fd4e3cc9b67ee631102e65b1bc7912f1 --> | |
<input class="hidden" id="my_form_city_search" name="my_form[city_search]" style="display: none;" type="text"> | |
<ul class="absolute rounded-xl shadow z-50 bg-gray-100 w-full cursor-pointer" style="display: none;" name="live-select-dropdown"> | |
</ul> | |
</div> | |
</form></div> | |
</div> | |
<iframe hidden height="0" width="0" src="/phoenix/live_reload/frame"></iframe></body> | |
</html> |
This file contains 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
# This is just the route I added to the project for this test page. | |
# the project's LayoutView is the basically-empty default | |
live_session :liveselect, root_layout: {MyProject.LayoutView, :liveselect_root} do | |
live "/liveselect", LiveSelectTest | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment