I am trying to use Tempus Dominus Bootstrap 4 in a form on a Ruby on Rails 5.2 app so the user can select a date. Here is the code:
app/views/events/_form.html.erb
<div class='form-group'>
<%= f.label :starts_at, 'Start Date and Time', class: 'control-label' %>
<div class="input-group date" id="datetimepicker1" data-target-input="nearest">
<%= f.text_field(:starts_at, class: "form-control datetimepicker-input", data: {target:"#datetimepicker1"}) %>
<div class="input-group-append" data-target="#datetimepicker1" data-toggle="datetimepicker">
<div class="input-group-text"><i class="fas fa-calendar-plus"></i></div>
</div>
</div>
</div>
app/assets/javascripts/events.js
$(function () {
$('#datetimepicker1').datetimepicker();
});
app/controllers/events_controller.rb
def create
#event = Event.new(event_params)
#event.user = current_user
if #event.save
redirect_to #event, notice: 'Event was successfully created.'
else
render :new
end
end
I want to submit the format with month first. When I pick a date June 9, 2018 and submit the form, it saves it to the database with the month and day reversed: Sept 6, 2018. When I look at the params after the form is submitted, the format is 06/09/2018 6:00 PM with month first, but Ruby/Rails converts it to a datetime object assuming day first.
How do I tell Ruby that the month is first when converting it to a date object? Can I do something in the controller before saving it?
You can tell Ruby how to read time string:
DateTime.strptime('06/09/2018', '%m/%d/%Y')
More details you can see in this answer.
Edited:
Also, you can set the default date format as there:
Add this to config/initializers/date_time.rb
Date::DATE_FORMATS[:default] = "%m/%d/%Y"
I found out you can change the date format to one Ruby correctly understands and that is easily readable by users. Change the JavaScript to:
$(document).on('turbolinks:load', function() {
$('#datetimepicker1').datetimepicker(
'format', 'MMMM D, YYYY h:mm A'
);
});
This will display the date to the user as June 9, 2018 6:30 PM. Date format comes from Moment.js http://momentjs.com/docs/#/displaying/format/ but is added to the format option of Tempus Dominus.
As a side note, to get tempus dominus boostrap 4 working in Rails, you have to also load moment.js. Either call the cdn or add the momentjs-rails gem. If the latter then in your application.js file you need to require it, something like this:
# app/assets/javascripts/application.js
...
//= require moment
//= require tempusdominus-bootstrap-4.js
Related
So, I have a rails application which there is a datepicker. When I put the date for the first time in the calendar it appears in this format: dd-mm-yyyy.
But rails save in the database in this format: yyyy-mm-dd.
When I go to edit this in the form, the datepicker get crazy, it appears a 1900 year, not the actual year.
I know this happens because the format date is different(the date which bootstrap expects and the date which is saved).
I tried change the datepicker format in the edit view(.html.erb) but it doesn't work. How can I solve this?
<%= f.text_field :my_date, "data-provide" => 'datepicker',
'data-date-format' => 'dd-mm-yyyy', class: 'datepicker form-control', :required => true %>
I'm creating a leave management app, and I need to input multiple date into a field from calendar (jquery ui datepicker or something like that).
I've tried gem 'multi-dates-picker-rails', but it's not working.
Would you give a solution? Thank you.
You can use below jquery library file
http://dubrox.github.io/Multiple-Dates-Picker-for-jQuery-UI/
Javascript
https://raw.githubusercontent.com/dubrox/Multiple-Dates-Picker-for-jQuery-UI/master/jquery-ui.multidatespicker.js
CSS
https://raw.githubusercontent.com/dubrox/Multiple-Dates-Picker-for-jQuery-UI/master/jquery-ui.multidatespicker.css
include these file into assets
In html
<%= text_field_tag :route_dates, nil, class: "gui-input", placeholder: "Select date" %>
coffescript
date = new Date()
$('#route_dates').multiDatesPicker
addDates: [date, date]
dateFormat: 'dd-M-yy'
I am using the bootstrap-datepicker-rails gem for my app and have created a form where users can pick a start date and an end date.
When the user edits the form I want them to be able to see the dates that they had previously chosen. (e.g. Start: October 31, 2015, End: November 15, 2015).
I am trying to write a test to make sure my app does this, but I'm stuck on the syntax.
user_updates_project_spec.rb
require "rails_helper"
feature "User updates project" do
before (:each) do
#user = create(:user)
login_as(#user, scope: :user)
#project = create(:project, creator: #user,
name: "Building a robot",
start_at: "2015-10-31",
end_at: "2015-11-15", )
end
scenario "and sees correct dates on form" do
visit edit_user_project_path(#user, #project)
expect(".datepicker").to have_content("October 31, 2015")
end
end
The error I get is:
Failure/Error: expect(".datepicker").to have_content("October 31, 2015")
expected to find text "October 31, 2015" in ".datepicker"
This is what my form looks like:
<div class="col-sm-6 pl0">
<%= f.input :start_at, label: "Start Date", as: :string,
input_html: {value:#project.set_start_date_for_form.to_s(:long),
class: "datepicker start-date"} %>
</div>
<div class="col-sm-6 pr0">
<%= f.input :end_at, label: "End Date", as: :string,
input_html: {value: #project.set_end_date_for_form.to_s(:long),
class: "datepicker end-date"} %>
</div>
Any ideas on why it's not working?
The way you've written your expects, what you're really saying is expect the string ".datepicker" to have the content "October 31, 2015" which is never going to be true. expect needs to take an element that the have_content matcher can be run against rather than a string. You could rewrite it like this
expect(page.find(:css, '.datepicker.start-date')).to have_content("October 31, 2015")
although a better method would probably be to use
expect(page).to have_css('.datepicker', text: 'October 31, 2015)
since that will match if the content is changing or being loaded via ajax.
One other thing to note is that since you're using a datepicker widget you might actually need to look at the html that is produced by the JS in a real browser, instead of the html in your view tempalte, to determine exactly which element you need to be checking for the content inside.
I guess there may be a confusing for .start-date and .end-date also you can use .text attribute to check them:
expect(page.find(:css, '.datepicker.start-date').text).to eq('October 31, 2015')
expect(page.find(:css, '.datepicker.end-date').text).to eq('November 15, 2015')
If it fails, you can print the value to debug it:
puts page.find(:css, '.datepicker.start-date').text
It turns out I wasn't checking inside the correct element when testing.
What solved it was:
expect(page).to have_css("#project_start_at[value='October 31, 2015']")
expect(page).to have_css("#project_end_at[value='November 15, 2015']")
The element id's that datepicker set were project_start_at and project_end_at.
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?
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!
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.
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
});
})
Can rails formatting helpers be used on an 'edit' screen? The format helpers (number_to_currency, number_to_percent) are great for index/show, but I don't see how to apply them during edit. I have a custom heler that formats the date:
def my_date_helper(datetime)
datetime.nil? ? "" : datetime.strf('%d-%b-%Y')
end
For example, if I have a starts_at attribute, that the user interacts with using a jQuery datepicker, the value placed in edit.html.erb in <%= f.text_field :starts_at %> by rails will be formatted like:
2011/12/19 00:00:00
I would like the user to be presented with a consistent format,so I want to apply the same format helper I use in show/index so the edit text field shows a format like:
19-Jan-2011
You could do this for your edit form:
<%= f.text_field :starts_at, :value => my_date_helper(#my_model.starts_at) %>
Also, jQuery's Date Picker includes a dateFormat parameter, so you could do something like this in your javascript:
jQuery("#my_model_starts_at").datepicker({
dateFormat: 'd/M/yy'
});
I just had a 'duh' moment. To doesn't seem there's any easy, rails-ey way. But it can be done really easy with unobtrusive JavaScript, like:
$('.datepicker').each(function(i){
var date = new Date($(this).val());
$(this).val($.datepicker.formatDate('dd-M-yy', date));
});
Four lines in application.js and you're done.
jQuery('#datetimepicker3').datetimepicker({
format:'d.m.Y H:i',
inline:true,
lang:'ru'
});
datetimepicker