@@ -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 "> |> assign(form: to_form(%{"author" => nil, "source" => nil, "quote" => nil}))</ code > </ pre >
678+ < pre class ="highlightjs highlight "> < code class ="language-elixir hljs " data-lang ="elixir "> defp empty_form() do
679+ to_form(%{"author" => "", "quote" => "", "source" => ""})
680+ end
681+
682+ def mount(_params, _session, socket) do
683+ {:ok,
684+ socket
685+ |> assign(alert: nil)
686+ |> 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" => "", "quote" => "", "source" => ""})
727+ end
728+
716729 def mount(_params, _session, socket) do
717730 {:ok,
718731 socket
719732 |> assign(alert: nil)
720- |> assign(form: to_form(%{"author" => nil, "source" => nil, "quote" => nil}))
721- }
733+ |> 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 <div class="mt-2">
853865 <.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 <div class="mt-2">
868881 <.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 <div class="mt-2">
886900 <.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
927942si 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- |> assign(form: form)
939- }
983+ socket
984+ |> assign(form: form)}
940985end</ 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+ |> cast(attrs, [:quote, :author, :source])
1011+ |> validate_required([:quote, :author, :source])
1012+ |> unique_constraint(:quote, name: :index_for_duplicate_quotes)
1013+ end
1014+
1015+ @doc false
1016+ def new(attrs \\ %{"author" => "", "quote" => "", "source" => ""}) 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- |> 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 ->
1056+ case Quotes.create_quote(params) do
1057+ {:ok, result} ->
1058+ Logger.debug(result)
1059+
1060+ socket
1061+ |> assign(form: empty_form())
1062+ |> put_flash(:info, "Created new Quote")
1063+
1064+ error ->
1065+ socket
1066+ |> assign(form: form)
1067+ |> put_flash(:error, "There was an error saving the Quote")
1068+ end
1069+
1070+ false ->
1071+ socket
1072+ |> assign(form: form)
1073+ |> put_flash(:error, "There was an error saving the Quote")
1074+ end
1075+
1076+ {:noreply, socket}
9621077end</ code > </ pre >
9631078</ div >
9641079</ div >
0 commit comments