Ajax calls for Date Difference - ruby-on-rails

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);
}
});
});
});

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);
}
})

Unable to reset/update options on jQuery Chosen in rails app

I'm developing a rails 5.1 app. I'm using chosen javascript plugin in my app for making the select-boxes more user friendly.
In one of my viewpage, I have 2 chosen select boxes. one for project and other for tasks. Requirement is to load only the associated tasks on change of project select box.
My View
<div class="form-group pad-right-one">
<%= f.collection_select :task_project_id_eq, #projects.order(:number), :id, :project_with_number, { include_blank: 'Project' }, {class: 'chosen-select', onchange: "populateTaskFieldWithOptions()"} %>
</div>
<div class="form-group pad-right-one">
<%= f.collection_select :task_id_eq, #tasks.order(:project_id, :number), :id, :task_with_number, { include_blank: 'Task' }, {class: 'chosen-select'} %>
</div>
Js Code
Ajax call that I'm making is a success and I'm getting all the values.
function populateTaskFieldWithOptions(){
let projectId = $("#q_task_project_id_eq").val();
$.ajax({
type: "POST",
url: "/mail/getTasks",
data: {project: projectId},
success:
function(result){
console.log("---Ajax Success----");
document.getElementById('q_task_id_eq').selectedIndex = -1;
var newOption = $('<option value="1">test</option>');
$('#q_task_id_eq').append(newOption);
$('#q_task_id_eq').trigger("chosen:updated");
// Other options I tried ...
//$('#q_task_id_eq').trigger("liszt:updated");
//$('#q_task_id_eq').val(' ').trigger('liszt:updated');
//$('#q_task_id_eq').val(' ').trigger('chosen:updated');
},
error:
function(jqXHR, textStatus, errorThrown){
console.log("---Ajax Error----")
console.error('AJAX Error: ' + textStatus + errorThrown);
}
})
};
I'm not able to reset or update the chosen dropdown.
Any help is really appreciated. Thanks in advance.
$(".chosen-select").chosen("destroy");

using the city-state gem in rails

Hey guys im currently working on a devise sign up form, the end goal is a user can select a state from the united states and a select tag below will populate with the correct cities in that state. im using the city-state gem. https://github.com/loureirorg/city-state
ive looked at other examples like this one https://forum.upcase.com/t/dependent-country-city-state/7038 my code is below
routes.rb
resources :states, only: :new
registrations.new.html.erb
<div class="field">
<%= f.select :state, options_for_select(CS.states(:us)), {:prompt => "State"}, {:class => "signup-input-container--input", :id => "state-picker"} %>
</div>
<div class="field">
<%= f.select :city, options_for_select([]),{}, {:class => "signup-input-container--input", :id => "city-picker"} %>
</div>
main.js
document.addEventListener("turbolinks:load", function(){
var state = document.getElementById("state-picker");
state.addEventListener("change", function() {
Rails.ajax({
url: "/states?country=" + "United States" + "&state=" +
state.value,
type: "GET"
})
})
});
registrations-controller.erb
def new
super
#cities = CS.get(:us, params[:state])
end
new.js.erb
var city = document.getElementById("city-picker");
while (city.firstChild) city.removeChild(city.firstChild);
var placeholder = document.createElement("option");
placeholder.text = "Choose a city";
placeholder.value = "";
city.appendChild(placeholder);
<% #cities.each do |c| %>
city.options[city.options.length] = new Option('<%= c %>');
<% end %>
im trying to get this to work the way the example link shows. the only difference is that users will only choose states from the US and citys
From our discussion in the comments the issue appears to be that you are requesting the wrong URL for your cities.
You have a route at /states/new but are making the request to /states. Try updating your main.js to:
document.addEventListener("turbolinks:load", function(){
var state = document.getElementById("state-picker");
state.addEventListener("change", function() {
Rails.ajax({
url: "/states/new?state=" + state.value,
type: "GET"
})
})
});
(I removed the country parameter in the URL because you don't seem to be using it, you say you only need this for the US anyway.)
Let me know how you get on with that.

Rails: Date format in forms and database

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' }
});
});

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 %>

Resources