pantographe / view_component-form

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

SimpleForm Support #125

Closed jonsgreen closed 1 year ago

jonsgreen commented 2 years ago

I have just started exploring using this gem in a new project and so far I am really appreciating what it offers. While trying to decide how to approach forms with ViewComponents I stumbled upon your gem in discussions like this one but I also ran into this thoughtful post that chose to stick with simple_form. I have decided so far to attempt to keep all my components using ViewComponents and I believe your gem will be essential to helping make that possible.

However, I have appreciated using simple_form in the past and I can see why the author of that post decided to stick with it. I am therefore curious if perhaps the best of both worlds could not be possible? Right now your ViewComponent::Form::Builder inherits fromActionView::Helpers::FormBuilderbut I am finding that if I switch that toSimpleForm::Builder` then I appear to be able to use the SimpleForm DSL but still have my form components be utilized. I have definitely not explored this thoroughly but it at least worked for a simple text_field as a proof of concept.

I am guessing that this might just be too much to ask for due to complexity and extra dependencies but I am curious what the maintainers of this gem think of this crazy idea and whether in general you have considered the whole SimpleForm vs ViewComponents dilemma before. Injecting a class to inherit from might not be wise but perhaps there is a way to extract the code it contains into a module that it then includes so that one could have a different way of composing this functionality into another builder.

nicolas-brousse commented 1 year ago

Hi! First, sorry for our late answer and thanks for your message 🙂

Since it's already a bit hard for us to spend more time for the bases of this gem we will not plan to do a complete support for SimpleForm. Maybe later. But maybe we could think about moving code of our ViewComponent::Form::Builder in a module to include. So you will be able to include it in your custom FormBuilder that will extend SimpleForm::FromBuilder instead ActionView::Helpers::FormBuilder.

Would this help you?

jonsgreen commented 1 year ago

@nicolas-brousse Thanks for responding! I had the same idea of making it more of a module approach rather than inheritance.

In the end though I created my own little input helper that is kind of like a home baked SimpleForm and I love it and not sure I would go back now.

This really is a great gem and it has been super helpful for me in getting our new project set up using ViewComponent with forms. I really should do a blog post sometime about it and we should all talk it up!

One thing though is that I kind of had to figure out for myself how to make my InputComponent work. I am not sure whether I did it in the expected way but I could not find anything in the documentation though there are references to GroupComponent that I was inspired by.

Here is what I did:

# app/lib/gto_form_builder.rb

class GtoFormBuilder < ViewComponent::Form::Builder
  # Set the namespace you want to use for your own components
  namespace 'Form'

  def input(method, options = {})
    render_component(:input, @object_name, method, objectify_options(options))
  end
end

# app/components/form/input_component.rb

module Form
  class InputComponent < ViewComponent::Form::FieldComponent
    def initialize(form, object_name, method_name, options = {})
      super
      @hide_label = @options.delete(:hide_label)
      @field_type = "#{@options.delete(:as)&.to_s || 'text'}_field"
      @text_options = (@options.delete(:text_options) || {}).merge(@options.except(:required))
    end

    def form_field
      form.public_send(@field_type, @method_name, @text_options)
    end
  end
end

# app/components/form/input_component/input_component.html.erb

<div class="flex flex-col flex-grow h-full" id="<%= dom_id(form.object, @method_name) %>">
  <div>
    <%= form.label(@method_name, @method_name.titleize, @options) unless @hide_label %>
  </div>
  <%= form_field %>
  <%= form.error_message @method_name %>
</div>

You might get the sense that it is still evolving and could use some cleaning up. I am curious if you have any thoughts, suggestions or impressions.

Spone commented 1 year ago

But maybe we could think about moving code of our ViewComponent::Form::Builder in a module to include. So you will be able to include it in your custom FormBuilder that will extend SimpleForm::FromBuilder instead ActionView::Helpers::FormBuilder.

We plan to make these changes for v0.3. You can follow the progress in #127

I'll go ahead and close this issue for now. Feel free to leave a comment if you want to add something on this topic!

jonsgreen commented 1 year ago

@Spone I am really appreciating this gem on a project I am working on and would like to both learn more about the internals of this project and see if there is a way that I can contribute. Are there currently ways to get involved. My time unfortunately is limited so smaller issues or features might be best. Thanks for considering.

Spone commented 1 year ago

@jonsgreen thanks for your feedback and for offering to contribute!

Feel free to browse the issues and start working on one if you want. You can post comments in issues if you need help figuring out how to get started.

We'll soon start working on the previews for each component, we'll surely need help with this, especially since it's a large task that can be split in smaller subtasks. I'll let you know!

It would also be helpful to guide the future development of the gem, if you can describe how you're using ViewComponent::Form and if you're running into limitations with the current version.

Thanks again!