2

I'm trying to render a Date field for my rails model as a datepicker.

The model looks like:

class Appointment
  include Mongoid::Document
  field :date, type: Date  
end

_form.html.haml view looks like:

= form_for @appointment, :url => {:action => :create} do |f| 
  = f.text_field(:date, {:class => 'datepicker'})
  %button{:type => 'submit'} Book appointment

:javascript
    jQuery(document).ready(function($) {
      $('.datepicker').datepicker();
    });

Controller action looks like:

class AppointmentsController < ApplicationController
  def create
    @appointment = Appointment.new(params[:appointment])

    # rest left out for demo purposes
  end
end

When "new" gets, called an error occurs:

ArgumentError in AppointmentsController#create

argument out of range

I know the value gets posted as MM/DD/YYYY, i.e. 03/11/2013

How can I tell Rails how to properly serialize this field?

Oved D
  • 7,132
  • 10
  • 47
  • 69

3 Answers3

2

I'm a little late to the party but...

Mongoid is pretty particular about the format of the string you feed it as a date. As I understand it, only dd-mm-yyyy will do. Fortunately the jQuery UI datepicker gives you the option to format its output. The format Mongoid wants would look like this:

$('.datepicker').datepicker({ dateFormat: 'dd-mm-yy' });

More info on the datepicker options and formats here:

http://api.jqueryui.com/datepicker/#option-dateFormat

Cheers!

Mishaux
  • 338
  • 2
  • 8
1

Figured it out. I added another field, date_string just as an attr_accessor that won't get stored in the db but can surface to the form, and can be used to convert to the internal date field. The model is changed to be:

class Appointment
  # extend these two to get accesss to drop down options
  include Mongoid::Document
  before_validation :parse_date_if_not_null

  #person info
  field :date, type: Date

  attr_protected :date
  attr_accessor :date_string

  def parse_date_if_not_null
    unless self.date_string.nil? || self.date_string == ''
      self.date = Date.strptime self.date_string, '%m/%d/%Y'
    end
  end
end

In the view, the date_string field is used:

= form_for @appointment, :url => {:action => :create} do |f| 
  = f.text_field(:date_field, {:class => 'datepicker'})
  %button{:type => 'submit'} Book appointment

:javascript
    jQuery(document).ready(function($) {
      $('.datepicker').datepicker();
    });

This works correctly and I've verified the field gets set in the db correctly.

Oved D
  • 7,132
  • 10
  • 47
  • 69
0

The problem is that rails/activerecord expect the date to be in ISO format 'yyyy-mm-dd'. But this not a user-friendly format

The easiest solution in my opinion is using the alt attribute on the datepicker - Basically, show a date format but submit another date format:

  = f.text_field :your_date, id: "your_date", class: "hidden" // This is hidden
  // This will show up
  = text_field_tag "date[something_we_will_not_use]", f.object.your_date.strftime("%m/%d/%Y"),
    class: "datepicker", 'data-alt-field' => '#your_date'

Datepicker initialization

$('.datepicker').each(function() {

      var alt_field = $(this).attr('data-alt-field');

      $this.datepicker({
        dateFormat: "mm/dd/yy",
        prevText: '<i class="fa fa-chevron-left"></i>',
        nextText: '<i class="fa fa-chevron-right"></i>',
        altField: alt_field, // This is the tag where the date will be filled
        altFormat: "yy/mm/dd" // This is how the date will be posted to your controller
      });
    })
vladCovaliov
  • 4,333
  • 2
  • 43
  • 58