Form helper - syntax change

Hi,

I was going to ruse some of my code from one of the 1.3 apps and in my 2.3 app and the form block style is apparently not supported anymore. This, for example returns undefined method div:

div class: "my-class" do

end

Will this be supported in the future again?

This looks a lot like Phlex. While there isn’t an official way to integrate Phlex with Hanami views at the moment, few people (including me) were interested in this. So I think we will get there eventually.

It was supported in 1.3, it’s still in the docs: V1.3: Forms | Hanami Guides.

Also, the select is behaving strange as well. I have this code:

<div class: "form-field2">
  <%= f.label "Active?", for: :active %>
  <%= f.select :active, active_switch, options: {selected: company.active}, class: "form-input" %>
</div>

And the value doesn’t get selected (worked in 1.3), there’s no code error output and the generated html is:

<div class: "form-field2">
  <label for="company-active">Active?</label> <select name="company[active]" id="company-active" class="form-input"><option>0</option><option>1</option></select>
</div>

Yes, it was Hanami::Helpers if I’m not mistaken, but it has been discontinued. However, looking at new Hanami::View, I found TagHelper, so perhaps this would work?

tag.div class: "my-class" do

end

Ah, yes. That works. Thank you!

Still, this is my oversimplified edit form and the only thing getting parsed is the Update button:

<%= 
  form_for :company, "/companies/#{company.id}", method: :patch, id: "xtube-companies-edit", values: {company: company} do |f| 

    tag.div class: "my-top-class" do
        f.label "Name", for: :name
        f.text_field :name, class: "xtube-form-input"
    end

    tag.div class: "my-top-class" do
      f.submit "Update", class: "xtube-form-button-submit"
    end
  end
%>

You’ll want to format it like this:

<%= form_for :company, "/companies/#{company.id}", method: :patch, id: "xtube-companies-edit", values: {company: company} do |f| %>
  <%= tag.div class: "my-top-class" do %>
    <%= f.label "Name", for: :name %>
    <%= f.text_field :name, class: "xtube-form-input" %>
  <% end %>

  <%= tag.div class: "my-top-class" do %>
    <%= f.submit "Update", class: "xtube-form-button-submit" %>
  <% end %>
<% end %>

The old Hanami 1 approach of ā€œeverything in a single blockā€ was taken because of limitations in the ERB rendering at the time. There was no way to capture literal template strings inside Ruby blocks, like this:

<%= form_for :company, "..." %>
  <h1>This is my cool form</h1>
<% end %>

But with Hanami 2, now you can! So this is why we’ve adopted this more conventional approach to our form helpers.

This also means you can replace your tag.div helper calls with literal <div> elements, if you prefer.

Hi @timriley,

I see the difference. Given the change I’m probably just go with the <div> syntax.

If I may, I’d repeat the question here, since it seems related, but I’m not sure if it’s about the parser or anything else. I have the select like this:

<div class: "xtube-form-row">
  <div class: "xtube-form-field2">
    <%= f.label "Active?", for: :active %>
    <%= f.select :active, active_switch, options: {selected: company.active}, class: "xtube-form-input" %>
  </div>
</div>

and the output in source code:

<div class: "xtube-form-row">
  <div class: "xtube-form-field2">
    <label for="company-active">Active?</label>
    <select name="company[active]" id="company-active" class="xtube-form-input"><option>0</option><option>1</option></select>
  </div>
</div>

I don’t get any errors, but the selected option is not set. The value company.active is available in the form.

This one is on me, active_switch was a simple array instead of nested arrays.

1 Like