3

I have a ActiveModel in my model like below:

class PromotionCodesGenerator
  include ActiveModel::Model
  include ActiveModel::Validations

  attr_accessor :no_of_codes,:start_date,:end_date
end

And the view like below

<%= simple_nested_form_for ([:admin, @promotion_codes_generator]) do |f| %>
      <%= f.input :start_date, as: :date, default: Time.zone.now, wrapper_tag: :p %>
      <%= f.input :end_date, as: :date, default: Time.zone.now + 1.month, wrapper_tag: :p %>
<% end %>

When the form is submitted the param looks like this

{"no_of_codes"=>"12", "start_date(1i)"=>"2016", "start_date(2i)"=>"12", "start_date(3i)"=>"15", "end_date(1i)"=>"2017", "end_date(2i)"=>"1", "end_date(3i)"=>"15"}

And of course this gives me error

undefined method `start_date(1i)=' 

when im trying to initiate the model in my controller.

@promotion_codes_generator = PromotionCodesGenerator.new(promotion_codes_generator_params)

So how should i handle the dates properly?

Fandy Dharmawan
  • 328
  • 4
  • 13

3 Answers3

0

Try replacing as: :date with as: :string

<%= f.input :start_date, as: :string, default: Time.zone.now, wrapper_tag: :p %>
<%= f.input :end_date, as: :string, default: Time.zone.now + 1.month, wrapper_tag: :p %>
Jagdeep Singh
  • 4,880
  • 2
  • 17
  • 22
0

You can use a gem called multiparameter_attributes_handler. If you apply it to params it will create entries for end_date and start_date with date objects constructed from the form element submissions. That will allow you to keep the rails helper date form drop-downs.

ReggieB
  • 8,100
  • 3
  • 38
  • 46
0

I use JQuery date-pickers in conjunction with simple form custom inputs. Doing it this way is especially helpful if you want to display American formatted time (mm/dd/yyyy), but submit the fields in the rails format (yyyy-mm-dd) through the alt_field. If you want to do this, first make sure you have the jquery-rails gem installed.

Create the custom simple form input for dates in app/inputs/datepicker_input.rb :

class DatepickerInput < SimpleForm::Inputs::StringInput
   def input(wrapper_options)
      merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)
      class_name = object.class.name.underscore + "_"
      "#{@builder.text_field(attribute_name, merged_input_options)}".html_safe +
      "#{@builder.hidden_field(attribute_name, { id: class_name + attribute_name.to_s + '-alt'}) }".html_safe
   end
end

This custom input creates a text field to display the formatted date to the user, and a hidden field to be submitted in place of the the displayed text field. The hidden field is given and id of the class_name + attribute_name + -alt. This id will be used in the JQuery date-picker initialization to specify the hidden field.

In your form simply change "as: :date" to "as: :datepicker":

<%= simple_nested_form_for ([:admin, @promotion_codes_generator]) do |f| %>
      <%= f.input :start_date, as: :datepicker, default: Time.zone.now, wrapper_tag: :p %>
      <%= f.input :end_date, as: :datepicker, default: Time.zone.now + 1.month, wrapper_tag: :p %>
<% end %>

In your javascript:

$("#admin_start_date").datepicker({
  dateFormat: "mm/dd/yy",
  altFormat: "yy-mm-dd",
  altField: $("#admin_start_date-alt")
});

$("#admin_end_date").datepicker({
  dateFormat: "mm/dd/yy",
  altFormat: "yy-mm-dd",
  altField: $("#admin_end_date-alt")
});

The altField with a format of "yy-mm-dd" will be submitted in place of the displayed "mm/dd/yy" field. In your controller simply permit you the params start_date and end_date inside of you object as you already do.

jlesse
  • 564
  • 5
  • 11