Skip to content

Commit

Permalink
Merge pull request #209 from dwyl/select-input
Browse files Browse the repository at this point in the history
Select input
  • Loading branch information
nelsonic authored Nov 29, 2022
2 parents 4d430b3 + e9104d7 commit d15e8d8
Show file tree
Hide file tree
Showing 15 changed files with 256 additions and 128 deletions.
1 change: 1 addition & 0 deletions assets/css/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -84,3 +84,4 @@ input[type=radio].has-error:not(.phx-no-feedback) {
100% { opacity: 1; }
}

[x-cloak] { display: none !important; }
16 changes: 15 additions & 1 deletion assets/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,22 @@ import {Socket} from "phoenix"
import {LiveSocket} from "phoenix_live_view"
import topbar from "../vendor/topbar"


let Hooks = {}
let csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content")
let liveSocket = new LiveSocket("/live", Socket, {params: {_csrf_token: csrfToken}})

let liveSocket = new LiveSocket("/live", Socket, {
hooks: Hooks,
dom:{
onBeforeElUpdated(from, to) {
if (from._x_dataStack) {
window.Alpine.clone(from, to)
}
}
},
params: {_csrf_token: csrfToken}
})


// Show progress bar on live navigation and form submits
topbar.config({barColors: {0: "#29d"}, shadowColor: "rgba(0, 0, 0, .3)"})
Expand Down
2 changes: 1 addition & 1 deletion config/config.exs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ config :logger, :console,
config :phoenix, :json_library, Jason

