progress on modal functionality and form styling
This commit is contained in:
parent
c7e12f7d49
commit
be155d7b98
16 changed files with 417 additions and 308 deletions
lib/bones73k_web
|
@ -4,16 +4,26 @@ defmodule Bones73kWeb.ModalComponent do
|
|||
@impl true
|
||||
def render(assigns) do
|
||||
~L"""
|
||||
<div id="<%= @id %>" class="phx-modal"
|
||||
phx-capture-click="close"
|
||||
phx-window-keydown="close"
|
||||
<div id="<%= @id %>" class="modal fade"
|
||||
phx-hook="BsModal"
|
||||
phx-window-keydown="hide"
|
||||
phx-key="escape"
|
||||
phx-target="#<%= @id %>"
|
||||
phx-page-loading>
|
||||
|
||||
<div class="phx-modal-content">
|
||||
<%= live_patch raw("×"), to: @return_to, class: "phx-modal-close" %>
|
||||
<%= live_component @socket, @component, @opts %>
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title"><%= Keyword.get(@opts, :title, "Modal title") %></h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<%= live_component @socket, @component, @opts %>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
"""
|
||||
|
@ -23,4 +33,9 @@ defmodule Bones73kWeb.ModalComponent do
|
|||
def handle_event("close", _, socket) do
|
||||
{:noreply, push_patch(socket, to: socket.assigns.return_to)}
|
||||
end
|
||||
|
||||
@impl true
|
||||
def handle_event("hide", _, socket) do
|
||||
{:noreply, push_event(socket, "modal-please-hide", %{})}
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,12 +5,10 @@ defmodule Bones73kWeb.PropertyLive.FormComponent do
|
|||
|
||||
@impl true
|
||||
def update(%{property: property} = assigns, socket) do
|
||||
changeset = Properties.change_property(property)
|
||||
|
||||
{:ok,
|
||||
socket
|
||||
|> assign(assigns)
|
||||
|> assign(:changeset, changeset)}
|
||||
socket
|
||||
|> assign(assigns)
|
||||
|> assign(:changeset, Properties.change_property(property))
|
||||
|> live_okreply()
|
||||
end
|
||||
|
||||
@impl true
|
||||
|
@ -30,10 +28,10 @@ defmodule Bones73kWeb.PropertyLive.FormComponent do
|
|||
defp save_property(socket, :edit, property_params) do
|
||||
case Properties.update_property(socket.assigns.property, property_params) do
|
||||
{:ok, _property} ->
|
||||
{:noreply,
|
||||
socket
|
||||
|> put_flash(:info, "Property updated successfully")
|
||||
|> push_redirect(to: socket.assigns.return_to)}
|
||||
socket
|
||||
|> put_flash(:info, "Property updated successfully")
|
||||
|> push_event("modal-please-hide", %{})
|
||||
|> live_noreply()
|
||||
|
||||
{:error, %Ecto.Changeset{} = changeset} ->
|
||||
{:noreply, assign(socket, :changeset, changeset)}
|
||||
|
@ -46,10 +44,10 @@ defmodule Bones73kWeb.PropertyLive.FormComponent do
|
|||
|
||||
case Properties.create_property(property_params) do
|
||||
{:ok, _property} ->
|
||||
{:noreply,
|
||||
socket
|
||||
|> put_flash(:info, "Property created successfully")
|
||||
|> push_redirect(to: socket.assigns.return_to)}
|
||||
socket
|
||||
|> put_flash(:info, "Property created successfully")
|
||||
|> push_event("modal-please-hide", %{})
|
||||
|> live_noreply()
|
||||
|
||||
{:error, %Ecto.Changeset{} = changeset} ->
|
||||
{:noreply, assign(socket, changeset: changeset)}
|
||||
|
|
|
@ -1,22 +1,44 @@
|
|||
<h2><%= @title %></h2>
|
||||
<%= form_for @changeset, "#", [
|
||||
phx_target: @myself,
|
||||
phx_change: "validate",
|
||||
phx_submit: "save"
|
||||
], fn f -> %>
|
||||
|
||||
<%= f = form_for @changeset, "#",
|
||||
id: "property-form",
|
||||
phx_target: @myself,
|
||||
phx_change: "validate",
|
||||
phx_submit: "save" %>
|
||||
|
||||
<%= label f, :name %>
|
||||
<%= text_input f, :name %>
|
||||
<%= error_tag f, :name %>
|
||||
<div class="mb-3" phx-feedback-for="<%= input_id(f, :name)%>">
|
||||
<%= label f, :name, class: "form-label" %>
|
||||
<div class="input-group has-validation">
|
||||
<%= text_input f, :name,
|
||||
class: input_class(f, :name, "form-control"),
|
||||
aria_describedby: error_id(f, :name)
|
||||
%>
|
||||
<%= error_tag f, :name %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<%= label f, :price %>
|
||||
<%= number_input f, :price, step: "any" %>
|
||||
<%= error_tag f, :price %>
|
||||
<div class="mb-3" phx-feedback-for="<%= input_id(f, :price)%>">
|
||||
<%= label f, :price, class: "form-label" %>
|
||||
<div class="input-group has-validation">
|
||||
<%= number_input f, :price,
|
||||
class: input_class(f, :price, "form-control"),
|
||||
step: "any",
|
||||
aria_describedby: error_id(f, :price)
|
||||
%>
|
||||
<%= error_tag f, :price %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<%= label f, :description %>
|
||||
<%= textarea f, :description %>
|
||||
<%= error_tag f, :description %>
|
||||
<div class="mb-3" phx-feedback-for="<%= input_id(f, :description)%>">
|
||||
<%= label f, :description, class: "form-label" %>
|
||||
<div class="input-group has-validation">
|
||||
<%= textarea f, :description,
|
||||
class: input_class(f, :description, "form-control"),
|
||||
aria_describedby: error_id(f, :description)
|
||||
%>
|
||||
<%= error_tag f, :description %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<%= submit "Save", phx_disable_with: "Saving..." %>
|
||||
</form>
|
||||
<%= submit "Save", phx_disable_with: "Saving...", class: "btn btn-primary" %>
|
||||
|
||||
<% end %>
|
||||
|
|
|
@ -30,7 +30,7 @@ defmodule Bones73kWeb.UserLive.Registration do
|
|||
@impl true
|
||||
def handle_event("validate", %{"user" => user_params}, socket) do
|
||||
cs = Accounts.change_user_registration(%User{}, user_params)
|
||||
{:noreply, assign(socket, changeset: %{cs | action: :update})}
|
||||
{:noreply, assign(socket, changeset: %{cs | action: :validate})}
|
||||
end
|
||||
|
||||
@impl true
|
||||
|
|
|
@ -19,7 +19,7 @@ defmodule Bones73kWeb.UserLive.ResetPassword do
|
|||
@impl true
|
||||
def handle_event("validate", %{"user" => user_params}, socket) do
|
||||
cs = Accounts.change_user_password(socket.assigns.user, user_params)
|
||||
{:noreply, socket |> assign(changeset: %{cs | action: :update})}
|
||||
{:noreply, socket |> assign(changeset: %{cs | action: :validate})}
|
||||
end
|
||||
|
||||
def handle_event("save", %{"user" => user_params}, socket) do
|
||||
|
@ -34,7 +34,7 @@ defmodule Bones73kWeb.UserLive.ResetPassword do
|
|||
{:noreply,
|
||||
socket
|
||||
|> put_flash(:error, "Please check the errors below.")
|
||||
|> assign(changeset: %{changeset | action: :update})}
|
||||
|> assign(changeset: changeset)}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -20,7 +20,7 @@ defmodule Bones73kWeb.UserLive.Settings.Email do
|
|||
@impl true
|
||||
def handle_event("validate", %{"user" => user_params}, socket) do
|
||||
cs = get_changeset(socket.assigns.current_user, user_params)
|
||||
{:noreply, assign(socket, changeset: %{cs | action: :update})}
|
||||
{:noreply, assign(socket, changeset: %{cs | action: :validate})}
|
||||
end
|
||||
|
||||
# user_settings_path GET /users/settings/confirm_email/:token Bones73kWeb.UserSettingsController :confirm_email
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
<%= icon_div @socket, "bi-lock", [class: "icon fs-5"] %>
|
||||
</span>
|
||||
<%= password_input f, :current_password,
|
||||
value: input_value(f, :current_password),
|
||||
class: "form-control",
|
||||
required: true,
|
||||
aria_describedby: error_id(f, :current_password)
|
||||
|
|
|
@ -30,7 +30,7 @@ defmodule Bones73kWeb.UserLive.Settings.Password do
|
|||
@impl true
|
||||
def handle_event("validate", %{"user" => user_params}, socket) do
|
||||
cs = get_changeset(socket.assigns.current_user, user_params)
|
||||
{:noreply, assign(socket, changeset: %{cs | action: :update})}
|
||||
{:noreply, assign(socket, changeset: %{cs | action: :validate})}
|
||||
end
|
||||
|
||||
@impl true
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
<%= icon_div @socket, "bi-lock", [class: "icon fs-5"] %>
|
||||
</span>
|
||||
<%= password_input f, :current_password,
|
||||
value: input_value(f, :current_password),
|
||||
class: "form-control",
|
||||
required: true,
|
||||
aria_describedby: error_id(f, :current_password)
|
||||
|
|
|
@ -11,27 +11,31 @@
|
|||
<div class="border-4 border-dashed border-gray-200 rounded-lg h-96"></div>
|
||||
</div> %>
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit. Voluptatibus dolore sunt quia aperiam sint id
|
||||
reprehenderit? Dolore incidunt alias inventore accusantium nulla optio, ducimus eius aliquam hic, pariatur
|
||||
voluptate distinctio.
|
||||
Praesent velit justo, auctor ut nibh id, fermentum eleifend nunc. Cras sed purus dignissim, ornare elit et, ultrices elit. Sed quis neque consequat, laoreet ante a, hendrerit elit. Maecenas dapibus sed nulla vitae consectetur. Duis sollicitudin augue nisl, et rhoncus enim tempor at. Fusce scelerisque sollicitudin purus sit amet iaculis. Phasellus lacinia mi ut laoreet accumsan. Sed sagittis erat nec sem placerat, ut volutpat neque porttitor. Suspendisse tempor mauris vel mollis sagittis. In ut laoreet arcu. Duis sed felis in dui imperdiet luctus nec faucibus sem. Donec commodo urna ut enim fringilla, quis lacinia ligula malesuada. Quisque feugiat fermentum pretium. Integer sed porttitor lacus, sed bibendum diam. Aliquam dapibus neque et pharetra interdum.
|
||||
</p>
|
||||
<!-- /End replace -->
|
||||
</div>
|
||||
|
||||
<%# <div class="columns is-centered">
|
||||
<div class="column is-three-fifths">
|
||||
<!-- Button trigger modal -->
|
||||
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModal">
|
||||
Launch demo modal
|
||||
</button>
|
||||
|
||||
<div class="title is-4">
|
||||
<span>Other Page</span>
|
||||
<!-- Modal -->
|
||||
<div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="exampleModalLabel">Modal title</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
Aliquam ultrices elit purus, eget dignissim orci pulvinar id. Curabitur tincidunt, ligula eu condimentum porttitor, nibh sapien scelerisque urna, nec cursus nisi nisi a neque. Mauris hendrerit orci blandit, suscipit ante nec, porttitor neque. Nunc.
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
||||
<button type="button" class="btn btn-primary">Save changes</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="subtitle">With a subtitle no less!</div>
|
||||
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit. Voluptatibus dolore sunt quia aperiam sint id
|
||||
reprehenderit? Dolore incidunt alias inventore accusantium nulla optio, ducimus eius aliquam hic, pariatur
|
||||
voluptate distinctio.
|
||||
</p>
|
||||
|
||||
</div>
|
||||
</div> %>
|
||||
</div>
|
||||
|
|
|
@ -30,37 +30,13 @@ defmodule Bones73kWeb.ErrorHelpers do
|
|||
def error_id(input_id) when is_binary(input_id), do: "#{input_id}_feedback"
|
||||
|
||||
def input_class(form, field, classes \\ "") do
|
||||
case field_status(form, field) do
|
||||
:ok -> "#{classes} is-valid"
|
||||
:error -> "#{classes} is-invalid"
|
||||
_ -> classes
|
||||
end
|
||||
end
|
||||
|
||||
defp field_status(form, field) do
|
||||
case field_has_data?(form, field) do
|
||||
true ->
|
||||
form.errors
|
||||
|> Keyword.get_values(field)
|
||||
|> Enum.empty?()
|
||||
|> case do
|
||||
true -> :ok
|
||||
false -> :error
|
||||
case form.source.action do
|
||||
nil -> classes
|
||||
_ ->
|
||||
case Keyword.has_key?(form.errors, field) do
|
||||
true -> "#{classes} is-invalid"
|
||||
_ -> "#{classes} is-valid"
|
||||
end
|
||||
|
||||
false ->
|
||||
:default
|
||||
end
|
||||
end
|
||||
|
||||
defp field_has_data?(form, field) when is_atom(field),
|
||||
do: field_has_data?(form, Atom.to_string(field))
|
||||
|
||||
defp field_has_data?(form, field) when is_binary(field) do
|
||||
case Map.get(form.params, field) do
|
||||
nil -> false
|
||||
"" -> false
|
||||
_ -> true
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue