jQuery ajax call from a numberfield using Rails is not working - javascript

For my application, I have fixeddeposits where we can create new fixeddeposits. Now, i want to update the rateofinterest field based upon the number(365/730/1095/1460 & 1825) I typed in the deposit period(number_field) and i have to check the customer age.
I have calculated customer age in fixeddeposits_controller. I don't know where i am wrong that too is not working.
Example 1:
1.1: If a customer age >58 && age<75, i want to open the fixed deposit for 365days means i have to sum the two fields rate(9.5%) + seniorincrement(0.5%) and then pass the value(10.0%) to rateofinterest field.
1.2: If a customer age >75, i want to open the fixed deposit for 365days means i have to sum the two fields rate(9.5%) + superseniorincrement(1.0%) and then pass the value(10.5%) to rateofinterest field.
1.3: If a customer age <58, i want to open the fixed deposit for 365days means i have to pass the rate(9.5%) field value alone to rateofinterest field.
Where as(rate, seniorincrement, superseniorincrement)fields are from interestrates table.
For this i am using AJAX/JQUERY which was suggest by Mandeep in my previous question.
I have implemented, but its not working. I have attached the code i tried. Kindly check it and please give me some ideas.
_form.html.erb
<%= form_for #fixeddeposit do |f| %>
<% if #fixeddeposit.errors.any? %>
<h4>Couldn't open FD Account</h4>
<ul>
<% #fixeddeposit.errors.full_messages.each do |error| %>
<li><%= error %></li>
<% end %>
</ul>
<% end %>
<%= f.label :customer_name, class:'required' %>
<%= f.text_field :customername, :placeholder =>'Name' %>
<%= f.label :date_of_birth, class:'required' %>
<%= f.date_select :dateofbirth, { :include_blank => true, :start_year => 1900, :end_year => 2014 }, :id => "dateofbirth" %>
<%= f.label :Periods, class:'required' %>
<%= f.number_field :periods, :id => "fixeddeposit_periods", :placeholder => "Days", :class => "input-mini" %>
<%= f.label :Rate_Of_Interest %>
<%= f.text_field :rateofinterest, :id => "fixeddeposit_rateofinterest", :value => "", :disabled => true, :class => "input-medium" %>
<span class="help-block">auto-generated</span>
<div>
</div>
<%= f.submit "Open FD", class: "btn btn-primary" %>
<% end %>
</div>
</div>
application.js
$(document).on("change","#fixeddeposit_periods",function(){
var periods = $(this).val();
var dateofbirth = $("#dateofbirth").val();
$.ajax({
type: "POST",
url: "/rateofinterest",
data: { periods: periods, dateofbirth: dateofbirth }
});
});
fixeddeposits_controller
def calculate_age(dateofbirth)
#age = DateTime.now - dateofbirth/ 365
end
def calculate_rateofinterest
#periods = params[:periods]
#dateofbirth = params[:dateofbirth]
calculate_age(#dateofbirth)
if #age >= 58 && #age < 75
#rateofinterest = Rateofinterest.select('interestrates.id, interestrates.seniorincrement')
elsif #age >= 75
#rateofinterest = Rateofinterest.select('interestrates.id, interestrates.superseniorincrement')
else
#rateofinterest = Rateofinterest.select('interestrates.id, interestrates.rate')
end
respond_to do |format|
format.html{ redirect_to fixeddeposits_path }
format.js{}
format.json{}
end
end
calculate_rateofinterest.js.erb
$("#fixeddeposit_rateofinterest").val(#rate);
routes.rb
resources :fixeddeposits do
resources :interestrates
end
post "/rateofinterest" => "fixeddeposits#calculate_rateofinterest" , as: "calculate_rateofinterest"
I don't know why it is not working. Help me to solve this issue.

First of all, in your js code replace
var dateofbirth = $("#fixeddeposit_dateofbirth").val();
with
// you have mentioned your dob field's id as 'dateofbirth'
var dateofbirth = $("#dateofbirth").val();
In your controller, you need to call calculate_age method to have #age variable. Replace
#dateofbirth = params[:dateofbirth]
with
#dateofbirth = params[:dateofbirth]
calculate_age(#dateofbirth)
I'm not sure, why you have written #age.save in your calculate_age method definition. You may remove it.
Now in your calculate_rateofinterest.js.erb file replace
$("#interestrates_rate").val(#rate);
with
$("#fixeddeposit_rateofinterest").val(#rate);
Hope it will help you.

Related

How can I get the dynamic Id of nested form?

I got the following code, which I want to show the Add option button when the user chooses the OPTIONS type in the select box. It only works for the first time to add the question. I know the problem which is I gave the id to the select box, but if I do not do that, how can I get the dynamic id of the select box?
<%= f.fields_for :questions do |question_form| %>
<%= question_form.text_field :question_text %>
<%= question_form.select(:question_type, [ 'TEXT', 'OPTIONS', 'UPLOAD' ],{:prompt => 'Select One'}, :id => "my_id", :onchange => "myFunction()") %>
<%= question_form.link_to_remove "Remove this Question" %>
<%= question_form.fields_for :options do |option_form| %>
<%= option_form.text_field :option_text %>
<%= option_form.link_to_remove "Remove this option" %>
<% end %>
<p id = "test" hidden><%= question_form.link_to_add "Add a option", :options %></p>
<% end %>
<p><%= f.link_to_add "Add a Question", :questions %></p>
<p>
<%= f.submit %>
</p>
<% end %>
<script>
function myFunction(){
var e = document.getElementById("my_id");
var x = e.options[e.selectedIndex].value
if (x == "OPTIONS"){
document.getElementById("test").hidden = false;
}
else{
document.getElementById("test").hidden = true;
}
}
</script>
While I'm not entirely sure what you mean by "It only works for the first time to add the question", it sounds like you're confident that using document.getElementById() is the problem. (I don't know why it would be, but I'm unfamiliar with Rails, so I'll assume you're correct.)
If so, you can avoid that selector by using the target property of the EventListeners's built-in "event" parameter:
function myFunction(event){
`var x = event.target.options[e.target.selectedIndex].value`
...
(And you might be able to shorten this to event.target.value.)

How can I retrieve the ID of a collection_select and display a list of items every time the select changes?

I have a form
_form.html.erb
<%= simple_form_for(#exam) do |f| %>
<%= f.error_notification %>
<div class="field">
<%= f.label :Year %>
<%= f.collection_select :year_id, Year.order(:name), :id, :name, prompt: true %>
</div>
<div class="form-inputs">
<%= f.input :marks_secured %>
</div>
<div class="form-actions">
<%= f.button :submit, "Submit" %>
</div>
<% end %>
And, every time the select box changes (i.e. a different year is selected), I want to display the list of students for the selected year. The list must be shown within the same page.
I don't know how to grab the ID of the selected item and use it back inside the view/controller in order to achieve this..
Here are my models:
student.rb
class Student < ApplicationRecord
belongs_to :year
has_many :exams
end
exam.rb
class Exam < ApplicationRecord
belongs_to :year
belongs_to :student
end
year.rb
class Year < ApplicationRecord
has_many :students
has_many :exams
end
I recommend using ajax in order to show the list of students every time the select option is changed; to do so you need to make several changes.
First, you need to determine where in your view you would like to display de students, for example, try adding a div in your form:
<%= simple_form_for(#exam) do |f| %>
<%= f.error_notification %>
<div class="field">
<%= f.label :Year %>
<%= f.collection_select :year_id, Year.order(:name), :id, :name, prompt: true %>
</div>
<div id="students"><!-- Students will be listed here --></div>
<div class="form-inputs">
<%= f.input :marks_secured %>
</div>
<div class="form-actions">
<%= f.button :submit, "Submit" %>
</div>
<% end %>
Next, add a script (on the same view where your form is) to detect when the select changes, and update (via ajax) the students list:
<script type="text/javascript">
$(function () {
function getStudents() {
var year = $('#exam_year_id').val();
$.ajax({
headers: {
'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
},
type: "GET",
url: "<%= students_url %>",
data: { year: year },
success: function(response) {
$('#students').html(html);
}
});
}
$('#exam_year_id').on('change', getStudents );
getStudents();
});
</script>
In this example the function getStudents is called whenever the select changes ($('#exam_year_id').on('change', getStudents );) and after the page loads (getStudents();), so the students from the default year selected (that is, when your page first loads) get listed.
Also notice that we are replacing the content of the div recently added with a variable called html which will be delivered within a view by your students controller (next step).
Now you need to update your students controller to get the list of students for the selected year:
def index
#Students = Student.where(year: params[:year])
end
And create your view with the list of students:
var html = "<select name='exam[student_id]' id='exam_student_id'>";
<% #Students.each do |student| %>
html = html + "<option value='<%= student.id %>'><%= student.name %></option>"
<% end %>
html = html + "</select>";
The view must be named index.js.erb (instead of a index.html.erb) and will contain javascript; in this example it only contains a the variable (html) with the list of students (the list is created as another select box but you can change it).
Finally, in your exams controller add an update action that will update the exam's details:
def update
exam = Exam.find(params[:id])
exam.student_id = exam_params[:student_id]
exam.year_id = exam_params[:year_id]
exam.save!
end
private
def exam_params
params.require(:exam).permit(:year_id, :student_id)
end
And that's it! Hope this helps.

select user and then dropdown of his challenges

A user has_many challenges.
When a user is selected...
<%= f.select :user_id, options_for_select(#challengers.collect { |challenger| [challenger.full_name] }) %>
... how can we show another dropdown with a list of his challenges?
<%= f.select :challenge_id, options_for_select(#challenger_challenges.collect { |challenged| [challenged.full_challenge]}) %>
In other words, how can we make "#challenger_challenges = the selected user's challenges"?
As it stand I get an error undefined method 'collect' for nil:NilClass since #challenger_challenges is nil.
OPTION 1
In challenges_controller I could do this:
#challengers = User.all
#challenger = User.find(params[:challenger_selected]) if (params[:challenger_selected]).present?
#challenger_challenges = #challenger.challenges
And then I would just need a way to refresh the page once a user is selected so that the user ID is passed in the params as :challenger_selected
OPTION 2
Achieve the aim of this question without the need of a page refresh. *Preferable
UPDATE
Based upon the comments below I realize I need to elaborate.
A user has_many challenges.
A user can create a duel.
In a duel there are two duelers.
The creator of the duel selects his own :challenge_id and then he selects the other dueler as well as one of his :challenge_id and then sets the #duel.consequence the dueler will have to do if he fails his challenge. The other dueler will get a duel request notification and then has the choice to accept or decline the conditions of the duel.
challenges.show.html.erb
<%= render 'duels/form' %>
duels/_form.html.erb
<%= simple_form_for(#duel) do |f| %>
<%= f.fields_for :duelers do |dueler| %>
<%= f.hidden_field :challenge_id, :value => #challenge.id %>
<%= #challenge.full_challenge %>
<% end %>
<%= f.fields_for :duelers do |dueler| %>
<%= render 'duels/dueler_fields', :f => dueler %>
<% end %>
<%= button_tag(type: 'submit', class: "btn", id: "challenge-create-save") do %>
Request Duel
<% end %>
<% end %>
duels/_dueler_fields.html.erb
<%= f.select :user_id, options_for_select(#challengers.collect { |challenger| [challenger.id] }) %>
# Trying to make this responsive to the user that is selected above
<%= render 'challenges/select', :f => f %>
<script>
$('#duel_duelers_attributes_1_user_id').change(function () {
var challenger_id = $(this).find(":selected").val();
var address = "<%= select_path %>".concat(challenger_id);
$.get(address, function(data) {
$("#duel_duelers_attributes_1_challenge_id").html(data);
});
});
</script>
routes
get 'challenges/select/:id' => 'challenges#select', as: 'select'
challenges/_select.html.erb
<%= f.select :challenge_id, options_for_select(#challenger_challenges.collect { |challenged| [challenged.full_challenge]}) %>
challenges_controller
def select
if (params[:challenger_id]).present?
#challenger = User.find(params[:challenger_id])
else
#challenger = User.find(1)
end
#challenger_challenges = #challenger.challenges
end
Credit for this should go to #Fallenhero - I am just explaining it in more detail.
You need to be able to identify the select tag.
<%= f.select ..., :html => {:id => :first} %>
You also need somewhere to put the second one.
<div id="second"></div>
Using jQuery:
$('#first').change(function () {
var challenger_id = $(this).find(":selected").val();
var address = "<%= [prints address to new select tag] %>".concat(challenger_id);
$.get(address, function(data) {
$("#second").html(data);
});
});
The address Ruby prints out should look something like challenges/select/ depending on how you want to design it. The / at the end is important.

multipleselect is forgeting selected values after proceed

Multiplyselect is forgetting owners values after searching.
After proceed i got params[:search] and params[:owners] but only input for search is filled-in. This is my code.
def index
#all_owners = Owner.select('distinct name').pluck(:name)
#animal = Animal.search(params[:search])
#animal = #animals.joins(:owners).where("owners.name IN (?) ", params[:owners].present? ? params[:owners] : #owners)
end
#------------------------------------------
<%= form_tag animals_path, :method => 'get' do %>
<%= text_field_tag :search, params[:search]%>
<%= select_tag :owners, options_for_select(#all_owners),id: "multiselect-id", multiple: true %>
<%= submit_tag "Search", :name => nil %>
<% end %>
<% #aminals.each do |animal| %>
<%= animal.name %>
<%= animal.owners.map(&:name).join(', ') %>
<% end %>
<script type="text/javascript">
$(document).ready(function() {
$('#multiselect-id').select2();
});
</script>
You forgot to specify the currently selected values in the select_tag. This is done e.g. by a second argument to the options_for_select helper, i.e. something like: options_for_select(#all_owners, params[:owners] || #owners).
See the docs here.

Rails 3 javascript: How to render a partial with parameters

I'm still getting the hang of Rails. Here I'm using Rails 3 and the goal basically is to have an AJAX call triggered when I click the subscribe button the post_form partial is rendered beneath for the topic I have just subscribed to. The button then becomes an unsubscibe button and the post_form partial is removed. The toggling of the button alone works (i.e: by removing the second line in the two immediately following snippets), but the rendering of the *post_form* partial does not.
The problem is I can't seem to get the right syntax and/or passing of parameters in the two following partials. The topic object is just not passed and I get an invalid model_name for NilClass error when clicking on the subscribe or unsubscribe button. If I refresh the page manually, the partial is rendered or hidden the correct way, so it's really just the AJAX part that isn't working right.
views/subscription/create.js.erb
$("#subscription_form").html("<%= escape_javascript(render('users/unsubscribe')) %>");
$("#post_form").html("<%= escape_javascript(render('shared/post_form', :topic => #topic)) %>");
views/subscription/destroy.js.erb
$("#subscription_form").html("<%= escape_javascript(render('users/subscribe')) %>");
$("#post_form").html("<%= escape_javascript(render('shared/post_form', :topic => #topic)) %>");
views/users/_subscription_form.html.erb
<% unless current_user?(#user) %>
<div id="subscription_form">
<% if current_user.subscribed?(#topic) %>
<%= render 'users/unsubscribe', :topic => #topic %>
<% else %>
<%= render 'users/subscribe', :topic => #topic %>
<% end %>
</div>
<% end %>
controllers/subscriptions_controller.rb
class SubscriptionsController < ApplicationController
before_filter :signed_in_user
respond_to :html, :js
def create
#topic = Topic.find(params[:subscription][:topic_id])
current_user.subscribe!(#topic)
respond_with #topic
end
def destroy
#topic = Subscription.find(params[:id]).topic
current_user.unsubscribe!(#topic)
respond_with #topic
end
end
views/shared/_post_form.html.erb
<%= form_for(#post) do |f| %>
<div class="field">
<%= f.hidden_field :topic_id, :value => #topic.id %>
<%= f.text_area :content, placeholder: "Tell us about it ..." %>
</div>
<%= f.submit "Post", class: "btn btn-large btn-primary" %>
<% end %>
If it is of any help, the relationships are:
post -> belongs_to -> topic and topic -> has_many -> posts
Looks like you're using the variable "#post" in the "views/_post_form.html.erb" file.
<%= form_for(#post) do |f| %>
Since you aren't setting that variable anywhere in your actions you would get a null reference error.
You would need to do something like this:
def create
#post = Post.find(the_post_id)
#topic = Topic.find(params[:subscription][:topic_id])
current_user.subscribe!(#topic)
respond_with #topic
end
Also you are passing in the "topic" variable as a local but accessing it as an instance variable. You should change the your _post_form.html.erb file to look like this:
<%= form_for(#post) do |f| %>
<div class="field">
<%= f.hidden_field :topic_id, :value => topic.id %>
<%= f.text_area :content, placeholder: "Tell us about it ..." %>
</div>
<%= f.submit "Post", class: "btn btn-large btn-primary" %>
<% end %>
I don't have my ruby environment readily available so I can't verify that this will solve your problem but I think it should move you in the right direction.

Categories