Skip to content

Commit

Permalink
fix: Wip 5.0 readme section. #54
Browse files Browse the repository at this point in the history
  • Loading branch information
LuchoTurtle committed Dec 6, 2022
1 parent 2f880b8 commit d277c82
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 42 deletions.
87 changes: 66 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -749,38 +749,83 @@ http://localhost:4000/items/new
We want the person to be able to create a new item
without having to navigate to a different page.
In order to achieve that goal,
we will include the `form.html` template (_partial_)
inside the `index.html` template. e.g:

```elixir
<%= render "form.html", Map.put(assigns, :action, Routes.item_path(@conn, :create)) %>
```

Before we can do that, we need to tidy up the `form.html`
we will include the
`lib/app_web/controllers/item_html/new.html.heex`
template (_partial_)
inside the
`lib/app_web/controllers/item_html/index.html.heex`
template. e.g:

Before we can do that, we need to tidy up the `new.html.heex`
template to remove the fields we don't _need_.

Let's open `lib/app_web/templates/item/form.html.eex`
Let's open `lib/app_web/controllers/item_html/new.html.heex`
and simplify it to just the essential field `:text`:

```elixir
<%= form_for @changeset, @action, fn f -> %>
<%= text_input f, :text, placeholder: "what needs to be done?",
class: "new-todo", autofocus: "" %>
<div style="display: none;"> <%= submit "Save" %> </div>
<% end %>
<.simple_form :let={f} for={@changeset} action={~p"/items"}>
<.input
field={{f, :text}}
type="text"
placeholder="what needs to be done?"
/>
<:actions>
<.button style="display:none">Save Item</.button>
</:actions>
</.simple_form>
```

> Before:
[`/lib/app_web/templates/item/form.html.eex`](https://github.com/dwyl/phoenix-todo-list-tutorial/blob/cc287975eef5ca8b738f49723fe8a03d9da52a19/lib/app_web/templates/item/form.html.eex) <br />
> After:
[`/lib/app_web/templates/item/form.html.eex#L2-L3`](https://github.com/dwyl/phoenix-todo-list-tutorial/blob/50a6f9ab9e2cb7d9ed3023fc64590992a2ee73af/lib/app_web/templates/item/form.html.eex#L2-L3)

We need to additionally
change the style of the `<.input>` tag.
With Phoenix, inside the
`lib/app_web/components/core_components.ex` file,
the styles are defined for pre-built components
(which is the case with `<.input>`).

To change this so it uses the same style as TodoMVC,
locate the following line.

```elixir
def input(assigns) do
```

Change the class attribute
with the `new-todo` class.
This function should look like the following.

```elixir
def input(assigns) do
~H"""
<div phx-feedback-for={@name}>
<.label for={@id}><%= @label %></.label>
<input
type={@type}
name={@name}
id={@id || @name}
value={@value}
class={[
input_border(@errors),
"new-todo"
]}
{@rest}
/>
<.error :for={msg <- @errors}><%= msg %></.error>
</div>
"""
end
```


If you run the Phoenix App now and visit
[http://localhost:4000/items/new](http://localhost:4000/items/new)
you will see the _single_ `:text` input field and no "Save" button:

![new-item-single-text-field-no-save-button](https://user-images.githubusercontent.com/194400/82753057-a7a04d80-9dba-11ea-9a08-3d904702e1e8.png)
![new-item-single-text-field-no-save-button](https://user-images.githubusercontent.com/17494745/205731473-4a9ce3b2-c902-4b66-9bdc-e64165f22841.png)

Don't worry, you can still submit the form with <kbd>Enter</kbd> (Return) key.
However if you attempt to submit the form now,
Expand All @@ -791,7 +836,7 @@ Let's fix that.
### 5.1 Update the `items` Schema to Set `default` Values

Given that we have removed two of the fields (`:person_id` and `:status`)
from the `form.html.eex`,
from the `new.html.eex`,
we need to ensure there are default values for these in
the schema.
Open the `lib/app/todo/item.ex` file
Expand Down Expand Up @@ -839,7 +884,7 @@ if you submit the `/items/new` form it will succeed.

### 5.2 Update `index/2` in `ItemController`

In order to in-line the new item form (`form.html.eex`)
In order to in-line the new item form (`new.html.eex`)
in the `index.html.eex` template,
we need to update the `AppWeb.ItemController.index/2`
to include a Changeset.
Expand All @@ -865,14 +910,14 @@ You will not _see_ any change in the UI or tests after this step.
Just move on to 5.3 where the "aha" moment happens.


### 5.3 Render The `form.html.eex` inside `index.html.eex`
### 5.3 Render The `new.html.eex` inside `index.html.eex`

Now that we have done all the preparation work,
the next step is to render the `form.html.eex` (_partial_)
the next step is to render the `new.html.eex` (_partial_)
inside `index.html.eex` template.

Open the `lib/app_web/templates/item/index.html.eex` file
and locate the line:
Open the `lib/app_web/controllers/item_html/index.html.heex`
file and locate the line:

```html
<input class="new-todo" placeholder="What needs to be done?" autofocus="">
Expand Down
6 changes: 3 additions & 3 deletions app/lib/app/todo/item.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ defmodule App.Todo.Item do
import Ecto.Changeset

schema "items" do
field :person_id, :integer
field :status, :integer
field :person_id, :integer, default: 0
field :status, :integer, default: 0
field :text, :string

timestamps()
Expand All @@ -14,6 +14,6 @@ defmodule App.Todo.Item do
def changeset(item, attrs) do
item
|> cast(attrs, [:text, :person_id, :status])
|> validate_required([:text, :person_id, :status])
|> validate_required([:text])
end
end
4 changes: 1 addition & 3 deletions app/lib/app_web/components/core_components.ex
Original file line number Diff line number Diff line change
Expand Up @@ -348,9 +348,7 @@ defmodule AppWeb.CoreComponents do
value={@value}
class={[
input_border(@errors),
"mt-2 block w-full rounded-lg border-zinc-300 py-[7px] px-[11px]",
"text-zinc-900 focus:outline-none focus:ring-4 sm:text-sm sm:leading-6",
"phx-no-feedback:border-zinc-300 phx-no-feedback:focus:border-zinc-400 phx-no-feedback:focus:ring-zinc-800/5"
"new-todo"
]}
{@rest}
/>
Expand Down
3 changes: 2 additions & 1 deletion app/lib/app_web/controllers/item_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ defmodule AppWeb.ItemController do

def index(conn, _params) do
items = Todo.list_items()
render(conn, :index, items: items)
changeset = Todo.change_item(%Item{})
render(conn, "index.html", items: items, changeset: changeset)
end

def new(conn, _params) do
Expand Down
1 change: 1 addition & 0 deletions app/lib/app_web/controllers/item_html/index.html.heex
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
<section class="todoapp">
<header class="header">
<h1>todos</h1>
<!-- I want to embed it here -->
<input class="new-todo" placeholder="What needs to be done?" autofocus="" />
</header>
<section class="main" style="display: block;">
Expand Down
20 changes: 6 additions & 14 deletions app/lib/app_web/controllers/item_html/new.html.heex
Original file line number Diff line number Diff line change
@@ -1,18 +1,10 @@
<.header>
New Item
<:subtitle>Use this form to manage item records in your database.</:subtitle>
</.header>

<.simple_form :let={f} for={@changeset} action={~p"/items"}>
<.error :if={@changeset.action}>
Oops, something went wrong! Please check the errors below.
</.error>
<.input field={{f, :text}} type="text" label="text" />
<.input field={{f, :person_id}} type="number" label="person_id" />
<.input field={{f, :status}} type="number" label="status" />
<.input
field={{f, :text}}
type="text"
placeholder="what needs to be done?"
/>
<:actions>
<.button>Save Item</.button>
<.button style="display:none">Save Item</.button>
</:actions>
</.simple_form>

<.back navigate={~p"/items"}>Back to items</.back>

0 comments on commit d277c82

Please sign in to comment.