Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to fill in inputs_for #133

Open
andrewtimberlake opened this issue Oct 1, 2024 · 7 comments
Open

How to fill in inputs_for #133

andrewtimberlake opened this issue Oct 1, 2024 · 7 comments

Comments

@andrewtimberlake
Copy link

I’m not sure if there’s a better place to ask questions.
When using inputs_for for a multiple inputs where each iteration is still an open form, how do you target each input with fill_in?

Example html:

<div>
<label>Name: <input name="model[0][name]" id="model_0_name" /></label>
</div>
<div>
<label>Name: <input name="model[1][name]" id="model_1_name" /></label>
</div>
conn |> fill_in("model[0][name]", "Name", with: "John Doe")
** (ArgumentError) Found many labels with text "Name":
@germsvel
Copy link
Owner

germsvel commented Oct 1, 2024

Hmmm. That's interesting. That may be a case we missed.

@andrewtimberlake if you try the same thing but have the labels and inputs separated, does it work? I think it might have to do wih the implicit label <> input association (which we should handle)

In other words, does it work if it's like this?

<div>
<label for="model_0_name">Name:</label> <input name="model[0][name]" id="model_0_name" />
</div>
<div>
<label for="model_1_name">Name:</label> <input name="model[1][name]" id="model_1_name" />
</div>

@andrewtimberlake
Copy link
Author

They are actually separate. I’m using the <.input /> component (my example above was a simplified example using HTML as I tend to write it by hand.
The problem is that there are multiple labels with the same name

@germsvel
Copy link
Owner

germsvel commented Oct 1, 2024

That sounds like a bug in that case -- but it's weird because that's exactly what our tests are testing. I wonder if there's something odd with inputs_for.

Can you confirm you're using v0.4.0, and is there a chance you could create a simple app that reproduces the error?

@andrewtimberlake
Copy link
Author

I have created a simple app that demonstrates what I’m trying to do:
https://github.com/andrewtimberlake/phoenix_test_inputs_for
Form at http://localhost:4000/test
Test in test/phoenix_test_inputs_for_web/live/test_live_test.exs

@germsvel
Copy link
Owner

germsvel commented Oct 3, 2024

@andrewtimberlake thanks for the repo! Made it much easier to figure out.

Your test in that repo has two errors:

  1. You're using fill_in/3 with a CSS selector but no label. That doesn't work. You have to use fill_in/4 to pass in a CSS selector
  2. Your CSS selectors are invalid. The values you're passing (e.g. model[items][0][name]) are just the values of an attribute. You need to specify which attribute they belong to. So it should be stuff like [name='model[items][0][name]'] (or you could use stuff like the id with #model_items_0_name).

So, all in all, your test should look like this:

  test "add items", %{conn: conn} do
    conn
    |> visit("/test")
    |> assert_has("h1", text: "PhoenixTestInputsFor")
    |> check("add more")
    |> fill_in("[name='model[items][0][name]']", "Name", with: "Item 1")
    |> check("add more")
    |> fill_in("[name='model[items][1][name]']", "Name", with: "Item 2")
    |> check("add more")
    |> fill_in("[name='model[items][2][name]']", "Name", with: "Item 3")
    |> submit()
  end

Here's the diff:

     |> visit("/test")
     |> assert_has("h1", text: "PhoenixTestInputsFor")
     |> check("add more")
-    |> fill_in("model[items][0][name]", with: "Item 1")
+    |> fill_in("[name='model[items][0][name]']", "Name", with: "Item 1")
     |> check("add more")
-    |> fill_in("model[items][1][name]", with: "Item 2")
+    |> fill_in("[name='model[items][1][name]']", "Name", with: "Item 2")
     |> check("add more")
-    |> fill_in("model[items][2][name]", with: "Item 3")
+    |> fill_in("[name='model[items][2][name]']", "Name", with: "Item 3")
     |> submit()
   end

When I run ☝️ that, the test passes. Hope that helps!

@germsvel germsvel closed this as completed Oct 3, 2024
@andrewtimberlake
Copy link
Author

Thanks for the help.
In that same test, I used a label and a checkbox to add a new item because I couldn’t get the example from the Phoenix docs to work, how do I test with a button like this:

<button type="button" name="model[items][]" value="new" phx-click={JS.dispatch("change")}>
  add more
</button>

See: https://hexdocs.pm/phoenix_live_view/Phoenix.Component.html#inputs_for/1-dynamically-adding-and-removing-inputs

@germsvel germsvel reopened this Oct 7, 2024
@germsvel
Copy link
Owner

germsvel commented Oct 9, 2024

@andrewtimberlake any chance you could create a simple app (or modify the one you already shared) to reproduce the error you're running into?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants