Looking for a basic form example

I know JS and I just want to create a basic form, submit the data and log it to the console in a phoenix app. I assume that when I submit data in a form it goes to a controller.

Here is my controller:

defmodule AppWeb.PageController do
  use AppWeb, :controller

  def index(conn, _params) do
    render(conn, "index.html")
  end
    
  
end

Here is my form:

 <form>
            <input type="text" name="">
            <input type="submit" name="">
</form>

In the phoenix documentation I tried to mull through this confusing nonsense and I couldn’t figure it out: Phoenix.HTML.Form — Phoenix.HTML v3.2.0

I don’t want to submit to a database yet, I just want to do a basic submission log so I can see how the parts fit. If I could see an example it would be helpful. The phoenix documentation is just gobble goop to me.

:wave:

Maybe try something like this:

<form action="/">
  <input type="text" name="text">
  <input type="submit">
</form>
def index(conn, params) do
  IO.inspect(params, label: "params")
  render(conn, "index.html")
end
1 Like

In node.js (for example) using express I can do this:

app.get("/register", (req, res) => {
    console.log("Hello world the event worked! when the submit button was clicked")
})
<form action="/register" method="GET">
<input class="btn register-button" type="submit ">
</form>

I just want to see a basic equivalent with Phoenix.

Can you clarify which version of Phoenix specifically? I can give you a quick example, but it changes a bit from 0.7 a fair bit.

Provided that your setup is a basic application with no Ecto backing it, this will be the set of changes that you’ll need to introduce in Phoenix 1.6.x

  1. Create our new controller for GET and POST routes:
# lib/example_web/controller/register_controller.ex
defmodule ExampleWeb.RegisterController do
  use ExampleWeb, :controller

  def index(conn, _params) do
    # While your NodeJS version is simple, it is vulnerable to
    # CSRF attacks. You should use the Phoenix forms that handle
    # this for you.
    # This is enforced by the `:protect_from_forgery` plug
    # defined in our router

    csrf_token = Plug.CSRFProtection.get_csrf_token()
    render(conn, "form.html", [csrf_token: csrf_token])
  end

  def register(conn, params) do
    # %{"example" => "User provided value", "_csrf_token" => "token_value"}
    IO.inspect(params, label: "Form params")
    redirect(conn, to: "/register")
  end
end
  1. Create out view module. Our view module could be used to expose shared logic in our templates:
# lib/example_web/views/register_view.ex
defmodule ExampleWeb.RegisterView do
  use ExampleWeb, :view
end
  1. Add our template:
# lib/example_web/templates/register/form.html.heex
<form method="POST" action="/register">
  <input type="hidden" name="_csrf_token" value={@csrf_token} />
  <input type="text" name="example" />
  <input type="submit">
</form>
  1. Finally, wire it up in our router:
# lib/example_web/router.ex
defmodule ExampleWeb.Router do
  use ExampleWeb, :router

  pipeline :browser do
    plug :accepts, ["html"]
    plug :fetch_session
    plug :fetch_live_flash
    plug :put_root_layout, {ExampleWeb.LayoutView, :root}
    plug :protect_from_forgery
    plug :put_secure_browser_headers
  end

  scope "/", ExampleWeb do
    pipe_through :browser

    get "/", PageController, :index
    get "/register", RegisterController, :index # To view the form
    post "/register", RegisterController, :register # To submit the form
  end
end

I know there’s a lot more here that your NodeJS example. In your example, the templating part is completely omitted and doesn’t include CSRF attack prevention. It might seem like a lot of ceremony in comparison, but keep in mind that Express isn’t a full stack web framework and Phoenix is. A majority of NodeJS full stack frameworks (e.g. NestJS) have this sort of rigmarole.

4 Likes

Thanks a million. This is perfect. I just needed something working so I can get the ball rolling and see how the parts fit past all the jargon.

I appreciate it! So much simpler

1 Like