Rails: Date format in forms and database - ruby-on-rails

I have a form which has a datepicker that shows a date with the format:
'%m/%d/%Y'
The problem is when I submit the form, this format is not a valid date, so it is not sent to the database on the INSERT INTO/UPDATE.
Nevertheless, it works if I submit a date with this format:
'%Y-%d-%m'
I have seen that I can do something like this before saving the object to the database:
my_object.due_date = params[:content_date].to_date.strftime("%Y-%d-%m")
But as I have more than one date field and more than one model with date fields, I would like to avoid doing an strftime() everywhere.
Do you have a better solution?

I'm using gem 'momentjs-rails', because of the datetime picker.
model
#deadline is saved in the db
#this is the getter-setter for deadline_string
def deadline_string
deadline.to_datetime.iso8601
end
def deadline_string=(deadline_str)
self.deadline = deadline_str
end
forms
#new form
<div class="field form-group">
<%= f.label :deadline %>
<%= f.text_field :deadline, class: "form-control new-task-deadline" %>
</div>
#edit form
<div class="field form-group">
<%= f.label :deadline %>
<%= f.text_field :deadline_string, class: "form-control edit-task-deadline" %>
</div>
js when saving to db
$('.new-task-submit').on('click', function (e){
e.preventDefault();
var localMoment = moment($('.new-task-deadline').val());
$('.new-task-deadline').val(localMoment.toISOString());
$('#newtask').submit();
});
$(document).on('click', '.edit-task-submit', function (e){
e.preventDefault();
var deadlineField = $('.edit-task-deadline');
var localMoment = moment(deadlineField.val());
var railsDate = localMoment.toISOString();
deadlineField.val(railsDate);
$(".task-update-form").submit();
});
js to show nice data on get request
//setting time and datetimepicker when opening edit task modal
$(document).on('shown.bs.modal', '#update-task-modal', function (e) {
var deadlineField = $('.edit-task-deadline');
var deadlineValue = deadlineField.attr('value');
var momentDeadline = moment(deadlineValue).format('MM/DD/YYYY hh:mm A');
deadlineField.val(momentDeadline);
deadlineField.datetimepicker({
sideBySide: true,
format: 'MM/DD/YYYY hh:mm A',
stepping: 15,
widgetPositioning: { vertical: 'bottom' }
});
});

Related

Rails select options dynamically changing based on another select (without ajax)

I have a form where a user selects a school, and then a qualification that the school provides:
<div class="row">
<div class="col-md-6">
<%= f.association :education_organization,
collection: EducationOrganization.active,
include_blank: true
%>
</div>
<div class="col-md-6">
<%= f.association :training_qualification,
collection: TrainingQualification.active,
include_blank: true
%>
</div>
</div>
I would like to dynamically scope the qualifications select to only show the qualifications available to the school that is selected.
I don't want to do an ajax call, I'd rather send the whole list at the start and have the client switch the select options offline.
What's the best way to do this?
I found a way, by initially loading all options, then storing the html options and filtering that list by the id of the association as a data attribute.
View:
<%= f.association :education_organization,
collection: EducationOrganization.active,
include_blank: true
%>
<%= f.association :training_qualification,
collection: TrainingQualification.active.map { |tq| [tq.name, tq.id, {data: {org: tq.education_organization.id}}] },
include_blank: true
%>
JS:
$(function(){
// this is a hack that lets the JS be included anywhere, but only run on pages with the relevant form
var qualifications_select = $('#user_training_qualification_id');
if(qualifications_select) {
// this stores all select options
var qualification_options = qualifications_select.html();
function updateQualSelect(qualifications_select) {
var selected_org_id = $('#user_education_organization_id :selected').val();
if(selected_org_id != '') {
var filtered_options = $(qualification_options).filter(`[data-org=${selected_org_id}]`);
qualifications_select.html(filtered_options);
} else {
qualifications_select.empty();
}
}
// this line filters the select when the other select changes
$('#user_education_organization_id').change(function() {
updateQualSelect(qualifications_select);
});
// this line filters the select on page load
updateQualSelect(qualifications_select);
}
})

getting params from form_tag for datetime_local_field

so i am working with google calendar apis in rails.
<%= form_tag new_event_url do %>
<div>
Subject :
<%= text_field_tag (:subject) %>
</div> <br>
<div>
Date And Time :
<%= datetime_local_field(:user, :event_date) %>
</div><br>
i need to grab parameter from the datetime_local_field.
controller code:
#subject = params[:subject]
#date = params[:user_event_date]
event = Google::Apis::CalendarV3::Event.new({
start: {
date_time: #date.to_datetime.rfc3339
},
end: {
date_time: #date.to_datetime.rfc3339
},
summary: #subject,
})
the subject part is good, but can't get the date_time
how to access that?
datetime_local_field creates a nested input:
#date = params[:user][:event_date]
Next time just look at the log or do params.inspect.

If Else in HAML to check the value of a "select" box

= form_tag questions_path, :method=>:post do
= label :question, :type, 'Type: '
= select :question, :type, %w(Text Picture Audio Video), :id=> :question_type_combo
**- if :question_type_combo.selected != 'Text'**
= label :question,:url, 'URL: '
= text_field :question,:url, :id=> :question_url_text
= submit_tag 'Add Question',:id=>:add_question_button
Is something of this sort possible in HAML? I wish to render the textfield only for certain options if selected in the SELECT BOX above.
Yes and no. You can write a conditional based on the values of the record that you bind to the form:
= form_for #question do |f|
= f.label :type
= f.select, :type, %w(Text Picture Audio Video), id: 'question_type_combo'
- unless f.object.question_type_combo === 'Text'
= f.label :url
= text_field :url, id: 'question_url_text'
But this would only change the visibility after the user submits the form and not be very useful.
Instead you can just use jQuery to create an event handler for the ´change´ event.
$(document).on('change','#question_type_combo', function(){
var type = $(this).first(':selected').val();
var $other_input = $('#other_input');
if (type == 'Text') {
$other_input.hide();
} else {
$other_input.show();
}
});
// sets the initial state
// if you are using turbolinks
$(document).on('page:load', function(){
$('#question_type_combo').trigger('change');
});
// if you are not using turbolinks
$(function(){
$('#question_type_combo').trigger('change');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form>
<div class="field">
<label>Type</label>
<select name="question[question_type_combo]" id="question_type_combo">
<option>Text</option>
<option>Something else</option>
</select>
</div>
<div class="field" id="other_input">
<label>URL</label>
<input type="text" name="question[url]">
</div>
</form>
- if :question_type_combo.selected != 'Text' This is not possible in the haml view, If you want to do something based on selected option you have to use js.
Or you may set the selected option using similar code if you have controller objects:
= select_tag("fee_discount", options_for_select(Fee.discounts.keys.map {|k| [k.titleize, k]}, selected: "#{"rewards" if #vendor.present? && #vendor.approved?}"), include_blank: true)
Or
You may keep the label and text_field inside a div with hide class.
And then using javascript you may hide unhide the div.

Add character counter in simple_form in Ruby on Rails

I use the simple_form gem and I want a simple character counter on a text field. I was told, this might work:
add this to the form:
<%= f.input :body, id: "body-field" %>
<span id="body-count">0 characters</span>
and javascript:
$("#body-field").on("keyup", function(){
length = $(this).val().length;
$("#body-count").html(length);
});
I got this information from here (Attention: It is full of advertisement): http://www.sohua.xyz/questions-full/4320915/how-do-i-implement-a-basic-character-counter-in-a-simple-form
I did this, but nothing happens. Here is my actual code chapters/new.html.erb:
<%= simple_form_for([#book, #book.chapters.build]) do |f| %>
<%= f.input :chaptertitle %>
Mininmum amount of characters: <%= #book.min_length %> Maximum amount of characters: <%= #book.max_length %>
<%= f.input :chaptercontent, id: "body-field" %>
<span id="body-count">0 characters</span>
<%= f.input :author %>
<%= f.button :submit %>
<% end %>
<script>
$("#body-field").on("keyup", function(){
length = $(this).val().length;
$("#body-count").html(length);
});
</script>
Can you give me any advice, how to get it work?
You need to wrap your code in jquery document ready function:
$(function() {
$("#body-field").on("keyup", function(){
var length = $(this).val().length;
$("#body-count").html(length);
});
});
Why don't you use an existing library instead?
https://github.com/dtisgodsson/jquery-character-counter
You might want to use either js or coffee-script, I am providing a coffee script example below:
Add this piece of code to your chapters.coffee file:
ready = ->
totalChars = 100
#Total characters allowed
countTextBox = $('#body-field')
# Remaining chars count will be displayed here
charsCountEl = $('#countchars')
#initial value of countchars element
charsCountEl.text totalChars
#user releases a key on the keyboard
countTextBox.keyup ->
#get chars count in Text field
thisChars = #value.replace(/{.*}/g, '').length
if thisChars > totalChars
# total extra chars to delete
CharsToDel = thisChars - totalChars
#remove excess chars from text field
#value = #value.substring(0, #value.length - CharsToDel)
else
#count remaining chars
charsCountEl.text totalChars - thisChars
return
return
$(document).ready ready
$(document).on 'page:load', ready
# Loads javascript while loading page
Add this line to your form right below to the Text input field.
var ready;
var charsCountEl, countTextBox, totalChars;
totalChars = 100;
countTextBox = $('#body-field');
charsCountEl = $('#countchars');
charsCountEl.text(totalChars);
countTextBox.keyup(function() {
var CharsToDel, thisChars;
thisChars = this.value.replace(/{.*}/g, '').length;
if (thisChars > totalChars) {
CharsToDel = thisChars - totalChars;
this.value = this.value.substring(0, this.value.length - CharsToDel);
} else {
charsCountEl.text(totalChars - thisChars);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input type="text" id="body-field" />
<span id="countchars"></span>
If your file under javascript/ folder doesn't have extestion .coffee the please rename it to chapters.coffee if it does then thats it.
PS: here is the javascript version of the same http://pastebin.com/LZb1DAC4.
Reference: https://stackoverflow.com/a/24629105/2545197
This solution won't be as good as Abhinay's solution, but it works for me:
(Please note, I'm an amateur, this code may be horrendous)
Javascript code:
<script>
$(document).ready(function(){
var choosingbar = function( event ){
$(event.target).parents(".counting").children(".count").text($(event.target).val().length);
};
$(".counting textarea").keyup(choosingbar);
});
</script>
new.html.erb code:
<%= simple_form_for([#book, #book.chapters.build]) do |f| %>
<%= f.input :chaptertitle %>
Mininmum amount of characters: <%= #book.min_length %> Maximum amount of characters: <%= #book.max_length %>
<div class="counting" ><%= f.input :chaptercontent %>Characters: <span class="count"></span></div><br>
<%= f.input :author %>
<%= f.button :submit %>
<% end %>

Ajax calls for Date Difference

In my _form.html.erb, I have two DatePicker:-
<div class="field">
<!--%= f.label :leaveFrom %-->
<div><%= f.text_field :leaveFrom, :id => 'datepicker4', :placeholder => "From Date"%></div>
</div>
<div class="field">
<!--%= f.label :leaveTo %-->
<div><%= f.text_field :leaveTo, :id => 'datepicker5', :placeholder => "To Date" %></div>
</div>
My requirement is to calculate the date difference between these two dates but not on the form submission. as soon as i select the "To Date", it displays the no of days. I am not able to implement ajax calls. can any one provide some solution to implement this.
I think best way is show difference using java script instead of calling ajax.var leaveFrom =
function dayDiff(){
var leavefrom = $('.datepicker4').datepicker('getDate');
var leaveto = $('.datepicker5').datepicker('getDate');
var dayDiff = Math.ceil((leavefrom - leaveto) / (1000 * 60 * 60 * 24));
}
Call this on select of date or before submitting form.
Try this using jQuery assuming CalculatorController having date_diff method
$(function() {
$('#datepicker5').live("change", function() {
$.ajax({
url: "/calculator/date_diff",
type: "POST",
data: {date1 : $("#datepicker4").val(), date2 : $("#datepicker5").val()}
success: function(result) {
alert(result);
}
});
});
});

Resources