Shared Phoenix form f function undefined

I want to create a shared Phoenix form fragment and am having trouble with the f function not passing to the fragment.

Standard generated form.html.eex

  <div class="field">
      <%= label f, :a_field, class: "label" %>
      <%= date_input f, :a_field %>
      <%= error_tag f, :a_field %>
  </div>

when I move the above fragment into <%= render(WwwFolkbotCom.Web.SharedView, "_users.html", assigns) %> I get

CompileError

lib/www_app_web/templates/shared/_users.html.eex:2: undefined function f/0

Console output is shown below.

how do I pass the form anonymous function to the form fragment?

Why do You think f is in the assigns?

Maybe like this…

<%= render(WwwFolkbotCom.Web.SharedView, "_users.html", f: f) %>

# in the partial

<div class="field">
      <%= label @f, :a_field, class: "label" %>
      <%= date_input @f, :a_field %>
      <%= error_tag @f, :a_field %>
</div>

BTW it’s totally optional to start partial’s name with an underscore. We are not in Rails world :slight_smile:

2 Likes

Thanks, the @f works!

Thanks for the tip on the _partial.html.eex. I use it for visual aid as much as anything.

followup question

If my fragment looks like this

<%= if @current_user != nil and @current_user.role_id == 1 do %>
<div class="field">
    <%= label @f, :user_id, "User", class: "label" %>
    <div class="control">
                    <span class="select is-danger">
                      <%= select @f, :user_id, users_for_select(@users) %>
                    </span>
    </div>
    <%= error_tag @f, :user_id %>
</div>
<% else %>
        <%= hidden_input @f, :user_id %>
<% end %>

what should <%= render(WwwFolkbotCom.Web.SharedView, "_users.html", f: f) %> look like?

You need those parameters to be passed to partial.

f: f, current_user: @current_user, users: @users

1 Like

thanks, that works, Happy New Year!

how about inputs_for as a fragment?

_entity.html.eex

<%= inputs_for @f, :entity, fn @ef -> %>
    <div class="form-group">
        <%= label @ef, :is_premium, class: "control-label" %>
        <%= checkbox @ef, :is_premium %>
        <%= error_tag @ef, :is_premium %>
    </div>
<% end %>

include

<%= render(WwwMyApp.Web.SharedView, "_entity.html", f: f, ef: ef) %>

gives error

CompileError
lib/www_myapp_com_web/templates/thing/property/form.html.eex:107: undefined function ef/0
Console output is shown below.
==> www_myapp_com_web
Compiling 101 files (.ex)

== Compilation error in file lib/www_myapp_com_web/views/property_view.ex ==
** (CompileError) lib/www_myapp_com_web/templates/thing/property/form.html.eex:107: undefined function ef/0
    (elixir 1.10.2) src/elixir_locals.erl:114: anonymous fn/3 in :elixir_locals.ensure_no_undefined_local/3
    (stdlib 3.12.1) erl_eval.erl:680: :erl_eval.do_apply/6
    (elixir 1.10.2) lib/kernel/parallel_compiler.ex:304: anonymous fn/4 in Kernel.ParallelCompiler.spawn_workers/7

this works


<%= inputs_for @f, :entity, fn ef -> %>
    <div class="form-group">
        <%= label ef, :is_premium, class: "control-label" %>
        <%= checkbox ef, :is_premium %>
        <%= error_tag ef, :is_premium %>
    </div>
<% end %>

include

<%= render(WwwMyApp.Web.SharedView, "_entity.html", f: f) %>

imho, practical examples like this should be in the docs, took a few hours searching and then Q&A to get to this

big ups to kokolegorille

1 Like