Thomas Klemm
Thomas Klemm

Reputation: 10856

Custom form tag / form field in Rails

I'm looking for a way to add a custom form tag / field type to the default Rails form builder. I'm looking for a way to do this without defining a custom form builder (as described here in the Rails guides.

# form
= form_for @event do |f|
  = f.label :start_date
  = f.my_date_select :start_date

# custom my_date_select form tag method
# this doesn't work yet!
class ActionView::Helpers::FormBuilder
  def my_date_select(*args)
    date_select(*args)
  end
end

The reason behind this custom form tag would be that I'd like to DRY up some markup across the forms that is formed in a specific way to work with a date select jquery plugin.

# repeated across a few forms right now
= form_for @event do |f|
  .field
    = f.label :date
    .input-group
      span class='input-group-addon' = icon_tag(:calendar)
      = f.text_field :date, value: @event.date

Thanks for any hints, solutions, articles!

Upvotes: 1

Views: 904

Answers (1)

RobHeaton
RobHeaton

Reputation: 1390

From my experience this is the wrong way to go about DRY-ing up your code. When I do this kind of stuff my wrapper function always ends up spiralling out of control. At the moment you only really want to DRY up the value attribute of the text_field, but what if you want to also wrap the class of the input? And what if the rules for DRY-ing up the value and the class start to only apply in special situations and you have to start passing in flags and/or doing some weird, opaque logic inside your wrapper function that is suddenly very hard for an outsider to understand?

So for now I would suggest that you focus on DRYing things up at a different level - either higher or lower. To wrap things at a higher level (ideal if possible) you could obviously just use a partial and pass in the event. To wrap at a lower level you could just DRY each individual piece of logic. So you could use a decorator on the event and do something like:

= f.text_field :date, value: @event.decorate.date_string

Upvotes: 1

Related Questions