config :tailwind,
version: "3.2.0",
version: "3.2.4",
default: [
args: ~w(
--config=tailwind.config.js
Expand Down
13 changes: 7 additions & 6 deletions lib/app/item.ex
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ defmodule App.Item do

def changeset_with_tags(item, attrs) do
changeset(item, attrs)
|> put_assoc(:tags, Tag.parse_and_create_tags(attrs))
|> put_assoc(:tags, attrs.tags)
end

@doc """
Expand Down Expand Up @@ -117,11 +117,12 @@ defmodule App.Item do
@doc """
Update an item and its associated tags
"""
def update_item_with_tags(%Item{} = item, attrs) do
item
|> Item.changeset_with_tags(attrs)
|> Repo.update()
end

# def update_item_with_tags(%Item{} = item, attrs) do
# item
# |> Item.changeset_with_tags(attrs)
# |> Repo.update()
# end

def delete_item(id) do
get_item!(id)
Expand Down
14 changes: 7 additions & 7 deletions lib/app/tag.ex
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,13 @@ defmodule App.Tag do
|> Repo.insert()
end

def parse_and_create_tags(attrs) do
(attrs[:tags] || "")
|> String.split(",")
|> Enum.map(&String.trim/1)
|> Enum.reject(&(&1 == ""))
|> create_tags(attrs[:person_id])
end
# def parse_and_create_tags(attrs) do
# (attrs[:tags] || "")
# |> String.split(",")
# |> Enum.map(&String.trim/1)
# |> Enum.reject(&(&1 == ""))
# |> create_tags(attrs[:person_id])
# end

@doc """
Insert the list of tag names given as argument.
Expand Down
1 change: 0 additions & 1 deletion lib/app/timer.ex
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,6 @@ defmodule App.Timer do
res = Ecto.Adapters.SQL.query!(Repo, sql, [item_id])

if res.num_rows > 0 do
# IO.inspect(res.rows)
timer_id = res.rows |> List.first() |> List.first()

Logger.debug(
Expand Down
2 changes: 1 addition & 1 deletion lib/app_web.ex
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ defmodule AppWeb do
def live_view do
quote do
use Phoenix.LiveView,
layout: {AppWeb.LayoutView, "live.html"}
layout: {AppWeb.LayoutView, :live}

unquote(view_helpers())
end
Expand Down
59 changes: 49 additions & 10 deletions lib/app_web/live/app_live.ex
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
defmodule AppWeb.AppLive do
require Logger

use AppWeb, :live_view
use Timex
alias App.{Item, Timer}
alias App.{Item, Tag, Timer}
# run authentication on mount
on_mount AppWeb.AuthController
on_mount(AppWeb.AuthController)
alias Phoenix.Socket.Broadcast

@topic "live"
Expand All @@ -19,30 +18,40 @@ defmodule AppWeb.AppLive do

person_id = get_person_id(socket.assigns)
items = Item.items_with_timers(person_id)
tags = Tag.list_person_tags(person_id)
selected_tags = []

{:ok,
assign(socket,
items: items,
editing_timers: [],
editing: nil,
filter: "active",
filter_tag: nil
filter_tag: nil,
tags: tags,
selected_tags: selected_tags,
text_value: ""
)}
end

@impl true
def handle_event("create", %{"text" => text, "tags" => tags}, socket) do
def handle_event("validate", %{"text" => text}, socket) do
{:noreply, assign(socket, text_value: text)}
end

@impl true
def handle_event("create", %{"text" => text}, socket) do
person_id = get_person_id(socket.assigns)

Item.create_item_with_tags(%{
text: text,
person_id: person_id,
status: 2,
tags: tags
tags: socket.assigns.selected_tags
})

AppWeb.Endpoint.broadcast(@topic, "update", :create)
{:noreply, socket}
{:noreply, assign(socket, text_value: "", selected_tags: [])}
end

@impl true
Expand All @@ -59,6 +68,37 @@ defmodule AppWeb.AppLive do
{:noreply, socket}
end

@impl true
def handle_event("toggle_tag", value, socket) do
person_id = get_person_id(socket.assigns)
selected_tags = socket.assigns.selected_tags
tag = Tag.get_tag!(value["tag_id"])
tags = Tag.list_person_tags(person_id)

selected_tags =
if Enum.member?(selected_tags, tag) do
List.delete(selected_tags, tag)
else
[tag | selected_tags]
end
|> Enum.sort_by(& &1.text)

{:noreply, assign(socket, tags: tags, selected_tags: selected_tags)}
end

@impl true
def handle_event("filter-tags", %{"key" => _key, "value" => value}, socket) do
person_id = get_person_id(socket.assigns)

tags =
Tag.list_person_tags(person_id)
|> Enum.filter(fn t ->
String.contains?(String.downcase(t.text), String.downcase(value))
end)

{:noreply, assign(socket, tags: tags)}
end

@impl true
def handle_event("delete", %{"id" => item_id}, socket) do
Item.delete_item(item_id)
Expand Down Expand Up @@ -104,15 +144,14 @@ defmodule AppWeb.AppLive do
@impl true
def handle_event(
"update-item",
%{"id" => item_id, "text" => text, "tags" => tags},
%{"id" => item_id, "text" => text},
socket
) do
person_id = get_person_id(socket.assigns)
current_item = Item.get_item!(item_id)

Item.update_item_with_tags(current_item, %{
Item.update_item(current_item, %{
text: text,
tags: tags,
person_id: person_id
})

Expand Down
110 changes: 92 additions & 18 deletions lib/app_web/live/app_live.html.heex
Original file line number Diff line number Diff line change
@@ -1,33 +1,109 @@
<main class="h-90 w-full font-sans">
<form
<main class="font-sans container mx-auto">
<.form
:let={_f}
for={:item}
phx-submit="create"
class="w-full lg:w-3/4 lg:max-w-lg text-center mx-auto"
class="w-full lg:w-1/2 m-auto"
>
<!-- textarea so that we can have multi-line capturing
help wanted auto re-sizing: https://github.com/dwyl/learn-alpine.js/issues/3 -->
<textarea
class="w-full py-1 px-1 text-slate-800 text-3xl
bg-white bg-clip-padding
resize-none
max-h-80
max-h-100
transition ease-in-out
border border-b border-slate-200
focus:border-none focus:outline-none"
focus:border-none focus:outline-none
my-2"
name="text"
phx-change="validate"
placeholder="What needs to be done?"
autofocus=""
autofocus="true"
required="required"
x-data="{resize() {
$el.style.height = '80px';
$el.style.height = '100px';
$el.style.height = $el.scrollHeight + 'px';
}
}"
x-init="resize"
x-on:input="resize"
><%= @text_value %></textarea>
<!-- Select Input -->
<div
class="lg:w-1/2 "
x-data="{open: false}"
x-on:click.away="open = false"
x-on:keydown.escape="open = false"
>
</textarea>
<input
type="text"
name="tag"
class="w-full my-2"
x-on:focus="open = true"
phx-keyup="filter-tags"
phx-debounce="250"
autocomplete="off"
placeholder="tags"
/>
<div
class="relative z-10 drop-shadow-lg w-auto"
x-show="open"
x-transition
x-cloak
>
<ul class="absolute border bg-white max-h-64 overflow-auto w-full">
<%= for tag <- @tags do %>
<li
class="border-b p-2 cursor-pointer hover:bg-slate-200"
phx-click="toggle_tag"
phx-value-tag_id={tag.id}
>
<div class="relative h-10">
<div class="inline-flex items-center w-3/4">
<span
class="w-5 h-5 bg-red-500 rounded-full mx-2 shrink-0"
style={"background-color:#{tag.color}"}
>
</span>
<span class="overflow-hidden text-ellipsis whitespace-nowrap">
<%= tag.text %>
</span>
</div>
<%= if Enum.member?(@selected_tags, tag) do %>
<svg
class="absolute font-bold w-4 top-0 bottom-0 m-auto right-0 text-green-500"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="currentColor"
>
<path
fill-rule="evenodd"
d="M19.916 4.626a.75.75 0 01.208 1.04l-9 13.5a.75.75 0 01-1.154.114l-6-6a.75.75 0 011.06-1.06l5.353 5.353 8.493-12.739a.75.75 0 011.04-.208z"
clip-rule="evenodd"
/>
</svg>
<% end %>
</div>
</li>
<% end %>
<li class="border-b p-2 cursor-pointer hover:bg-slate-200">
<%= link("edit tags", to: "/tags", class: "block w-full text-center") %>
</li>
</ul>
</div>
</div>
<!-- End Select Input -->

<input type="text" name="tags" placeholder="tag1, tag2,..." />
<!-- Display the selected tags -->
<div class="">
<%= for selected_tag <- @selected_tags do %>
<span
class="text-white font-bold py-1 px-2 rounded-full ml-2"
style={"background-color:#{selected_tag.color}"}
>
<%= selected_tag.text %>
</span>
<% end %>
</div>
<!-- Want to help "DRY" this? see: https://github.com/dwyl/app-mvp-phoenix/issues/105 -->
<!-- https://tailwindcss.com/docs/justify-content#end -->
<div class="flex justify-end mr-1">
Expand All @@ -50,7 +126,7 @@
Save
</button>
</div>
</form>
</.form>
<!-- List of items with inline buttons and controls -->
<ul class="w-full">
<%= for item <- filter_items(@items, @filter, @filter_tag) do %>
Expand Down Expand Up @@ -187,14 +263,13 @@
required="required"
value={item.text}
><%= item.text %></textarea>
<input
<!--<input
id={"tag-of-item-#{item.id}"}
type="text"
name="tags"
value={tags_to_string(item.tags)}
placeholder="tag1, tag2..."
/>

/>-->
<input type="hidden" name="id" value={item.id} />

<div
Expand Down Expand Up @@ -443,9 +518,9 @@
</ul>
</main>

<footer class="mt-2">
<footer class="mt-5 container mx-auto">
<%= if has_items?(@items) do %>
<div class="flex flex-row justify-center p-1 border-t">
<div class="flex flex-row justify-center p-1">
<div class="px-2 py-2">
<%= live_patch("All",
to: Routes.live_path(@socket, AppWeb.AppLive, %{filter_by: "all"}),
Expand Down Expand Up @@ -481,7 +556,6 @@
}
function timer_text(start, current) {
console.log("timer_text(start, current)", start, current)
let h="00", m="00", s="00";
const diff = current - start;
// seconds
Expand Down
Loading

0 comments on commit d15e8d8

Please sign in to comment.