Nicolas

Nicolas

Form validation with LiveView / Surface

Hi,
Looking at LiveView and Surface examples I created a first test Component to a Login form (code below).

It appears that this code fails with the following error:

** (exit) an exception was raised:
    ** (ArgumentError) argument error
        :erlang.atom_to_binary("email", :utf8)
        (phoenix_ecto 4.2.1) lib/phoenix_ecto/html.ex:111: Phoenix.HTML.FormData.Ecto.Changeset.input_value/4
        (phoenix_html 2.14.3) lib/phoenix_html/form.ex:482: Phoenix.HTML.Form.input_value/2
        (phoenix_html 2.14.3) lib/phoenix_html/form.ex:825: Phoenix.HTML.Form.generic_input/4
        (surface 0.4.0) lib/surface/components/form/email_input.ex:31: anonymous fn/7 in Surface.Components.Form.EmailInput.render/1
        (phoenix_live_view 0.15.5) lib/phoenix_live_view/diff.ex:356: Phoenix.LiveView.Diff.traverse/6

I’m not used with forms validation using changeset. Can someone help me with this one ?

defmodule ScubananaWeb.Components.LoginForm do
  defmodule FormData do
    use Ecto.Schema
    import Ecto.Changeset

    @primary_key false
    embedded_schema do
      field :email, :string
      field :password, :string
    end

    def changeset(form_data, attrs \\ %{}) do
      form_data
      |> cast(attrs, [:email, :password])
      |> validate_required([:email, :password])
      |> validate_email()
    end

    defp validate_email(changeset) do
      changeset
      |> validate_format(:email, ~r/^[^\s]+@[^\s]+$/,
        message: "must have the @ sign and no spaces"
      )
      |> validate_length(:email, max: 160)
    end

    def validate(params) do
      %FormData{}
      |> changeset(params)
      |> Map.put(:action, :insert)
    end
  end

  defmodule Component do
    use Surface.LiveComponent

    alias Surface.Components.Form
    alias Surface.Components.Form.{Field, Label, EmailInput, PasswordInput}

    data changeset, :changeset, default: FormData.changeset(%FormData{})
    prop submit, :event

    def render(assigns) do
      IO.inspect(assigns.changeset)

      ~H"""
      <Form for={{ @changeset }} change="validate" submit={{ @submit }}>
        <Field name="email" class="form-control w-1/2">
          <Label class="label"><span class="label-text">Email</span></Label>
          <EmailInput class="input input-bordered flex-grow"/>
        </Field>
        <Field name="password" class="form-control w-1/2">
          <Label class="label"><span class="label-text">Password</span></Label>
          <PasswordInput class="input input-bordered flex-grow"/>
        </Field>
        <div class="card-actions w-1/2 mt-4">
          <button type="submit" class="btn btn-primary flex-grow">Login</button>
        </div>

      </Form>
      """
    end

    def handle_event("validate", params, socket) do
      {:noreply, assign(socket, changeset: FormData.validate(params))}
    end
  end
end

Marked As Solved

miguels

miguels

Hi @Nicolas!

When using changesets with your form you need to pass atoms as your field names.

Could you try following and let me know if that fixes your issue?

  1. Change <Field name="email" class="form-control w-1/2"> to <Field name={{ :email }} class="form-control w-1/2">
  2. Change <Field name="password" class="form-control w-1/2"> to <Field name={{ :password }} class="form-control w-1/2">

Where Next?

Popular in Questions Top

marius95
Hello everyone, I try to use an Javascript Event Handler in my root.html.leex file. Therefore I created a function in the app.js file: ...
New
_russellb
I want to try my hand at web scraping. What tools/libraries do I need to use. I’m hoping to turn this into something professional so don’...
New
qwerescape
Is there a way to get the call stack or stack trace at any point in the code? Not from exceptions, but an expression that returns how the...
New
fireproofsocks
I’m working on defining a simple Ecto schema for a table (in PostGres), but I don’t see where I can define a column as NOT NULL. Conside...
New
tduccuong
Hi, is there any work on GUI with Elixir, that is similar to Electron/Javascript? My idea is to bundle Phoenix and BEAM into a single se...
New
jononomo
I am trying to figure out how Mix knows whether the environment is test, dev, or prod – where is this set? Thanks.
New
dokuzbir
I want to highlight html closing tags when i click a html tag. That works in .html files but doesnt work for html.eex templates. How can...
New
vonH
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
PeterCarter
There are pre-rolled solutions for other frameworks that do work. However, Phoenix does not seem to have these. Have people had good expe...
New

Other popular topics Top

aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
marius95
Hello everyone, I try to use an Javascript Event Handler in my root.html.leex file. Therefore I created a function in the app.js file: ...
New
Nvim
Anybody knows a comprehensive comparison of Django and Phoenix, thanks for the help. Where are they similar? Where do they differ the m...
New
fireproofsocks
Forgive me if this is obvious, but how does one delete a database record WITHOUT selecting it first? Ecto.Repo — Ecto v3.14.0 has exampl...
New
jay1
Why is it that the mnesia database isn’t the most preferred database for use in Elixir/Phoenix?
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
RisingFromAshes
I’ve read in another post that it may be possible with a router helper - but I couldn’t find an appropriate one, and tbh, I’m still just ...
New
jason.o
In the code below, if the create action is not set to accept “extra_key” as an input, it errors out with a message shown above. Is there ...
New
dblack
I’ve got an issue with an app and I’ve no idea of how to troubleshoot it. I’m hoping someone here might have seen something similar. I p...
New
svb
Hi! Currently I want to submit a form by pressing the Enter key. However, since my input field is of type “textarea” this is just adds a...
New

We're in Beta

About us Mission Statement