Skip to content

Commit 567de85

Browse files
committed
added liveview
1 parent 05192ed commit 567de85

File tree

16 files changed

+356
-4544
lines changed

16 files changed

+356
-4544
lines changed

docs/.nojekyll

Whitespace-only changes.

docs/ecosystem/ecosystem.html

Lines changed: 0 additions & 961 deletions
This file was deleted.

docs/elixir/chapter.html

Lines changed: 0 additions & 590 deletions
This file was deleted.

docs/elixir/liveview.html

Lines changed: 130 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -675,7 +675,16 @@ <h3 id="formulario"><a class="anchor" href="#formulario"></a>Formulario</h3>
675675
</div>
676676
<div class="listingblock">
677677
<div class="content">
678-
<pre class="highlightjs highlight"><code class="language-elixir hljs" data-lang="elixir">|&gt; assign(form: to_form(%{"author" =&gt; nil, "source" =&gt; nil, "quote" =&gt; nil}))</code></pre>
678+
<pre class="highlightjs highlight"><code class="language-elixir hljs" data-lang="elixir">defp empty_form() do
679+
to_form(%{"author" =&gt; "", "quote" =&gt; "", "source" =&gt; ""})
680+
end
681+
682+
def mount(_params, _session, socket) do
683+
{:ok,
684+
socket
685+
|&gt; assign(alert: nil)
686+
|&gt; assign(form: empty_form())}
687+
end</code></pre>
679688
</div>
680689
</div>
681690
<div class="paragraph">
@@ -713,12 +722,15 @@ <h3 id="formulario"><a class="anchor" href="#formulario"></a>Formulario</h3>
713722
<pre class="highlightjs highlight"><code class="language-elixir hljs" data-lang="elixir">defmodule StoicQuotesWeb.Live.QuotesForm do
714723
use StoicQuotesWeb, :live_view
715724

725+
defp empty_form() do
726+
to_form(%{"author" =&gt; "", "quote" =&gt; "", "source" =&gt; ""})
727+
end
728+
716729
def mount(_params, _session, socket) do
717730
{:ok,
718731
socket
719732
|&gt; assign(alert: nil)
720-
|&gt; assign(form: to_form(%{"author" =&gt; nil, "source" =&gt; nil, "quote" =&gt; nil}))
721-
}
733+
|&gt; assign(form: empty_form())}
722734
end
723735

