pantographe / view_component-form

Rails FormBuilder for ViewComponent
MIT License
204 stars 16 forks source link

Docs: Example for wrapping input in div #154

Closed stebo closed 10 months ago

stebo commented 10 months ago

First off, thanks a lot for providing this awesome gem, exactly what I was looking for!

In the readme it says

You can use the same approach to inject options, wrap the input in a div etc.

But I am not sure how to accomplish this - would you create a text_field_component.html.erb file for this, or take care of that in text_field_component.rb - what's the best practise way?

Maybe you can help out with a short example for these classical cases where some div should be wrapped around the input or an icon can be optionally but before/after the input.

Thanks a lot!

Spone commented 10 months ago

Hi @stebo, I agree we could elaborate a bit more on this.

(edited for clarity)

First, follow the steps described in the README:

# app/helpers/custom_form_builder.rb
class CustomFormBuilder < ViewComponent::Form::Builder
  # Set the namespace you want to use for your own components
  namespace "Custom::Form"
end
- <%= form_for @user do |f| %>
+ <%= form_for @user, builder: CustomFormBuilder do |f| %>
bin/rails generate component Custom::Form::TextField --inline --parent ViewComponent::Form::TextFieldComponent

Then, here is how you could wrap the input in a div:

# app/components/custom/form/text_field_component.rb
class Custom::Form::TextFieldComponent < ViewComponent::Form::TextFieldComponent
  def call
    content_tag :div, super, class: "custom-form-wrapper"
  end
end

or with inline templates:

# app/components/custom/form/text_field_component.rb
class Custom::Form::TextFieldComponent < ViewComponent::Form::TextFieldComponent
  erb_template <<~ERB
    <div class="custom-form-wrapper">
      <%= render_parent_to_string %>
    </div>
  ERB
end

If you prefer, you can do this in a sibling template file:

# app/components/custom/form/text_field_component.rb
class Custom::Form::TextFieldComponent < ViewComponent::Form::TextFieldComponent
end
# app/components/custom/form/text_field_component.html.erb
<div class="custom-form-wrapper">
  <%= render_parent_to_string %>
</div>

Let me know if it's clearer :)

stebo commented 10 months ago

Thanks a lot for the information, overwriting the call function was what I was missing - but I went with a sibling template file now which gives a bit more freedom for complex templates :)

Thanks also for noting render_parent_to_string which works very well!