1

I'm using jQuery Datepicker gem and when I'm editing a record that has a date it it behaves unexpectedly.

When I create a new record the date is entered with the mm/dd/yy format. When I go to edit the record the date is being populated in the date field in the format yyyy-dd-mm and I have no idea why. Perhaps this is something to do with Rails itself?

The Date column in the table is set to Date, which I would imagine is fine. Is there something that I need to do in my view when displaying the date or something in the controller?

This is what is in my application.js file:

$(document).on('page:change', function () {
        $('#cust_dob').datepicker({
            changeMonth: true,
            changeYear: true,
            dateFormat: "mm/dd/yy",
            yearRange:  "1900:+0"
    });
});

Any help would be much appreciated.

DaveInFL
  • 162
  • 2
  • 9
  • Actually, seems worse than I thought...It's not actually saving to the DB right now..it was doing this but now it isn't. Not sure what's going on :( – DaveInFL Apr 16 '14 at 01:39

4 Answers4

2

Ok, I was able to get this working. There were two issues. The first is that the date wasn't always getting saved into the database table because of a difference of format. So, I used a hidden field and used the altFormat and altField options of the datapicker. The second issue was formatting a current date when editing a record. This was achieved using strftime as DevDue suggested. So, for those that are interested here is what I have in my view. Not saying this is the best way since I really am still learning RoR, but it works :)

So, my partial view with the date:

<div class="span2 input">
  <% dob_display = :dob %>
  <%= f.text_field dob_display,  placeholder: "mm/dd/yyyy", required: true, id: "cust_dob", value: @customer.dob.try(:strftime, "%m/%d/%Y") %>
  <%= f.hidden_field :dob, id: "cust_dobalt" %>
</div>

It took me a while to realise that unless the hidden_field comes after the visble field it just doesn't work!

My application.js file for this datepicker looks as follows. Notice the altField and altFormat:

$(document).on('page:change', function () {
    $('#cust_dob').datepicker({
        changeMonth: true,
        changeYear: true,
        dateFormat: "mm/dd/yy",
        yearRange:  "1900:+0",
        altField:   "#cust_dobalt",
        altFormat:  "yy-mm-dd",
        duration:   "slow"
    });
});
DaveInFL
  • 162
  • 2
  • 9
  • While this may not be the perfect solution, this is 99% of what I've spent too long looking for! No added gems, no date format initializers, no I18n customization. Nice. Simple. The only problem is that when dates other than the `mm/dd/yyyy` format are manually entered, the date is not updated (of course), but no error is returned. For example, when editing, if I enter "2014/10/02" the object gets saved without changing the date, and is returned as if the change was successful. – digijim Sep 12 '14 at 17:07
2

Disclaimer, I've only been a rails dev for about a year now, no formal training. That said, here is how I got it working in my own app.

  1. Set the datepicker to format the date the way we want it to show up in the form, i.e. %m/%d/%y.
  2. Before we save it to the db, we convert it from a string back to a Date Object using strptime, so that the controller knows what to do with it.
    • In case you didn't know the difference (I didn't until I figured this out), strftime allows you to create a string from a date object, while strptime allows you to do the opposite, converting a string to a Date Object.
  3. We add it back to the params we're creating/updating from, and it should work just fine.

Form View

<%= f.text_field dob_display, value: @customer.dob.strftime("%m/%d/%Y")%>, id: 'cust_dob'

jQuery

$('.cust_dob').datepicker({format: 'mm/dd/yyyy'});

Controller

filtered_params = user_params
filtered_params[:dob] = Date.strptime(filtered_params[:dob], '%m/%d/%Y')
@user = User.new(filtered_params)

Hopefully this works for you! I did the same thing with the bootstrap-datetimepicker plugin as well and it works fine for me.

nickcamillo
  • 340
  • 2
  • 9
  • I'm flabbergasted that Rails doesn't have a solution to automatically convert the string value to a Date or Time object. Having to do it manually seems so anti-rails. Never the less, thank you for posting this! I've spent too much time on this issue that I'm just happy to get it working. – Justin Adkins Oct 07 '18 at 15:34
0

You can change the format for the datepicker

// setter
$( ".selector" ).datepicker( "option", "dateFormat", "mm/dd/yy" );

From:

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

And to change the date format on the way out:

t.strftime("Printed on %m/%d/%Y")   #=> "Printed on 11/19/2007"

http://apidock.com/ruby/DateTime/strftime

Good luck

SomeDudeSomewhere
  • 3,928
  • 1
  • 23
  • 27
  • It's not the format when entering the date...that is fine, and I believe the default is actually mm/dd/yy. I think this has more to do with Ruby and how it stores dates when they are brought back fromt he database. – DaveInFL Apr 16 '14 at 00:43
  • Use strftime to change the format then. http://apidock.com/ruby/DateTime/strftime – SomeDudeSomewhere Apr 16 '14 at 13:17
  • Tried but getting another error now. The line of code causing the error is: <%= f.text_field :dob.try(:strftime, "%m/%d/%Y"), placeholder: "mm/dd/yyyy", required: true, id: "cust_dob" %> The actual error message is: undefined method `' for # – DaveInFL Apr 16 '14 at 17:58
0

Followed the solution provided by nickcamillo. Listed my implementation here specifically to show the date format config in coffeescript since many people seem to have faced a problem configuring it correctly.

The format configuration in coffeescript by itself was not enough. I had to also explicitly convert the incoming effective_from_date parameter value to the format I wanted. Or I guess I could have set the default date format application-wide as described in Changing the default date and time format in Rails 4

Coffeescript:

ready = ->
  $('.activate-datepicker').datepicker format: 'mm/dd/yyyy'

$(document).ready(ready)
$(document).on('page:load', ready)

Controller:

param[:effective_from_date] = Date.strptime(params[:effective_from_date], '%m/%d/%Y')
Community
  • 1
  • 1