724736
def handle_event("validate", params, socket) do
@@ -852,6 +864,7 @@ <h3 id="formulario"><a class="anchor" href="#formulario"></a>Formulario</h3>
852864
&lt;div class="mt-2"&gt;
853865
&lt;.input
854866
autofocus="true"
867+
required="true"
855868
placeholder="Marcus Aurelius"
856869
phx-debounce="blur"
857870
field={@form[:author]}
@@ -867,6 +880,7 @@ <h3 id="formulario"><a class="anchor" href="#formulario"></a>Formulario</h3>
867880
&lt;div class="mt-2"&gt;
868881
&lt;.input
869882
placeholder="Meditations"
883+
required="true"
870884
phx-debounce="blur"
871885
field={@form[:source]}
872886
class="block w-full rounded-md bg-white/5 px-3 py-1.5 text-base text-white outline-1 -outline-offset-1 outline-white/10 placeholder:text-gray-500 focus:outline-2 focus:-outline-offset-2 focus:outline-indigo-500 sm:text-sm/6"
@@ -885,6 +899,7 @@ <h3 id="formulario"><a class="anchor" href="#formulario"></a>Formulario</h3>
885899
&lt;div class="mt-2"&gt;
886900
&lt;.input
887901
type="textarea"
902+
required="true"
888903
rows="5"
889904
placeholder="Lorem Ipsum"
890905
phx-debounce="blur"
@@ -925,21 +940,95 @@ <h2 id="paso-5-implementar-validación-del-formulario"><a class="anchor" href="#
925940
<div class="paragraph">
926941
<p>Ahora se realizará la validación del formulario, para que muestre errores
927942
si se envía un valor que no sea correcto. Para esto modificaremos la función
928-
<code>def handle_event("validate", params, socket)</code>.</p>
943+
<code>def handle_event("validate", params, socket)</code>, donde crearemos un nuevo <code>changeset</code>,
944+
el cual será la estructura usada para realizar todas las validaciones. Como ya tenemos
945+
un esquema podemos reutilizarlo, sin embargo también existen los <code>changeset</code> sin esquemas
946+
(por ejemplo un formulario de contacto) que pemiten realizar validaciones a formularios
947+
no asociados a una base de datos o también cuando sea necesario validar múltiples valores
948+
no relacionados en la misma tabla.</p>
949+
</div>
950+
<div class="paragraph">
951+
<p>Primero añadimos el módulo y el <em>Logger</em>.</p>
952+
</div>
953+
<div class="listingblock">
954+
<div class="title">quotes_form.ex</div>
955+
<div class="content">
956+
<pre class="highlightjs highlight"><code class="language-elixir hljs" data-lang="elixir">defmodule StoicQuotesWeb.Live.QuotesForm do
957+
use StoicQuotesWeb, :live_view
958+
959+
alias StoicQuotes.Quotes
960+
alias StoicQuotes.Quotes.Quote
961+
require Logger
962+
...</code></pre>
963+
</div>
964+
</div>
965+
<div class="paragraph">
966+
<p>Luego modificamos la función para usar el módulo. Notemos que añadimos
967+
una nueva función llamada <code>Quote.new</code> que inicia una validación con los parámetros
968+
que le hemos dado. Para esto debemos añadir la función al esquema correspondiente.</p>
929969
</div>
930970
<div class="listingblock">
931971
<div class="title">quotes_form.ex</div>
932972
<div class="content">
933973
<pre class="highlightjs highlight"><code class="language-elixir hljs" data-lang="elixir">def handle_event("validate", params, socket) do
934-
IO.inspect(params, label: :validate)
935-
form = to_form(params)
974+
changeset =
975+
Quote.new(params)
976+
977+
form = to_form(params, errors: changeset.errors)
978+
979+
Logger.debug(changeset)
980+
Logger.debug(form)
981+
936982
{:noreply,
937-
socket
938-
|&gt; assign(form: form)
939-
}
983+
socket
984+
|&gt; assign(form: form)}
940985
end</code></pre>
941986
</div>
942987
</div>
988+
<div class="paragraph">
989+
<p>Ahora modicamos el esquema para que tenga la función <code>new</code>.</p>
990+
</div>
991+
<div class="listingblock">
992+
<div class="title">lib/stoic_quotes/quotes/quote.ex</div>
993+
<div class="content">
994+
<pre class="highlightjs highlight"><code class="language-elixir hljs" data-lang="elixir">defmodule StoicQuotes.Quotes.Quote do
995+
use Ecto.Schema
996+
import Ecto.Changeset
997+
alias __MODULE__
998+
999+
schema "quotes" do
1000+
field(:quote, :string)
1001+
field(:author, :string)
1002+
field(:source, :string)
1003+
1004+
timestamps(type: :utc_datetime)
1005+
end
1006+
1007+
@doc false
1008+
def changeset(quote, attrs) do
1009+
quote
1010+
|&gt; cast(attrs, [:quote, :author, :source])
1011+
|&gt; validate_required([:quote, :author, :source])
1012+
|&gt; unique_constraint(:quote, name: :index_for_duplicate_quotes)
1013+
end
1014+
1015+
@doc false
1016+
def new(attrs \\ %{"author" =&gt; "", "quote" =&gt; "", "source" =&gt; ""}) do
1017+
changeset(%Quote{}, attrs)
1018+
end
1019+
end</code></pre>
1020+
</div>
1021+
</div>
1022+
<div class="ulist">
1023+
<ul>
1024+
<li>
1025+
<p><code>alias <em>MODULE</em></code>: Este elemento permite utilizar el módulo dentro del mismo.</p>
1026+
</li>
1027+
<li>
1028+
<p><code>changeset(%Quote{}, attrs)</code>: Llamamos a la función existente pasando los parámetros adecuados.</p>
1029+
</li>
1030+
</ul>
1031+
</div>
9431032
</div>
9441033
</div>
9451034
<div class="sect1">
@@ -953,12 +1042,38 @@ <h2 id="paso-6-implementar-el-guardado-en-la-base-de-datos"><a class="anchor" hr
9531042
<div class="title">quotes_form.ex</div>
9541043
<div class="content">
9551044
<pre class="highlightjs highlight"><code class="language-elixir hljs" data-lang="elixir">def handle_event("save", params, socket) do
956-
IO.inspect(params, label: :save)
957-
form = to_form(params)
958-
{:noreply,
959-
socket
960-
|&gt; assign(form: form)
961-
}
1045+
changeset =
1046+
Quote.new(params)
1047+
1048+
form = to_form(params, errors: changeset.errors)
1049+
1050+
Logger.debug(changeset)
1051+
Logger.debug(form)
1052+
1053+
socket =
1054+
case changeset.valid? do
1055+
true -&gt;
1056+
case Quotes.create_quote(params) do
1057+
{:ok, result} -&gt;
1058+
Logger.debug(result)
1059+
1060+
socket
1061+
|&gt; assign(form: empty_form())
1062+
|&gt; put_flash(:info, "Created new Quote")
1063+
1064+
error -&gt;
1065+
socket
1066+
|&gt; assign(form: form)
1067+
|&gt; put_flash(:error, "There was an error saving the Quote")
1068+
end
1069+
1070+
false -&gt;
1071+
socket
1072+
|&gt; assign(form: form)
1073+
|&gt; put_flash(:error, "There was an error saving the Quote")
1074+
end
1075+
1076+
{:noreply, socket}
9621077
end</code></pre>
9631078
</div>
9641079
</div>

docs/jobs/_images/fullstack.jpg

-56.4 KB
Binary file not shown.

docs/jobs/_images/mshaped.png

-147 KB
Binary file not shown.

docs/jobs/_images/tshaped.jpg

-42.5 KB
Binary file not shown.

0 commit comments

Comments
 (0)